zoukankan      html  css  js  c++  java
  • MyBatis 分页之拦截器实现

      分页是WEB程序中常见的功能,mybatis分页实现与hibernate不同,相比hibernate,mybatis实现分页更为麻烦。mybatis实现分页需要自己编写(非逻辑分页RowBounds),以mysql为例,使用分页时需要自己在mapper中的sql语句中添加LIMIT #{xx},#{xx}。这种方式不具备可重用性与可拓展性。

      mybatis提供了plugins,plugins实现了拦截器的功能。它可以拦截指定类中的方法,当指定的方法被执行时,mybatis就会自动拦截并完成相应逻辑。通过mybatis的plugins,就可以实现自动分页功能。

      实现分析:拦截查询语句,判断该查询语句是否需要添加分页,修改原来的sql语句,查询得到的总记录数

      具体源码在https://github.com/yuen666/mybatis-pagination

    简要思路

      编写Interceptor,拦截StatementHandler中的prapare方法,在mybatis中,执行的是RoutingStatementHandler实现类。该类使用代理的方式来调用BaseStatementHandler。

      

      在每次使用查询语句时,都会调用RoutingStatementHandler.prepare(...),该方法的实现如下:

      

      它调用了delegate的prepare,实现类为BaseStatementHandler,源码如下:

      

      由于每次查询都调用该prepare方法,故可以对RoutingStatementHandler的prepare进行拦截。该方法中拥有connection对象,通过connection对象也可以连接数据库查询总记录数,比较方便。

      关于sql语句的修改。在delegate中,即BaseStatementHandler中,拥有如下几个域:

      

      其中,boundSql中包含了sql语句(boundSql.sql),由于是protected类型,所以可以采用反射的方式获取原sql语句并设置新sql语句。

      总结下:

    1. 拦截StatementHandler的prepare方法
    2. 通过反射获取delegate.boundSql.sql修改并设置
    3. 获取参数connection并查询中记录数

     关于反射

      mybaits提供了MetaObject类,该类对反射进行封装。可以通过该类快速的实现获取与设置delegate.boundSql.sql。

    private Object getValue(StatementHandler statementHandler, String exp) {
        MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
        return metaObject.getValue(exp);
    }
    private void setValue(StatementHandler statementHandler, String exp, Object obj) {
        MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
        metaObject.setValue(exp, obj);
    }

      其中的exp为OGNL表达式。

  • 相关阅读:
    第四十七讲 ASP.NET实例编程(六)
    第四十四讲 ASP.NET实例编程(三)
    第四十一讲 ASP.NET消息处理(二)
    第四十三讲 ASP.NET实例编程(二)
    第四十二讲 ASP.NET实例编程(一)
    第四十六讲 ASP.NET实例编程(五)
    第四十八讲 ASP.NET实战编程(一)
    第四十讲 ASP.NET消息处理(一)
    第四十五讲 ASP.NET实例编程(四)
    第三十九 ASP.NET编码
  • 原文地址:https://www.cnblogs.com/loading4/p/6414994.html
Copyright © 2011-2022 走看看