ibatis3中直接在xml中写明一对多的关系和利用ibatis的拦截器进行SQL重组达到分页的目的

1 篇文章 0 订阅
1 篇文章 0 订阅

最近没事儿,搭建了一个ssi框架,虽然问题依旧很多,但是收获依旧不少,先记录点点滴滴,以便以后有参考。

之前本来打算运用ibatis2.3.4版本,因为之前工作就是用的ibatis2.3.4,所以对这个版本比较熟悉一些。后来做分页的时候由于不想像以前工作的时候做分页那样写两条SQL进行分页,就想到了运用拦截器进行SQL的重组,然后去执行。发现只有mybaits3才有,后来就升级到了mybatis3。

分页拦截器如下(找了网上很多大神的方法,非我原创,原创出处已往,见谅):

定义一个拦截器继承ibatis的Interceptor类,重写intercept(Invocation invocation)方法

if (invocation.getTarget() instanceof RoutingStatementHandler) {
RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation
.getTarget();
BaseStatementHandler delegate = (BaseStatementHandler) Tools
.getValueByFieldName(statementHandler, "delegate");
MappedStatement mappedStatement = (MappedStatement) Tools
.getValueByFieldName(delegate, "mappedStatement");
BoundSql boundSql = delegate.getBoundSql();
// 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
String method = mappedStatement.getId();
String sql = boundSql.getSql();
if (mappedStatement.getId().matches(defaultPageSqlId)) {
Object parameterObject = boundSql.getParameterObject();
if (null != parameterObject) {
Page<?> page = null;
if (parameterObject instanceof Page) { // 参数就是Pages实体
page = (Page<?>) parameterObject;
} else { // 参数为某个实体,该实体拥有Pages属性
Object obj = Tools.getObjByFieldName(parameterObject,
"page");
if (obj != null && obj instanceof Page) {
page = (Page<?>) obj;
} else {
// 不存在page属性
return invocation.proceed();
}
}
if (null == page)
return invocation.proceed();
// 重写sql
Connection connection = (Connection) invocation.getArgs()[0];
String countSql = "select count(0) from (" + sql
+ " ) tmp_count ";
PreparedStatement countStmt = connection
.prepareStatement(countSql);
Tools.setValueByFieldName(boundSql, "sql", countSql);
DefaultParameterHandler ParameterHandler = new DefaultParameterHandler(
mappedStatement, parameterObject, boundSql);
ParameterHandler.setParameters(countStmt);
ResultSet rs = countStmt.executeQuery();
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
rs.close();
countStmt.close();
page.setTotalCount(count);
String pageSql = buildPageSql(sql, page);
Tools.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
logger.error("重写后的SQL:"
+ sql.replaceAll("[\\s]+", " ").replaceAll(
"[\\s][,]{1}", ","));
}
}
}
return invocation.proceed();

只拦截后缀名为Page结尾的方法。


在mybatis中表明一对多的关系为

<association property="files" column="applyInfoId" select="FileInfo.getFileInfos" javaType="String"/>

而在ibatis2中则为<resultMap id="departMap" extends="baseMap" class="depart">
<result property="children" column="{parentid=departid}" select="Depart.getDeparts" />
<result property="users" column="{departid=departid}" select="User.getUsers" />
</resultMap>

这是3和2的一点小区别

当加载xml文件时运行到这句代码就会去namespace为FileInfo下去寻找getFileInfos方法,并把column传过去。这样就完成了一对多的映射。

初学,谨以此篇记录。

内附完整的拦截类(拦截类非我原创,原创出处已忘,见谅)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值