关于春天JdbcTemplate的一些总结

  

关于春天JdbcTemplate的一些总结

  

一个小问题的思考

  

起因

  

当前项目中一直使用的都是<代码> SpringData JPA> 公共接口UserRepository延伸JpaRepository&肝移植;用户,Serializable& gt; 这种用法;

  

考虑到JPA代码 <代码> SpringData确实有一定的局限性,在部分查询中使用到了<代码> JdbcTemplate 进行复杂查询操作,
由于本人16年也曾使用过<代码> JdbcTemplate>   

首先列出同事的做法:

  
 <代码类="语言java ">
  公开课xxx {
  
  xxx方法(){
  …
  List=jdbcTemplate列表。查询(sql,新的WishDTO ());
  …
  }
  }
  
  @ data
  公共类WishDTO实现RowMapper可序列化的{
  字符串xxx;
  长xxx;
  xxx日期;
  BigDecimal xxx;
  
  @Override
  公共WishDTO mapRow (ResultSet rs, int rowNum) {
  WishDTO dto=new WishDTO ();
  .getDeclaredFields领域[]字段=dto.getClass () ();
  (字段字段:字段){
  尝试{
  field.setAccessible(真正的);
  字段。集(dto, rs.getObject (field.getName ()));
  }捕捉(异常e) {
  e.printStackTrace ();
  }
  }
  返回dto;
  }
  
  }
   
  

个人愚见

  

个人感觉让WishDTO再实现实现一遍RowMapper有点麻烦,毕竟WishDTO实体类的所有字段都是需要赋值的,并没有定制化需求。

  

所以想着有没有更好地写法,然后就翻了一下jdbcTemplate的方法,找到了一个<代码>自认为满足自己这个需求的方法:

  
  

公共& lt; T>ListqueryForList (String sql, Class应用)
即将代码改为:

  
 <代码类="语言java ">
  公开课xxx{ 
     
 <代码> xxx方法(){
  …
  List=jdbcTemplate列表。queryForList (sql, WishDTO.class);
  …
  } 
  

}   

@ data
公共类WishDTO实现Serializable {
字符串xxx;
长xxx;
日期xxx。
BigDecimal xxx。
}

  
 <代码>
  一切看起来都很完美,但执行却报错了:* *不正确的列数:1,实际13 * *
  
  # # #思考
  
  经过一番对源码进行调试、结合网上的一些资料,大概知道了是什么原因了,分析如下;
  
  “的”java
  公共& lt; T>ListqueryForList (String sql, Class应用)抛出DataAccessException {
  返回查询(sql, getSingleColumnRowMapper(应用));
  } 
  

其本质是还是调用<代码>公共和lt; T& gt;List&肝移植;T& gt;sql查询(字符串,RowMapper&肝移植;T& gt;rowMapper)> Class&肝移植;T& gt;应用> RowMapper 实现实例;

  
 <代码类="语言java ">保护& lt; T>RowMappergetSingleColumnRowMapper (ClassrequiredType) {
  返回新SingleColumnRowMapper<祝辞(requiredType);
  } 
  

现在我们可以看一下SingleColumnRowMapper类的描述:

  
 <代码>/* *
  * {@link RowMapper}实现单个列转换成一个
  *每一行结果值。预计经营>公共类xxx {
  
  xxx方法(){
  …
  List=jdbcTemplate列表。查询(sql,新BeanPropertyRowMapper (WishDTO.class));
  …
  }
  }
  
  @ data
  公共类WishDTO实现Serializable {
  字符串xxx;
  长xxx;
  xxx日期;
  BigDecimal xxx;
  } 
  

接下来看一下<代码> BeanPropertyRowMapper>   

 <代码>/* *
  * {@link RowMapper}实现将一行转换成一个新实例
  *指定映射的目标类。必须是一个映射的目标类
  *顶级类,它必须有一个违约或不带参数的构造函数。
  *
  * & lt; p>基于列值被映射的>
  int rowCount=this.jdbcTemplate。从t_actor queryForObject (“select count (*)”, Integer.class);
  
  int countOfActorsNamedJoe=this.jdbcTemplate。queryForObject (“select count(*)从t_actor first_name=?”,整数。类,“乔”);
  
  字符串lastName=this.jdbcTemplate。queryForObject(“从t_actor选择last_name id=在哪里?”,新对象[]{1212 l}, String.class);
  
  演员演员=this.jdbcTemplate.queryForObject (
  “选择first_name、last_name t_actor id=在哪里?”,
  新对象[]{1212 l},
  新的RowMapper () {
  公共演员mapRow (ResultSet rs, int rowNum) throws SQLException {
  演员演员=new演员();
  actor.setFirstName (rs.getString (“first_name”));
  actor.setLastName (rs.getString (“last_name”));
  返回的演员;
  }
  });
  
  List

关于春天JdbcTemplate的一些总结