将Ibatis的Connection改为长连接,并且封装

[size=large][i] 看到这个主题 很多人会怀疑,Ibatis已经为我们做了很多事情,例如连接池管理、获取连接、增、删、改、查等操作,[/i]
[b] 为什么还需要通过Ibatis获取JDBC连接做连接保持呢(长连接)?[/b]
我的解释是有很多操作需要在同一个数据源连接下完成。如:oracle的临时表操作。
熟悉oracle的人都不陌生关于[b]oracle的内部临时表,分为2种,1:事务级。2:会话级。[/b]而我在一次项目开发(老存报表储过程进行改装成java逻辑)中就遇到这样,而又没有足够的时间去重写这样的业务逻辑。于是项目经理要求将逻辑平移到java项目中。
而就是原先的操作使用到了oracle的会话级临时表,因此,使用Ibatis的插入、更改、删除临时表后,在执行下一次操作时,无法查询到临时表的数据。
这个原因就是 会话级的临时表在作怪,而要解决这样原因只能采用JDBC的Connection来完成整个操作。
于是,我想到了Ibatis已经封装好的属性和方法,为什么我不调用封装呢。
[b]具体的封装方式如下:[/b][/size]
首先:通过Ibatis获取指定Id的SQL语句

/**
* 获取SQL
* ibatais根据sqlMap的Id获取sql语句
* @param sqlId 是xml文件配置的ID
* @return sql语句 以“$”注入的会自动转换,“#”不会
*/
public static String getSql(SqlMapClientImpl sqlclientImpl,String sqlId,Object params){

String sqlStr = "";
/**获取隐身对象*/
MappedStatement stmt = sqlclientImpl.getMappedStatement(sqlId);
Sql sql = stmt.getSql();
/**获取规则*/
SessionScope sessionScope = new SessionScope();
sessionScope.incrementRequestStackDepth();
StatementScope statementScope = new StatementScope(sessionScope);
stmt.initRequest(statementScope);
/**获取sql映射对象*/
sqlStr = sql.getSql(statementScope, params);

log.debug("sqlMap:"+sqlId);
log.debug("sql:"+sqlStr);

return sqlStr;
}



其次:将请求参数通过Java反射方式封装起来。

/**
* 预编译封装对象
* @param sqlmap
* @param ps
* @param sqlId
* @param params
* @return 绘制PreparedStatement
*/
public static PreparedStatement getSqlParameterMap(SqlMapClientImpl sqlmap,PreparedStatement ps,String sqlId,Object params) {

/**获取ibatis参数*/
ParameterMapping[]paramMappSet = IbatisMapping.getParameterMapp( sqlmap, sqlId);
/**反射来装配参数*/
try {
int index=0;
for(ParameterMapping paramMapp : paramMappSet){
index++;
String methodName = "get"+ToolUtil.toFirstLetterUpperCase(paramMapp.getPropertyName());
Method method = params.getClass().getDeclaredMethod(methodName);
Object obj = null;
obj = method.invoke(params, null);
putPreparedStatement(ps,index,obj ,method.getGenericReturnType());
}
} catch (Exception e) {
logger.error("反射装配ibatais参数异常,系统错误!",e);
}

return ps;
}


/**
* 获取ibatis预编译参数
* */
private static ParameterMapping[] getParameterMapp(SqlMapClientImpl sqlmap,String sqlId){
/**获取sqlMap.xml映射*/
MappedStatement stmt = sqlmap.getMappedStatement(sqlId);
/**获取指定ID的parameterClass参数*/
ParameterMapping[] paramMappSet = stmt.getParameterMap().getParameterMappings();

return paramMappSet;
}

private static void putPreparedStatement(PreparedStatement ps,int index,Object obj ,Object type) throws SQLException{
/*String*/
if(obj instanceof String){
ps.setString(index, obj.toString());
}
/*Integer*/
if(obj instanceof Integer){
ps.setInt(index, Integer.valueOf(obj.toString()));
}
/*Long*/
if(obj instanceof Long){
ps.setLong(index, Long.valueOf(obj.toString()));
}
/*Double*/
if(obj instanceof Double){
ps.setDouble(index, Double.valueOf(obj.toString()));
}
/*Date*/
if(obj instanceof Date){
java.util.Date utilDate = (Date) obj;
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
ps.setDate(index, sqlDate);
}
if(obj instanceof BigDecimal){
ps.setBigDecimal(index, BigDecimal.valueOf(Long.valueOf(obj.toString())));
}
}


//**
* 将手字母大写
**/
public static String toFirstLetterUpperCase(String strName) {
if (strName == null || strName.length() < 2) {
return strName;
}
String firstLetter = strName.substring(0, 1).toUpperCase();
return firstLetter + strName.substring(1, strName.length());
}



最后:调用方法如下

Connection conn = null;
PreparedStatement ps = null;
try {
//获取JDBC连接
conn = sqlMapClient.getDataSource().getConnection();
conn.setAutoCommit(true);

//执行
for(String sqlId : sqlIdSet){
/**获取配置sql*/
String sql = this.getSql((SqlMapClientImpl)sqlMapClient, sqlId, params);
ps = conn.prepareStatement(sql);
/**动态装配参数*/
ps = getSqlParameterMap((SqlMapClientImpl)sqlMapClient, ps, sqlId, params);
/**执行*/
executeUpdate(ps);
/**清空预编译参数*/
ps.clearParameters();
}

} catch (SQLException e) {
logger.error("访问数据库异常,执行政企报表失败!",e);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值