Spring JDBC - Spring JDBC模版使用

前言

        Spring JdbcTemplate是Spring Framework提供的一个强大的数据库访问工具,它简化了数据库操作的过程,为开发者提供了一个高级的数据库访问抽象层。

        JdbcTemplate是Spring JDBC模块中的一个核心类,它位于org.springframework.jdbc.core包中。

        JdbcTemplate通过封装JDBC的核心功能,如数据库连接管理、SQL执行、参数绑定、结果集提取、异常处理等,使得数据库操作变得更加简单和高效。

1 使用Spring JDBC 模版

  • Spring的JDBC框架将数据访问的过程中获取连接、释放资源、异常处理、遍历查询结果等必须的样板代码封装隐藏到模板类之下,从而简化我们的JDBC 代码.
  • Spring针对JDBC提供了3个模板类
    • JdbcTemplate:Spring 里最基本的 JDBC 模板,利用 JDBC 和简单的索引参数查询提供对数据库的简单访问。
    • NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数,这有利于简化动态组合条件查询的实现,也不容易搞混参数
    • SimpleJdbcTemplate:利用Java 5的特性,比如自动装箱、泛型(generic)和可变参数列表来简化JDBC模板的使用。

1.1 使用JdbcTemplate

  • 将JdbcTemplate配置成bean
  • 注入DataSource
<bean id="jdbcTemplate" class="….jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource"/>
</bean>
  • 案例:完成scott中员工信息的增删查改操作

EmpDao:

public interface EmpDao {

	List<Emp> search();
	List<Emp> search(Emp e);
	Emp findById(int empno);
	void save(Emp e);
	void update(Emp e);
	void delete(int empno);
}

Dao的实现类: 

public class EmpDaoJdbcTemplate implements EmpDao {
 
	@Resource(name="jdbcTemplate")
	private JdbcTemplate jdbcTemplate;
    	……
}
  • 案例:员工信息的插入操作
  • JdbcTemplate
    • public int update(String sql,Object...args)
public void save(Emp e) {
     String sql = "insert into emp (empno,ename,deptno) values (?,?,?)";
     Object[] params = 
	newObject[]{e.getEmpno(), e.getEname(), e.getDept().getDeptno()};
     jdbcTemplate.update(sql, params);
}

传递参数时,可以按顺序依次传参,也可以封装成一个Object数组进行传参。

测试类:

@Test
public void testSave() throws Exception {
	Emp emp = new Emp(1012,"员工测试",new Dept(40));
	dao.save(emp);
}
  •  案例:实现无参的search方法
  • JdbcTemplate的query方法
    • 一个字符串,SQL语句
    • 一个RowMapper对象,从ResultSet里提取数值并构造一个实体对象返回,在这里就是员工对象。
public List<Emp> search() {
	String sql = "select e.empno,e.ename,d.deptno,d.dname from emp e inner join dept d on e.deptno = d.deptno ";
	RowMapper rowMapper = new ParameterizedRowMapper<Emp>() 
	{
		@Override
		public Emp mapRow(ResultSet rs, int rowNum) …{
			Emp e = new Emp();
			e.setEmpno(rs.getInt("empno"));
			e.setEname(rs.getString("ename"));
			Dept d = new Dept();
			d.setDeptno(rs.getInt("deptno"));
			d.setDname(rs.getString("dname"));
			e.setDept(d);
			return e;
		}
	};
	List<Emp> list = jdbcTemplate.query(sql,rowMapper);	
	return list;
}
  • search()、findById()和search(Emp e)都需要使用同一个RowMapper对象
  • 定义成EmpDao接口的一个公共静态常量属性
public static final RowMapper rowMapper = new ParameterizedRowMapper<Emp>() {
	@Override
	public Emp mapRow(ResultSet rs, int rowNum) throws SQLException {
		Emp e = new Emp();
		e.setEmpno(rs.getInt("empno"));
		e.setEname(rs.getString("ename"));
		Dept d = new Dept();
		d.setDeptno(rs.getInt("deptno"));
		d.setDname(rs.getString("dname"));
		e.setDept(d);
		return e;
	}
};
List<Emp> list = jdbcTemplate.query(sql,rowMapper);//精减后的代码
  • 案例:实现findById方法
  • findById方法与search相同,仅有两点不同
    • 需要传递查询条件
    • 仅返回一个员工对象而不是一个员工对象集合
public Emp findById(int empno) {
	String sql = "select e.empno,e.ename,d.deptno,d.dname from emp e 
	inner join dept d on e.deptno = d.deptno where empno = ?";
 
	List<Emp> list = jdbcTemplate.query(sql, rowMapper,empno);
	return list.size()>0?(Emp)list.get(0):null;
}
  • 案例:实现search(Emp e)方法
  • 根据用户在多个查询条件中选填后得到动态组合查询的效果。
  • 两个查询条件,员工姓名和所属部门。
    • 无条件查询
    • 仅填写姓名,进行模糊查询
    • 仅选择部门,查询谋部门的所有员工
    • 既填写姓名又选择部门,查询谋部门符合姓名条件的员工信息

