spring动态改变数据源(与ibitas整合)

使用jdbc template链接数据库,必须提供连接数据库所需的地址、用户名、密码。这些信息可以从已有的ibatis sqlclient对象中获取。

[java]  view plain copy
  1. // 2. 创建JDBC链接 */  
  2. Class.forName("oracle.jdbc.driver.OracleDriver");  
  3. DataSource dataSource = extSqlMapClient.getDataSource();  
  4. if (dataSource instanceof DelegatingDataSource) {  
  5.    dataSource = ((DelegatingDataSource) dataSource).getTargetDataSource();  
  6. }  
  7. BasicDataSource basicDataSource = (BasicDataSource) dataSource;  
  8. conn = DriverManager.getConnection(basicDataSource.getUrl(), basicDataSource.getUsername(),  
  9.                 basicDataSource.getPassword());  
 

 

 

然后从ibatis配置中获取需要执行的sql语句。但是ibatis每次执行sql都需要有一个RequestScope和SessionScope对象,所以我们手动生成这两个对象,传给ibatis。

[java] view plain copy
  1. // 1. 初始化 MappedStatment/requestScope 对象 */  
  2. mappedStatement = extSqlMapClient.getMappedStatement(NAME_SPACE_MJR_KNOWLEDGE + "." + SELECT_EX_BY_ROBOTCODE));  
  3. requestScope = new RequestScope();  
  4. mappedStatement.initRequest(requestScope);  
  5. SessionScope session = new SessionScope();  
  6. session.reset();  
  7. session.setSqlMapClient(extSqlMapClient);  
  8. session.setSqlMapExecutor(extSqlMapClient);  
  9. session.setSqlMapTxMgr(extSqlMapClient);  
  10. requestScope.setSession(session);  
  11. Sql sql = mappedStatement.getSql();/*ibatis的sql对象*/  
  12. Map<String, Object> params = new HashMap<String, Object>();  
  13. params.put("robotCode", robotCode);  
  14. params.put("lastFetchTimePoint", toSqlTimestamp(modifyTimeBegin));  
  15. params.put("currentFetchTimePoint", toSqlTimestamp(modifyTimeEnd));  
  16. String sqlString = sql.getSql(requestScope, params);/*ibatis根据参数,动态生成sql*/  
  17. PreparedStatement st = conn.prepareStatement(sqlString);/*生成jdbc template所需的PreparedStatement*/  

 

在执行PreparedStatement 之前,必须先给PreparedStatement 绑定变量

[java]  view plain copy
  1. // 4. 绑定变量给PreparedStatement */  
  2. ParameterMap pmap = sql.getParameterMap(requestScope, params);  
  3. Object[] parameterObj = pmap.getParameterObjectValues(requestScope, params);  
  4. if (parameterObj != null && parameterObj.length > 0) {  
  5.     for (int i = 0; i < parameterObj.length; i++) {  
  6.         st.setObject(i + 1, parameterObj[i]);  
  7.     }  
  8. }  
 

 

ok,PreparedStatement对象已经准备完毕,可以执行了。

[java]  view plain copy
  1. // 5. 执行并设置结果集 */  
  2. resultSet = st.executeQuery();  
  3. requestScope.setResultSet(resultSet);  
 

 

数据库返回了resultset,但是我们还需要让ibatis帮我们把结果组装成dto对象。

[java]  view plain copy
  1. int resultsFetched = 0;  
  2. ResultMap resultMap = requestScope.getResultMap();  
  3. LinkListRowHandler rh = new LinkListRowHandler();  
  4. RowHandlerCallback callback = new RowHandlerCallback(resultMap, null, rh);  
  5. try {  
  6.     while ((resultsFetched < pageSize) && resultSet.next()) {  
  7.         Object[] columnValues = resultMap.resolveSubMap(requestScope, resultSet).getResults(requestScope, resultSet);  
  8.         callback.handleResultObject(requestScope, columnValues, resultSet);  
  9.         resultsFetched++;  
  10.       }  
  11. catch (SQLException e) {  
  12.     log.error("取数据出错", e);  
  13. }  
  14. return rh.getList();  
 

ok,大功告成,返回结果就是我们所需要的对像啦。

 

采用以上jdbc template 与ibatis结合的好处是,可以自己控制查询的过程。

当查询的数据结果比较大时,采用传统的ibatis查询,一般有两种方式:分页和不分页。如果分页,就需要排序,大数量的排序是比较耗时的,这样数据库总是在做重复的工作,增加了数据库的压力。如果不分页,jvm需要缓存大量的对象,占用大量的内存,并且可能导致内存溢出。

而查询工作由我们自己来做的话,我们就可以只做一次查询,并且不需要排序,可以将这个resultset对象缓存起来,每次从resultset中取一批数据,取完之后将这个对象释放掉。这种方法的缺点是,查询结果会在数据库中存在比较长的时间,一段时间内,占用内存无法释放。

 

你可能感兴趣的:(spring动态改变数据源(与ibitas整合))