jdbcTemplate中Callback的三个实现
工作中遇到外键关联的联表查询,采用jdbcTemplate的query来实现,需对返回ResutlSet自行进行组装,故研究了下Callback三个接口实现。
三种实现分别是ResultSetExtracor、RowMapper、RowCallbackHanlder,借用网上的一个例子(查询顾客信息)来阐述用法。
List<Customer> customerList = (List<Customer>)jdbcTemplate.query("select * from customer", new ResultSetExtractor(){ public Object extractData(ResultSet rs) throws SQLException,DataAccessException { List<Customer> customers = new ArrayList<Customer>(); while(rs.next()){ Customer customer = new Customer(); customer.setFirstName(rs.getString("fristname")); customer.setLastName(rs.getString("lastname")); customers.add(customer); } return customers; }); } List<Customer> customerList = jdbcTemplate.query("select * from customer", new RowMapper(){ public Object mapRow(ResultSet rs, int rowNumber) throws SQLException { Customer customer = new Customer(); customer.setFirstName(rs.getString("firstname")); customer.setLastName(rs.getString("lastname")); return customer; }); } final List<Customer> customerList = new ArrayList<Customer>(); jdbcTemplate.query("select * from customer", new RowCallbackHandler(){ public void processRow(ResultSet rs) throws SQLException { Customer customer = new Customer(); customer.setFirstName(rs.getString("firstname")); customer.setLastName(rs.getString("lastname")); customerList.add(customer); }); }
从代码中看,ResultSetExtractor与其他两种方法相比,需自己对结果集遍历,这同时也给了一个权限。游标的位置isBforeFisrt()是true,可通过res.next(),取得所有返回数据;
RowMapper中的rowMapper是对单条的处理,游标的位置isBeforeFisrt()是false,每一次操作,都对应一条数据,且返回的是每一条处理结果的对象;
RowCallbackHanlder中的processRow也是对单条处理,游标的位置isBeforeFisrt()是false,因为没有返回值,操作结果只能通过final传回上层。
在联表查询返回时,需对数据重新组装,直接采用ResultSetExtractor可以解决问题,但要注意数据组装的细节。用RowCallbackHanlder也可达到同样的效果,但需采用PreparedStatementCreator,使结果集可回滚,将游标定位到beforeFirst,再通过res.next()处理。