主题:从iBatis中得到PreparedStatement
时间: 2020-08-27来源:ITEYE
前景提要
相关推荐: iBatis分页 iBatis batch处理那些事 ibatis源码学习(一)整体设计和核心流程 从iBatis中得到PreparedStatement 项目开发-iBatis事务源码之SQL执行 ibatis 学习笔记 3 ibatis 中blob的使用 [ibatis]动态映射
推荐群组: IBM WebSphere专区
更多相关推荐
iBATIS   iBatis是个好东西,特别是他的动态SQL构建,其实也是选它的原因,除去这个热点,spring的jdbcTemplate更加的 smart。但并不是封装的越完整越好,有时候我们需要用到preparentStatement和resultset,进行一些例外的操作,这时还要用到动态生成的sql和参数的封装,只能从iBatis处想办法了。从现有的iBatis中无法得到这些对象,拿源代码来跟踪一下,改改(开源的好处之一:源代码)。  注意:该改变仅对查询,如果对于更新或其它的,还是调用iBatis的缺省function较好,保证事务的完整和缓存的更新。   水平有限,有什么不对的地方,请大家包涵并指正!   1.对SqlMapClient增加几个接口     /** * 不执行具体的查询,返回一个SessionScope,利用这个sessionScope,返回一个statement * 记得用closeSessionScope来关闭 * @return */ public SessionScope getSessionScope(); /** * 根据传入的sessionScope,关闭 * @param scope */ public void closeSessionScope(SessionScope scope); /** * 你要调用 sessionScope.getSqlMapTxMgr().endTransaction() * sessionScope.cleanup(); * sessionScope.closePreparedStatements() * 释放相关资源 * 或sqlMapClient.closeSessionScope() * * @param session * @param sqlId * @param paramObject * @return * @throws SQLException */ public PreparedStatement makePreparedStatement(SessionScope session,String sqlId,Object paramObject) throws SQLException; 2.SqlMapClientImpl实现上面的接口 /** * 不执行具体的查询,返回一个SessionScope,利用这个sessionScope,调用sqlMapClient.makePreparedStatement返回一个statement * 你要调用 sessionScope.getSqlMapTxMgr().endTransaction() * sessionScope.cleanup(); * sessionScope.closePreparedStatements() * 释放相关资源 * @return */ public SessionScope getSessionScope(){ return this.getLocalSqlMapSession().sessionScope; } /** * 根据传入的sessionScope,关闭 * @param scope */ public void closeSessionScope(SessionScope scope){ try{ scope.getSqlMapTxMgr().endTransaction(); } catch(Exception e){} scope.closePreparedStatements(); scope.cleanup(); } /** * 利用sessionScope生成一个preparedStatement * by wangqiang 2010.01.12 */ public PreparedStatement makePreparedStatement(SessionScope session,String sqlId,Object paramObject) throws SQLException{ return this.delegate.makePreparedStatement(session, sqlId, paramObject,this); } 3.SqlMapExecutorDelegate 增加 public PreparedStatement makePreparedStatement(SessionScope sessionScope, String id, Object paramObject,SqlMapClientImpl sqlMapClient) throws SQLException{ PreparedStatement ps = null; Transaction trans = getTransaction(sessionScope); boolean autoStart = trans == null; try { trans = autoStartTransaction(sessionScope, autoStart, trans); MappedStatement ms = getMappedStatement(id); ms.setSqlMapClient(sqlMapClient); StatementScope statementScope = beginStatementScope(sessionScope, ms); sessionScope.getCurrentConnection="+sessionScope.getSqlMapClient().getCurrentConnection()); ps = ms.makePreparedStatement(statementScope, Unwind.unwindConnection(sessionScope.getSqlMapClient().getCurrentConnection()), paramObject); endStatementScope(statementScope); }catch(Exception e){ e.printStackTrace(); throw new SQLException(e); } return ps; } 4.MappedStatement 增加 public PreparedStatement makePreparedStatement(StatementScope statementScope, Connection conn, Object parameterObject) throws SQLException{ parameterObject = validateParameter(parameterObject); Sql sql = getSql(); ParameterMap parameterMap = sql.getParameterMap(statementScope, parameterObject); statementScope.setParameterMap(parameterMap); Object[] parameters = parameterMap.getParameterObjectValues(statementScope, parameterObject); String sqlString = sql.getSql(statementScope, parameterObject); return getSqlExecutor().makePreparedStatement(statementScope, conn, sqlString, parameters); } 5.SqlExecutor 增加 ////////////////////// /** * by wangqiang 2010.01.12 */ public PreparedStatement makePreparedStatement(StatementScope statementScope, Connection conn, String sql, Object[] parameters) throws SQLException{ PreparedStatement ps = null; try{ Integer rsType = statementScope.getStatement().getResultSetType(); if (rsType != null) { ps = prepareStatement(statementScope.getSession(), conn, sql, rsType); } else { ps = prepareStatement(statementScope.getSession(), conn, sql); } setStatementTimeout(statementScope.getStatement(), ps); Integer fetchSize = statementScope.getStatement().getFetchSize(); if (fetchSize != null) { ps.setFetchSize(fetchSize.intValue()); } statementScope.getParameterMap().setParameters(statementScope, ps, parameters); } catch(Exception e){ throw new SQLException(e); } return ps; } 6.新建一个java,因为iBatis的connection,statement,resultset都通过proxy来生成的,需要得原始的这些对象 Unwind.java public class Unwind { public static Connection unwindConnection(Connection connection) { if (connection == null) { return null; } Connection localConnection = connection; while (Proxy.isProxyClass(localConnection.getClass())) { InvocationHandler ih = Proxy.getInvocationHandler(localConnection); if (ih instanceof ConnectionLogProxy) { localConnection = ((ConnectionLogProxy) ih).getConnection(); } else if (ih instanceof SimplePooledConnection) { localConnection = ((SimplePooledConnection) ih).getRealConnection(); } else { // some other non iBATIS proxy - jump out break; } } return localConnection; } public static PreparedStatement unwindPreparedStatement(PreparedStatement statement) { if (statement == null) { return null; } PreparedStatement localStatement = statement; while (Proxy.isProxyClass(localStatement.getClass())) { InvocationHandler ih = Proxy.getInvocationHandler(localStatement); if (ih instanceof PreparedStatementLogProxy) { localStatement = ((PreparedStatementLogProxy) ih).getPreparedStatement(); } else { // some other non iBATIS proxy - jump out break; } } return localStatement; } public static Statement unwindStatement(Statement statement) { if (statement == null) { return null; } Statement localStatement = statement; while (Proxy.isProxyClass(localStatement.getClass())) { InvocationHandler ih = Proxy.getInvocationHandler(localStatement); if (ih instanceof StatementLogProxy) { localStatement = ((StatementLogProxy) ih).getStatement(); } else { // some other non iBATIS proxy - jump out break; } } return localStatement; } public static ResultSet unwindResultSet(ResultSet resultset) { if (resultset == null) { return null; } ResultSet localResultset = resultset; while (Proxy.isProxyClass(localResultset.getClass())) { InvocationHandler ih = Proxy.getInvocationHandler(localResultset); if (ih instanceof ResultSetLogProxy) { localResultset = ((ResultSetLogProxy) ih).getRs(); } else { // some other non iBATIS proxy - jump out break; } } return localResultset; } } 还有,对有些不是public 的function,改成public就行了。 写段代码测试一下:   ApplicationContext context = null; String path="D:/myproject/java/myQTEIS_lib/spring"; String[] spfiles= new String[4]; spfiles[0] = path+"/spring.xml "; spfiles[1] = path+"/spring_ibatis.xml "; spfiles[2] = path+"/spring_logistics.xml "; spfiles[3] = path+"/spring_logistics_service.xml "; context = new FileSystemXmlApplicationContext(spfiles); DaoBase dao = (MaterialCatalogDaoImpl)context.getBean("materialCatalogDao"); Map pms = new HashMap(); PreparedStatement stm = null; ResultSet rs = null; int ii = 35; pms.put("fldid", ii); try { SessionScope ses = dao.getSqlMapClient().getSessionScope(); dao.wrapLimited(pms, -1, 1000); stm = dao.getSqlMapClient().makePreparedStatement(ses, ((DaoBase)dao).getSelectSQLName(), pms); stm.execute(); System.out.println("ses:"+ses.toString()); System.out.println("iBatisMain statement(37)="+stm.getMetaData().getColumnCount()); stm.close(); ses.getSqlMapTxMgr().endTransaction(); ses.cleanup(); ses.closePreparedStatements(); System.out.println("ses:"+ses.toString()); } catch (SQLException e) { e.printStackTrace(); } finally{ try { stm.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } stm=null; } OK,得到了想要的!

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行