持久层封装之JdbcTemplate

 SpringJDBC进行了良好的封装,通过提供相应的模板和辅助类,在相当程度上降低JDBC操作的复杂性。并且得益于Spring良好的隔离设计,JDBC封装类库可以脱离Spring Context独立使用,也就是说,即使系统并没有采用Spring作为结构性框架,我们也可以单独使用SpringJDBC部分(spring-dao.jar)来改善我们的代码。

作为对比,首先让我们来看一段传统的JDBC代码:

  1. Connection conn =null;
  2. Statement stmt =    null;
  3. try {
  4. conn = dataSource.getConnection();
  5.   stmt = con.createStatement();
  6.   stmt.executeUpdate("UPDATE user SET age = 18 WHERE id = 'erica'");
  7. }   finally {
  8. if (stmt != null) {
  9. try {
  10. stmt.close();
  11. }   catch (SQLException ex) {
  12. logger.warn("Exception in closing JDBC Statement", ex);
  13. }
  14.   }
  15. if (conn != null) {
  16. try {
  17. conn.close();
  18.  }  catch (SQLException ex) {
  19. logger.warn("Exception in closing JDBC Connection", ex);
  20.  }
  21. }
  22. }

类似上面的代码非常常见。为了执行一个SQL语句,我们必须编写22行代码,而其中21行与应用逻辑并无关联,并且,这样的代码还会在系统其他地方(也许是每个需要数据库访问的地方)重复出现。于是,大家开始寻找一些设计模式以改进如此的设计,Template模式的应用是其中一种典型的改进方案。SpringJDBC封装,很大一部分就是借助Template模式实现,它提供了一个优秀的JDBC模板库,借助这个工具,我们可以简单有效的对传统的JDBC编码方式加以改进。下面是借助Spring JDBC Template修改过的代码,这段代码完成了与上面代码相同的功能。 

 

可以看到,两行代码完成了上面需要19行代码实现的功能。所有冗余的代码都通过合理的抽象汇集到了JdbcTemplate中。无需感叹,借助Template模式,我们大致也能实现这样一个模板,不过,Spring的设计者已经提前完成了这一步骤。org.springframework.jdbc.core.JdbcTemplate中包含了这个模板实现的代码,经过Spring设计小组精心设计,这个实现可以算的上是模板应用的典范。特别是回调(CallBack)的使用,使得整个模板结构清晰高效。值得一读。

Tips:实际开发中,可以将代码中硬编码的SQL语句作为Bean的一个String类型属性,借DI机制在配置文件中定义,从而实现SQL的参数化配置。

再对上面的例子进行一些改进,通过PrepareStatement执行update操作以避免SQLInjection漏洞

  1. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  2. jdbcTemplate
  3. .update(
  4. "UPDATE user SET age = ? WHERE id = ?",
  5. new PreparedStatementSetter() {
  6. public  void setValues(PreparedStatementSetter ps)
  7. throws SQLException {
  8. ps.setInt(118);
  9. ps.setString(2"erica");
  10. }
  11. }
  12. );

可以看到,上面引用了update方法的另一个版本,传入的参数有两个,第一个用于创建PreparedStatementSQL。第二个参数是为PreparedStatement设定参数的PreparedStatementSetter第二个参数的使用方法比较独到,我们动态新建了一个PreparedStatementSetter类,并实现了这个抽象类的setValues方法。之后将这个类的引用作为参数传递给updateupdate接受参数之后,即可调用第二个参数提供的方法完成PreparedStatement的初始化。Spring JDBC Template中大量使用了这样的Callback机制,这带来了极强的灵活性和扩展性。

上面演示了update方法的使用(同样的操作适用于updateinsertdelete)。下面是一个查询的示例。

  1. final List userList =   new ArrayList();
  2. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  3. jdbcTemplate
  4. .query(
  5. "SELECT name, sex, address FROM user WHERE age > 18",
  6. new RowCallbackHandler() {
  7. public  void processRow(ResultSet rs)   throws SQLException {
  8. User user = new User();
  9. user.setId(rs.getString("name"));
  10. user.setSex(rs.getString("sex"));
  11. user.setAddress(rs.getString("address"));
  12. userList.add(product);
  13. }
  14. });

这里传入query方法的有两个参数,第一个是Select查询语句,第二个是一个RowCallbackHandler实例,我们通过RowCallbackHandlerSelect语句得到的每行记录进行解析,并为其创建一个User数据对象。实现了手动的OR映射。

此外,我们还可以通过JdbcTemplate.call方法调用存储过程。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值