从iBatis中得到PreparedStatement

  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,得到了想要的!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值