public List<Emp> search(Emp e) {
StringBuilder sql = new StringBuilder("select empno,ename,d.deptno,dname from…");
 
List plist = new ArrayList();
if(e!=null){
	if(e.getEname()!=null && e.getEname().trim().length()!=0){
		sql.append(" and e.ename like ?");
		plist.add("%"+e.getEname()+"%");
	}
	if(e.getDept()!=null && e.getDept().getDeptno()!=null 
			&&  e.getDept().getDeptno()>0){
		sql.append(" and d.deptno = ?");
		plist.add(e.getDept().getDeptno());
}}
Object[] params = plist.toArray();
List<Emp> list = jdbcTemplate.query(sql.toString(),params,rowMapper);
return list;}

如果符合条件就拼接对应的where条件,达到多条件查询的效果。

 1.2 使用NamedParameterJdbcTemplate

  • 案例:save方法实现中使用了索引参数
  • 注意参数在SQL语句里的次序
  • 以正确次序设置对应参数的值
  • 改变参数的次序,值的次序也必须随之改变
  • 使用命名参数
insert into emp ( empno , ename , deptno ) 
values ( :empno, :ename, :deptno)
  • 次序是没有关系的
  • 用名称绑定每个值
  • 参数次序改变,不需要修改参数绑定的代码

代码实现:

  • JDBC 模板:NamedParameterJdbcTemplate

spring.xml(spring的配置文件):

<bean id="namedParameterJdbcTemplate"
	class="…jdbc.core.namedparam.NamedParameterJdbcTemplate">
	<constructor-arg ref="dataSource"/>
</bean>

 java代码:

@Component("empDaoNamedParam")
public class EmpDaoNamedParameter implements EmpDao {
 
	@Resource(name="namedParameterJdbcTemplate")
	private NamedParameterJdbcTemplate  jdbcTemplate;
	……
}

案例: 

  •  案例:使用命名参数的save方法
  • 案例:只有一个参数的findById方法
  • 案例:search方法,查询所有员工
public int save(Emp e) {
String sql = "insert into emp (empno,ename,deptno) " +
	     "values (:empno,:ename,:deptno)";		
	Map params = new HashMap();
	params.put("empno", e.getEmpno());
	params.put("ename", e.getEname());
	params.put("deptno", e.getDept().getDeptno());
	return jdbcTemplate.update(sql, params);
}
public Emp findById(int empno) {
 
	String sql = "select e.empno,e.ename,d.deptno,d.dname from emp e inner join dept d on e.deptno = d.deptno where empno = :empno";
		
	Map params = new HashMap();
	params.put("empno", empno);
		
	List<Emp> list = jdbcTemplate.query(sql, params,rowMapper);
	return list.size()>0?(Emp)list.get(0):null;
}
public List<Emp> search() {

String sql = "select e.empno,e.ename,d.deptno,d.dname from 
emp e inner join dept d on e.deptno = d.deptno ";

List<Emp> list = jdbcTemplate.query(sql,new HashMap(),rowMapper);
		
return list;
}

2 使用Spring 对 JDBC的 DAO支持类

  • 存在问题
    • JDBC的全部DAO类,需要一个JdbcTemplate属性和一个设置方法
    • 把JdbcTemplate Bean装配到每个DAO的JdbcTemplate属性
    • 多个DAO,产生很多重复代码
  • 解决方案
    • 全部DAO 对象创建一个通用父类 在其中设置 JdbcTemplate 属性,
    • 全部 DAO 继承这个类,使用父类的JdbcTemplate进行数据访问,
    • Spring恰好提供了这样一些基类。

2.1 使用JdbcDaoSupport

  • Spring 的 JdbcDaoSupport 就是用于编写基于JDBC 的DAO 类的基类
  • 自己的DAO类继承它即可
package dao.support;
public class EmpDaoJdbcSupport extends JdbcDaoSupport implements EmpDao{
     ……省略方法
}
public int save(Emp e) {
	String sql = "insert into emp (empno,ename,deptno) values (?,?,?)";
		
	Object[] params = new Object[]{
		e.getEmpno(),e.getEname(),e.getDept().getDeptno()};
 	//调用父类的方法
	return getJdbcTemplate().update(sql, params);
}
  • JdbcTemplate属性定义在父类JdbcDaoSupport中
  • 无法使用注解,因为添加注解需要修改源代码
  • 只能使用xml方式配置
<bean id="empDaoJdbcSupport" class="dao.support.EmpDaoJdbcSupport">
	<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

2.2 使用NamedParameterJdbcDaoSupport

  • 使用命名参数形式
  • 让Dao类继承NamedParameterJdbcDaoSupport类
package dao.support;
public class EmpDaoNamedJdbcSupport extends NamedParameterJdbcDaoSupport
implements EmpDao{
     ……省略方法
}
  •  调用父类的getNamedParameterJdbcTemplate()方法返回一个NamedParameterJdbcTemplate对象
  • 可以使用命名参数的形式编写dao操作
public int save(Emp e) {
	String sql = "insert into emp (empno,ename,deptno) values "+
		   "(:empno,:ename,:deptno)";
	Map params = new HashMap();
	params.put("empno", e.getEmpno());
	params.put("ename", e.getEname());
	params.put("deptno", e.getDept().getDeptno());
 
	return getNamedParameterJdbcTemplate().update(sql, params);
}
  • bean配置
<bean id="empDaoNamedJdbcSupport" 	class="dao.support.EmpDaoNamedJdbcSupport">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

总结

主要介绍如何使用Spring JDBC模版,以及使用Spring对JDBC的DAO支持类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值