基于mybatis3.X的分页拦截器

为什么会分享mybatis拦截器的方法,由于以往可能都是通过自己写分页sql查寻方法进行分页,这样在支持多个不同的数据库上花费的时间会比较多,如果能在基于sql查寻进行拦截,然后进行拼装分页sql,这样一来能减少不少工作量。闲话不多话,先来看如何实现:

1.首先指定自己的sql插件类进行sql拦截类,在配置mybatis的数据库信息时如下信息

<bean id="userSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource" />
        <property name="configLocation" value="classpath:mybatis/mybatisConfiguration.xml" />
        <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" />
        <property name="plugins">
        <bean class="com.my.mybatis.iterceptor.SqlPageInterceptor"/>
        </property>

    </bean>

2.拦截器类的定义,及核心代码分享(基于mysql的分页 limit实现)

类必须实现org.apache.ibatis.plugin.Interceptor 接口,实现接口内的三个方法,主要是intercept方法,拦截内容设置,与

@Intercepts({@Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class , Integer.class}),
@Signature(method = "query", type = Executor.class, args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })

public class SqlPageInterceptor implements Interceptor {

@Override

public Object intercept(Invocation arg0) throws Throwable {

     if (invocation.getTarget() instanceof StatementHandler) {


//获取StatementHandler,默认是RoutingStatementHandler
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//获取statementHandler包装类
MetaObject metaObjectHandler = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());


MappedStatement mappedStatement = (MappedStatement) metaObjectHandler.getValue("delegate.mappedStatement");
String mapId = mappedStatement.getId();


//拦截以.ByPage结尾的请求,分页功能的统一实现
if (mapId.matches(".+ByPage$")) {
//获取进行数据库操作时管理参数的handler

ParameterHandler parameterHandler = (ParameterHandler) metaObjectHandler.getValue("delegate.parameterHandler");

                            //自己定义分页信息类,总页数,每页条数,当前第几页

PageInfo  pageInfo = (PageInfo ) parameterHandler.getParameterObject();
pageInfo.checkAndSetPageInfo();//设置信息
//修改以byPage结尾的强制分页
String sql = (String) metaObjectHandler.getValue("delegate.boundSql.sql");

queryTotalRecord(pageInfo, pageInfo, mappedStatement, (Connection) invocation.getArgs()[0]);

String limitSql = buildPageSql(pageInfo, sql);
logger.info("生成的分页查询sql为:"+ limitSql);
metaObjectHandler.setValue("delegate.boundSql.sql", limitSql);
}
}
return invocation.proceed(); }


@Override
public Object plugin(Object arg0) {
   return Plugin.wrap(arg0, this);
 
}


@Override
public void setProperties(Properties arg0) {
// TODO Auto-generated method stub

}

      /**
* 生成分页查询sql
* @param pageInfo 分页类自己定义
* @param sql
* @return
*/
protected String buildPageSql(PageInfo pageInfo, String sql) {
int offset = (pageInfo.getPage() - 1) * pageInfo.getSize();
return new StringBuilder(sql).append(" limit                     ").append(offset).append(",").append(pageInfo.getSize()).toString();
}


/**
* 查询总记录数
* @param page 分页信息对象
* @param parameterObject 查询参数对象
* @param mappedStatement
* @param connection
* @throws SQLException
*/
protected void queryTotalRecord(PageInfo page, Object parameterObject, MappedStatement mappedStatement,                 Connection connection) throws SQLException {
BoundSql boundSql = mappedStatement.getBoundSql(page);
String sql = boundSql.getSql();
String countSql = this.buildCountSql(sql);
logger.info("生成的查询总页数的sql为:"+ countSql);
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, parameterMappings, parameterObject);
ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBoundSql);
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
   pstmt = connection.prepareStatement(countSql);
   parameterHandler.setParameters(pstmt);
   rs = pstmt.executeQuery();
   if (rs.next()) {
       int totalRecord = rs.getInt(1);
       page.setTotal(totalRecord);
       logger.info("查询到的总页数为:"+ totalRecord);
   }
} catch (Exception e) {
logger.error("执行查询总页数sql出现异常!", e);
} finally {
   if (rs != null)
       try {
           rs.close();
       } catch (Exception e) {
               logger.error("关闭ResultSet时异常.", e);
       }
   if (pstmt != null)
       try {
           pstmt.close();
       } catch (Exception e) {
               logger.error("关闭PreparedStatement时异常.", e);
       }
}
}


protected String buildCountSql(String sql) {
return "select count(1) from (" + sql +") as t";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值