1.新建一个RowMapper接口:
public interface RowMapper { void buildRow(ResultSet rs)throws SQLException; }
2.创建一个回调接口:QueryCallBack
interface QueryCallback{ public Object call(ResultSet rs) throws SQLException; }
3.创建QueryHelper类
public class QueryHelper { public static void executeQuery(String sql,Object[]parameters,QueryCallback call){ Connection conn=null; PreparedStatement pstmt=null; ResultSet rs=null; try{ conn=DataAccess.getConnection(); if(parameters!=null) { int i=1; for(Object param:parameters){ pstmt.setObject(i, param); i++; } } pstmt=conn.prepareStatement(sql); rs=pstmt.executeQuery(); call.call(rs); }catch (Exception e) { e.printStackTrace(); } } }
4.创建DatabaseManager
public class DatabaseManager { public void executeQuery(final RowMapper rowMapper,String sql, Object[] parameters){ QueryHelper.executeQuery(sql, parameters, new QueryCallback(){ public Object call(ResultSet rs) throws SQLException { while(rs.next()){ rowMapper.buildRow(rs); } return null; } }); } }
5.创建UserDaoImpl:
package com.jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class UserDaoImpl implements UserDao{ private DatabaseManager databaseManager=new DatabaseManager(); public List<User> findUserByName(String name) { List<Object> parameterList=new ArrayList<Object>(); StringBuffer selectSql=new StringBuffer(); //1.组装sql语句,参数为动态绑定的 //2.将查询条件中的值加入到parameterList中 //3.sql语句也有了,查询时所需参数的值也有了,接下来可以进行查询,并将结果组装了 Object[] parameters=parameterList.toArray(); List<User> userList=new ArrayList<User>(); databaseManager.executeQuery(new UserMapper(userList), selectSql.toString(), parameters); return null; } } class UserMapper implements RowMapper{ private List<User> userList=new ArrayList<User>(); public UserMapper(List<User> userList) { this.userList = userList; } public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; } public void buildRow(ResultSet rs) throws SQLException { User user=new User(); user.setId(rs.getLong("id")); user.setAge(rs.getInt("age")); user.setName(rs.getString("name")); user.setAddress(rs.getString("address")); userList.add(user); } }
DatabaseManager类的executeQuery(final RowMapper rowMapper,String sql, Object[] parameters)方法
是核心,它将RowMapper和CallBack链接起来了。
首先调用QueryHelper类的executeQuery方法可以查询出所有满足查询参数的记录,获得最终的ResultSet.
然后QueryHelper自己并不去将ResultSet中的值组装成User对象,它将这个任务交给QueryCallback去做。
DatabaseManager创建的实现了接口QueryCallback的匿名内部类把上面这个任务担当下来了。但是这只是表面现象。因为它自己也没做事,它还是把数据的组装操作交给了RowMapper.
QueryCallback匿名内部类能访问外部类的final型的RowMapper.
最终还是落到了RowMapper头上。
在UserDaoImpl中,创建一个RowMapper的具体实现,并在创建的同时准备一个东西来装等下组装出来的User对象。所以就有了
new UserMapper(userList)
UserMapper实现的buildRow(ResultSet rs) 方法相当专一。一个rs对应一个User。(我不管外面的世界是怎么地!我就做这样简单的工作,呵呵!)
综上,通过此思路构建的查询操作,各个部分的操作职责分明。
通过此思路的解析,可以构建一个完整的CRUD操作工具集,利用的核心技术还是回调技术。
序列图如下: