自学内容网 自学内容网

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支持类


原文地址:https://blog.csdn.net/weixin_52937170/article/details/142758013

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!