使用jdbc template链接数据库,必须提供连接数据库所需的地址、用户名、密码。这些信息可以从已有的ibatis sqlclient对象中获取。
- // 2. 创建JDBC链接 */
- Class.forName("oracle.jdbc.driver.OracleDriver");
- DataSource dataSource = extSqlMapClient.getDataSource();
- if (dataSource instanceof DelegatingDataSource) {
- dataSource = ((DelegatingDataSource) dataSource).getTargetDataSource();
- }
- BasicDataSource basicDataSource = (BasicDataSource) dataSource;
- conn = DriverManager.getConnection(basicDataSource.getUrl(), basicDataSource.getUsername(),
- basicDataSource.getPassword());
然后从ibatis配置中获取需要执行的sql语句。但是ibatis每次执行sql都需要有一个RequestScope和SessionScope对象,所以我们手动生成这两个对象,传给ibatis。
- // 1. 初始化 MappedStatment/requestScope 对象 */
- mappedStatement = extSqlMapClient.getMappedStatement(NAME_SPACE_MJR_KNOWLEDGE + "." + SELECT_EX_BY_ROBOTCODE));
- requestScope = new RequestScope();
- mappedStatement.initRequest(requestScope);
- SessionScope session = new SessionScope();
- session.reset();
- session.setSqlMapClient(extSqlMapClient);
- session.setSqlMapExecutor(extSqlMapClient);
- session.setSqlMapTxMgr(extSqlMapClient);
- requestScope.setSession(session);
- Sql sql = mappedStatement.getSql();/*ibatis的sql对象*/
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("robotCode", robotCode);
- params.put("lastFetchTimePoint", toSqlTimestamp(modifyTimeBegin));
- params.put("currentFetchTimePoint", toSqlTimestamp(modifyTimeEnd));
- String sqlString = sql.getSql(requestScope, params);/*ibatis根据参数,动态生成sql*/
- PreparedStatement st = conn.prepareStatement(sqlString);/*生成jdbc template所需的PreparedStatement*/
在执行PreparedStatement 之前,必须先给PreparedStatement 绑定变量
- // 4. 绑定变量给PreparedStatement */
- ParameterMap pmap = sql.getParameterMap(requestScope, params);
- Object[] parameterObj = pmap.getParameterObjectValues(requestScope, params);
- if (parameterObj != null && parameterObj.length > 0) {
- for (int i = 0; i < parameterObj.length; i++) {
- st.setObject(i + 1, parameterObj[i]);
- }
- }
ok,PreparedStatement对象已经准备完毕,可以执行了。
- // 5. 执行并设置结果集 */
- resultSet = st.executeQuery();
- requestScope.setResultSet(resultSet);
数据库返回了resultset,但是我们还需要让ibatis帮我们把结果组装成dto对象。
- int resultsFetched = 0;
- ResultMap resultMap = requestScope.getResultMap();
- LinkListRowHandler rh = new LinkListRowHandler();
- RowHandlerCallback callback = new RowHandlerCallback(resultMap, null, rh);
- try {
- while ((resultsFetched < pageSize) && resultSet.next()) {
- Object[] columnValues = resultMap.resolveSubMap(requestScope, resultSet).getResults(requestScope, resultSet);
- callback.handleResultObject(requestScope, columnValues, resultSet);
- resultsFetched++;
- }
- } catch (SQLException e) {
- log.error("取数据出错", e);
- }
- return rh.getList();
ok,大功告成,返回结果就是我们所需要的对像啦。
采用以上jdbc template 与ibatis结合的好处是,可以自己控制查询的过程。
当查询的数据结果比较大时,采用传统的ibatis查询,一般有两种方式:分页和不分页。如果分页,就需要排序,大数量的排序是比较耗时的,这样数据库总是在做重复的工作,增加了数据库的压力。如果不分页,jvm需要缓存大量的对象,占用大量的内存,并且可能导致内存溢出。
而查询工作由我们自己来做的话,我们就可以只做一次查询,并且不需要排序,可以将这个resultset对象缓存起来,每次从resultset中取一批数据,取完之后将这个对象释放掉。这种方法的缺点是,查询结果会在数据库中存在比较长的时间,一段时间内,占用内存无法释放。