MyBatis分页插件

来源:互联网 发布:湖南步步高 知乎 编辑:程序博客网 时间:2024/06/10 07:03

        MyBatis分页插件--有测试代码哦,可以抄袭哦

20人阅读 评论(0)收藏举报
本文章已收录于:
分类:
作者同类文章X
    作者同类文章X

      也许分页插件是你最为感兴趣的东西,那好我们开完成一个分页插件。

      好长的代码,hold住哦。 博主今天累了,改天再和你们解释一下这个插件的设计思想。

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. package com.learn.mybatis.plugin;  
      2.   
      3. import java.sql.Connection;  
      4. import java.sql.PreparedStatement;  
      5. import java.sql.ResultSet;  
      6. import java.util.Map;  
      7. import java.util.Properties;  
      8.   
      9. import org.apache.ibatis.executor.parameter.ParameterHandler;  
      10. import org.apache.ibatis.executor.statement.StatementHandler;  
      11. import org.apache.ibatis.mapping.BoundSql;  
      12. import org.apache.ibatis.mapping.MappedStatement;  
      13. import org.apache.ibatis.plugin.Interceptor;  
      14. import org.apache.ibatis.plugin.Intercepts;  
      15. import org.apache.ibatis.plugin.Invocation;  
      16. import org.apache.ibatis.plugin.Plugin;  
      17. import org.apache.ibatis.plugin.Signature;  
      18. import org.apache.ibatis.reflection.MetaObject;  
      19. import org.apache.ibatis.reflection.SystemMetaObject;  
      20. import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;  
      21. import org.apache.ibatis.session.Configuration;  
      22.   
      23. /** 
      24.  * 
      25.  * @author ykzhen2015 
      26.  */  
      27. @Intercepts({  
      28.     @Signature(type = StatementHandler.class,  
      29.             method = "prepare",  
      30.             args = {Connection.class})})  
      31. public class PagingPlugin implements Interceptor {  
      32.   
      33.     private Integer defaultPage;  
      34.     private Integer defaultPageSize;  
      35.     private Boolean defaultUseFlag;  
      36.     private Boolean defaultCheckFlag;  
      37.   
      38.     @Override  
      39.     public Object intercept(Invocation invocation) throws Throwable {  
      40.         StatementHandler stmtHandler = getUnProxyObject(invocation);  
      41.         MetaObject metaStatementHandler = SystemMetaObject.forObject(stmtHandler);  
      42.         String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");  
      43.         //不是select语句.  
      44.         if (!this.checkSelect(sql)) {  
      45.             return invocation.proceed();  
      46.         }  
      47.         BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");  
      48.         Object parameterObject = boundSql.getParameterObject();  
      49.         PageParams pageParams = null;  
      50.         if (parameterObject instanceof Map) {  
      51.             Map parameterMap = (Map) parameterObject;  
      52.             pageParams = (PageParams) parameterMap.get("$pageParams");  
      53.         } else if (parameterObject instanceof PageParams) {  
      54.             pageParams = (PageParams) parameterObject;  
      55.         }  
      56.         if (pageParams == null) {  
      57.             throw new Exception("没有获得分页参数!!,请正确使用分页参数!!");  
      58.         }  
      59.         //获取参数.  
      60.         Integer pageNum = pageParams.getPage() == nullthis.defaultPage : pageParams.getPage();  
      61.         Integer pageSize = pageParams.getPageSize() == nullthis.defaultPageSize : pageParams.getPageSize();  
      62.         Boolean useFlag = pageParams.getUseFlag() == nullthis.defaultUseFlag : pageParams.getUseFlag();  
      63.         Boolean checkFlag = pageParams.getCheckFlag() == nullthis.defaultCheckFlag : pageParams.getCheckFlag();  
      64.         if (!useFlag) {  //不使用分页插件.  
      65.             return invocation.proceed();  
      66.         }  
      67.         int total = this.getTotal(invocation, metaStatementHandler, boundSql);  
      68.         pageParams.setTotal(total);  
      69.         //计算总页数.  
      70.         int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;  
      71.         pageParams.setTotalPage(totalPage);  
      72.         //检查当前页码的有效性.  
      73.         this.checkPage(checkFlag, pageNum, totalPage);  
      74.         //修改sql  
      75.         this.changeSQL(metaStatementHandler, boundSql, pageNum, pageSize);  
      76.         //执行查询,得到最后的结果.  
      77.         Object data = invocation.proceed();  
      78. //        PageDataPO pageData = this.dealPageData(data, pageTotal, total, pageSize, pageNum);  
      79.         return data;  
      80.     }  
      81.   
      82.   
      83.     /** 
      84.      * 判断是否sql语句. 
      85.      * @param sql 
      86.      * @return 
      87.      */  
      88.     private boolean checkSelect(String sql) {  
      89.         String trimSql = sql.trim();  
      90.         int idx = trimSql.toLowerCase().indexOf("select");  
      91.         return idx == 0;  
      92.     }  
      93.   
      94.     /** 
      95.      * 检查当前页码的有效性. 
      96.      * @param checkFlag 
      97.      * @param pageNum 
      98.      * @param pageTotal 
      99.      * @throws Throwable 
      100.      */  
      101.     private void checkPage(Boolean checkFlag, Integer pageNum, Integer pageTotal) throws Throwable  {  
      102.         if (checkFlag) {  
      103.             //检查页码page是否合法.  
      104.             if (pageNum > pageTotal) {  
      105.                 throw new Exception("查询失败,查询页码【" + pageNum + "】大于总页数【" + pageTotal + "】!!");  
      106.             }  
      107.         }  
      108.     }  
      109.   
      110.   
      111.     /** 
      112.      * 修改当前查询的SQL 
      113.      * @param metaStatementHandler 
      114.      * @param boundSql 
      115.      * @param page 
      116.      * @param pageSize 
      117.      */  
      118.     private void changeSQL(MetaObject metaStatementHandler, BoundSql boundSql, int page, int pageSize) {  
      119.         //获取当前需要执行的SQL  
      120.         String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");  
      121.         /** 
      122.          * TODO 这里使用的是MySQL其他数据库需要修改. 
      123.          * 根据你的数据库,修改分页的SQL 
      124.          */  
      125.         String newSql = "select * from (" + sql + ") $_paging_table limit " + (page - 1) * pageSize + ", " + pageSize;  
      126.         //修改当前需要执行的SQL  
      127.         metaStatementHandler.setValue("delegate.boundSql.sql", newSql);  
      128.     }  
      129.   
      130.     /** 
      131.      * 获取综述. 
      132.      * 
      133.      * @param ivt Invocation 
      134.      * @param metaStatementHandler statementHandler 
      135.      * @param boundSql sql 
      136.      * @return sql查询总数. 
      137.      * @throws Throwable 异常. 
      138.      */  
      139.     private int getTotal(Invocation ivt, MetaObject metaStatementHandler, BoundSql boundSql) throws Throwable {  
      140.         //获取当前的mappedStatement  
      141.         MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");  
      142.         //配置对象  
      143.         Configuration cfg = mappedStatement.getConfiguration();  
      144.         //当前需要执行的SQL  
      145.         String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");  
      146.         /** 
      147.         * TODO 如果是其他的数据库需要按你数据库的SQL规范改写. 
      148.         * 改写为统计总数的SQL 
      149.         */  
      150.         String countSql = "select count(*) as total from (" + sql + ") $_paging";  
      151.         //获取拦截方法参数,我们知道是Connection对象.  
      152.         Connection connection = (Connection) ivt.getArgs()[0];  
      153.         PreparedStatement ps = null;  
      154.         int total = 0;  
      155.         try {  
      156.             //预编译统计总数SQL  
      157.             ps = connection.prepareStatement(countSql);  
      158.             //构建统计总数SQL  
      159.             BoundSql countBoundSql = new BoundSql(cfg, countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());  
      160.             //构建MyBatis的ParameterHandler用来设置总数Sql的参数。  
      161.             ParameterHandler handler = new DefaultParameterHandler(mappedStatement, boundSql.getParameterObject(), countBoundSql);  
      162.             //设置总数SQL参数  
      163.             handler.setParameters(ps);  
      164.             //执行查询.  
      165.             ResultSet rs = ps.executeQuery();  
      166.             while (rs.next()) {  
      167.                 total = rs.getInt("total");  
      168.             }  
      169.         } finally {  
      170.             //这里不能关闭Connection否则后续的SQL就没法继续了。  
      171.             if (ps != null && ps.isClosed()) {  
      172.                 ps.close();  
      173.             }  
      174.         }  
      175.         System.err.println("总条数:" + total);  
      176.         return total;  
      177.     }  
      178.   
      179.     /** 
      180.      * 从代理对象中分离出真实对象. 
      181.      * 
      182.      * @param ivt --Invocation 
      183.      * @return 非代理StatementHandler对象 
      184.      */  
      185.     private StatementHandler getUnProxyObject(Invocation ivt) {  
      186.         StatementHandler statementHandler = (StatementHandler) ivt.getTarget();  
      187.         MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);  
      188.         // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过循环可以分离出最原始的的目标类)  
      189.         Object object = null;  
      190.         while (metaStatementHandler.hasGetter("h")) {  
      191.             object = metaStatementHandler.getValue("h");  
      192.         }  
      193.         if (object == null) {  
      194.             return statementHandler;  
      195.         }  
      196.         return (StatementHandler) object;  
      197.     }  
      198.   
      199.     @Override  
      200.     public Object plugin(Object statementHandler) {  
      201.         return Plugin.wrap(statementHandler, this);  
      202.     }  
      203.   
      204.     @Override  
      205.     public void setProperties(Properties props) {  
      206.         String strDefaultPage = props.getProperty("default.page""1");  
      207.         String strDefaultPageSize = props.getProperty("default.pageSize""50");  
      208.         String strDefaultUseFlag = props.getProperty("default.useFlag""false");  
      209.         String strDefaultCheckFlag = props.getProperty("default.checkFlag""false");  
      210.         this.defaultPage = Integer.parseInt(strDefaultPage);  
      211.         this.defaultPageSize = Integer.parseInt(strDefaultPageSize);  
      212.         this.defaultUseFlag = Boolean.parseBoolean(strDefaultUseFlag);  
      213.         this.defaultCheckFlag = Boolean.parseBoolean(strDefaultCheckFlag);  
      214.     }  
      215.   
      216.   
      217. }  

      注意:在代码注解的地方有些地方有TODO,这里我采用的是MySQL修改语句,如果你是其他数据库需要在哪里修改为对应数据库的SQL语句。


      有了这个插件,还不行哦,还要配置一下:

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1.      <plugins>  
      2.         <plugin interceptor="com.learn.mybatis.plugin.PagingPlugin">  
      3.             <!--默认第1页-->  
      4.             <property name="default.page" value="1" />  
      5.             <!--默认每页20条-->  
      6.             <property name="default.pageSize" value="20" />  
      7.             <!--默认不启用分页插件-->  
      8.             <property name="default.useFlag" value="false" />  
      9.             <!--默认不检查页码-->  
      10.             <property name="default.checkFlag" value="false" />  
      11.         </plugin>  
      12.     </plugins>  

      这样在MyBatis上下文就可以引用这个插件了。

      这里的配置:

      • default.page -- 缺省页码的时候,采用第1页
      • default.pageSize -- 缺省每页多少条配置的时候,才有每页20条
      • default.useFlag -- 查询是否启用分页插件,如果为false则不启用。
      • default.checkFlag -- 查询是否检查page当前页有效。如最大页码是2,程序传递为3,如此项为true,则抛出异常提示错误。如果为false则不抛出异常

      以上的默认参数都可以通过这个类进行改变:

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. package com.learn.mybatis.plugin;  
      2.   
      3.   
      4. /** 
      5.  * 
      6.  * @author ykzhen2015 
      7.  */  
      8. public class PageParams {  
      9.   
      10.     private Integer page;  
      11.     private Integer pageSize;  
      12.     private Boolean useFlag;  
      13.     private Boolean checkFlag;  
      14.     private Integer total;  
      15.     private Integer totalPage;  
      16.   
      17.     public Integer getPage() {  
      18.         return page;  
      19.     }  
      20.   
      21.     public void setPage(Integer page) {  
      22.         this.page = page;  
      23.     }  
      24.   
      25.     public Integer getPageSize() {  
      26.         return pageSize;  
      27.     }  
      28.   
      29.     public void setPageSize(Integer pageSize) {  
      30.         this.pageSize = pageSize;  
      31.     }  
      32.   
      33.     public Boolean getUseFlag() {  
      34.         return useFlag;  
      35.     }  
      36.   
      37.     public void setUseFlag(Boolean useFlag) {  
      38.         this.useFlag = useFlag;  
      39.     }  
      40.   
      41.     public Boolean getCheckFlag() {  
      42.         return checkFlag;  
      43.     }  
      44.   
      45.     public void setCheckFlag(Boolean checkFlag) {  
      46.         this.checkFlag = checkFlag;  
      47.     }  
      48.   
      49.     public Integer getTotal() {  
      50.         return total;  
      51.     }  
      52.   
      53.     public void setTotal(Integer total) {  
      54.         this.total = total;  
      55.     }  
      56.   
      57.     public Integer getTotalPage() {  
      58.         return totalPage;  
      59.     }  
      60.   
      61.     public void setTotalPage(Integer totalPage) {  
      62.         this.totalPage = totalPage;  
      63.     }  
      64.   
      65. }  

      当以下属性被设置会有这样的效果:

      • page  --插件默认设置default.page作废,采取这个值

      • pageSize --插件默认设置default.pageSize作废,采取这个值

      • useFlag --插件默认设置default.useFlag作废,采取这个值

      • checkFlag --插件默认设置default.checkFlag作废,采取这个值

      而:

      total  ——代表总条数,插件回自动帮我们回填

      totalPage ——代表总页数,插件回自动帮我们回填



      有了这个类,我们来举例如何使用它,我们先定义Mapper接口。

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. package com.learn.mybatis.chapter1.mapper;  
      2.   
      3. import java.util.List;  
      4. import java.util.Map;  
      5.   
      6. import org.apache.ibatis.annotations.Param;  
      7.   
      8. import com.learn.mybatis.chapter1.po.TRole;  
      9. import com.learn.mybatis.plugin.PageParams;  
      10. import com.learn.mybatis.plugin.TestParams;  
      11.   
      12. public interface RoleMapper {  
      13.     public TRole getRole(Long id);  
      14.   
      15.     public List<TRole> selectAllRole(TestParams pageParams);  
      16.   
      17.     public List<TRole> selectRoleByMap(Map<String, Object> params);  
      18.   
      19.       //"$pageParams"这个键不能修改   
      20.      public List<TRole> selectRoleByMap(@Param("roleName") String roleName, @Param("$pageParams") PageParams pageParams);  
      21. }  
       

      好,这里有三个select开头的方法,参数分别为POJO, map和MyBatis的注解型。这三种类型这个插件都可以适用。

      让我们看看POJO---TestParams,它继承了PageParams

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. package com.learn.mybatis.plugin;  
      2.   
      3. public class TestParams extends PageParams {  
      4.   
      5.     String roleName;  
      6.   
      7.     public String getRoleName() {  
      8.         return roleName;  
      9.     }  
      10.   
      11.     public void setRoleName(String roleName) {  
      12.         this.roleName = roleName;  
      13.     }  
      14. }  

      这时候我们看看roleMapper.xml

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. <?xml version="1.0" encoding="UTF-8" ?>  
      2.  <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
      3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
      4. <mapper namespace="com.learn.mybatis.chapter1.mapper.RoleMapper">  
      5.     <select id="getRole" parameterType="long" resultType="com.learn.mybatis.chapter1.po.TRole">  
      6.         select id, role_name as roleName, note from t_role where id=#{id}  
      7.     </select>  
      8.    
      9.    <select id="selectAllRole" parameterType="com.learn.mybatis.plugin.TestParams" resultType="com.learn.mybatis.chapter1.po.TRole">  
      10.         select id, role_name as roleName, note from t_role  
      11.         <where>  
      12.         <if test="roleName != null">  
      13.         role_name like concat('%', #{roleName}, '%')  
      14.         </if>  
      15.         </where>  
      16.     </select>  
      17.   
      18.     <select id="selectRoleByMap" parameterType="map" resultType="com.learn.mybatis.chapter1.po.TRole">  
      19.         select id, role_name as roleName, note from t_role  
      20.         <where>  
      21.         <if test="roleName != null">  
      22.         role_name like concat('%', #{roleName}, '%')  
      23.         </if>  
      24.         </where>  
      25.     </select>  
      26.   
      27.     <select id="selectRoleByKey"  resultType="com.learn.mybatis.chapter1.po.TRole">  
      28.         select id, role_name as roleName, note from t_role  
      29.         <where>  
      30.         <if test="roleName != null">  
      31.         role_name like concat('%', #{roleName}, '%')  
      32.         </if>  
      33.         </where>  
      34.     </select>  
      35. </mapper>  

      可以看好,三个select都有方法了。

      我们用main方法测试一下:

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. public static void main(String[] args) {  
      2.         testParams();  
      3.         testPOJO();  
      4.         testMap();  
      5.   
      6.     }  
      7.   
      8.     public static void testPOJO() {  
      9.         SqlSession sqlSession = null;  
      10.         try {  
      11.             sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession();  
      12.             RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);  
      13.             TestParams params = new TestParams();  
      14.             params.setUseFlag(true);  
      15.             params.setCheckFlag(false);  
      16.             params.setPage(2);  
      17.             params.setPageSize(5);  
      18.             params.setRoleName("test");  
      19.             List<TRole> pageData = roleMapper.selectAllRole(params);  
      20.             System.err.println("#######################测试POJO##################");  
      21.             System.err.println("总页数:" + params.getTotalPage());  
      22.             System.err.println("总条数:" + params.getTotal());  
      23.         } finally {  
      24.             sqlSession.close();  
      25.         }  
      26.     }  
      27.   
      28.     public static void testMap() {  
      29.         SqlSession sqlSession = null;  
      30.         try {  
      31.             sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession();  
      32.             RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);  
      33.             Map<String, Object> paramMap = new HashMap<String, Object>();  
      34.             PageParams pageParams = new PageParams();  
      35.             pageParams.setUseFlag(true);  
      36.             pageParams.setCheckFlag(false);  
      37.             pageParams.setPage(2);  
      38.             pageParams.setPageSize(5);  
      39.             paramMap.put("roleName""test");  
      40.            paramMap.put("$pageParams", pageParams);//"$pageParams"这个键不能修改  
      41.             List<TRole> pageData2 = roleMapper.selectRoleByMap(paramMap);  
      42.             System.err.println("#######################测试Map##################");  
      43.             System.err.println("总页数:" + pageParams.getTotalPage());  
      44.             System.err.println("总条数:" + pageParams.getTotal());  
      45.         } finally {  
      46.             sqlSession.close();  
      47.         }  
      48.     }  
      49.   
      50.     public static void testParams() {  
      51.         SqlSession sqlSession = null;  
      52.         try {  
      53.             sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession();  
      54.             RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);  
      55.             PageParams pageParams2 = new PageParams();  
      56.             pageParams2.setUseFlag(true);  
      57.             pageParams2.setCheckFlag(true);  
      58.             pageParams2.setPage(2);  
      59.             pageParams2.setPageSize(5);  
      60.             List<TRole> pageData3 = roleMapper.selectRoleByMap("test", pageParams2);  
      61.             System.err.println("#######################测试@Param##################");  
      62.             System.err.println("总页数:" + pageParams2.getTotalPage());  
      63.             System.err.println("总条数:" + pageParams2.getTotal());  
      64.         } finally {  
      65.             sqlSession.close();  
      66.         }  
      67.     }  

      好,他们都执行相同的查询,并且打印了总页数和总条数,会不会成功呢?我们看看打印的日志:

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. run:  
      2. DEBUG 2016-06-16 21:03:46,208 org.apache.ibatis.logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.  
      3. DEBUG 2016-06-16 21:03:46,818 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      4. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      5. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      6. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      7. DEBUG 2016-06-16 21:03:47,583 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection  
      8. DEBUG 2016-06-16 21:03:48,646 org.apache.ibatis.datasource.pooled.PooledDataSource: Created connection 2042495840.  
      9. DEBUG 2016-06-16 21:03:48,646 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      10. DEBUG 2016-06-16 21:03:48,662 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select count(*) as total from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging   
      11. DEBUG 2016-06-16 21:03:48,802 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      12. DEBUG 2016-06-16 21:03:48,896 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1  
      13. 总条数:11  
      14. DEBUG 2016-06-16 21:03:48,896 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select * from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging_table limit 55   
      15. DEBUG 2016-06-16 21:03:48,912 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      16. DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 5  
      17. #######################测试@Param##################  
      18. 总页数:3  
      19. 总条数:11  
      20. DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      21. DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      22. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool.  
      23. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection  
      24. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.datasource.pooled.PooledDataSource: Checked out connection 2042495840 from pool.  
      25. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      26. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select count(*) as total from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging   
      27. DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      28. DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1  
      29. 总条数:11  
      30. DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select * from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging_table limit 55   
      31. DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      32. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 5  
      33. #######################测试POJO##################  
      34. 总页数:3  
      35. 总条数:11  
      36. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      37. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      38. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool.  
      39. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection  
      40. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.datasource.pooled.PooledDataSource: Checked out connection 2042495840 from pool.  
      41. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      42. DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select count(*) as total from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging   
      43. DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      44. 总条数:11  
      45. DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1  
      46. DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select * from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging_table limit 55   
      47. DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      48. DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 5  
      49. #######################测试Map##################  
      50. 总页数:3  
      51. 总条数:11  
      52. DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      53. DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@79be0360]  
      54. DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool.  
      55. 成功构建 (总时间: 5 秒)  

      好,我们看到,我们的分页参数的总条数和总页数被回填了。而且我们可以通过useFlag属性来控制是否启用分页,这样对于select count(*) from t_role这样的语句我们通过设置参数,就可以不启用这个分页功能了。


      此外还有检查页码的功能,只要设置了属性,checkFlag插件会为我们检查这个页码的正确性,让我们看看:

      [java] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. public static void testException() {  
      2.         SqlSession sqlSession = null;  
      3.         try {  
      4.             sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession();  
      5.             RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);  
      6.             TestParams params = new TestParams();  
      7.             params.setUseFlag(true);  
      8.             params.setCheckFlag(true);//检查页码正确性  
      9.             params.setPage(5);//故意超过最大页数  
      10.             params.setPageSize(5);  
      11.             params.setRoleName("test");  
      12.             List<TRole> pageData = roleMapper.selectAllRole(params);  
      13.             System.err.println("#######################测试POJO##################");  
      14.             System.err.println("总页数:" + params.getTotalPage());  
      15.             System.err.println("总条数:" + params.getTotal());  
      16.         } finally {  
      17.             sqlSession.close();  
      18.         }  
      19.     }  

      params.setCheckFlag(true);//检查页码正确性

      注意这里设置了需要检验

      params.setPage(5);//故意超过最大页数

      这样让他超过了最大的页数。

      我们测试它,得到日志:

      [plain] view plain copy print?在CODE上查看代码片派生到我的代码片
      1. run:  
      2. DEBUG 2016-06-16 21:09:22,123 org.apache.ibatis.logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.  
      3. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      4. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      5. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      6. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.  
      7. DEBUG 2016-06-16 21:09:22,732 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection  
      8. DEBUG 2016-06-16 21:09:23,482 org.apache.ibatis.datasource.pooled.PooledDataSource: Created connection 1033490990.  
      9. DEBUG 2016-06-16 21:09:23,482 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d99d22e]  
      10. DEBUG 2016-06-16 21:09:23,513 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select count(*) as total from (select id, role_name as roleName, note from t_role WHERE role_name like concat('%', ?, '%')) $_paging   
      11. DEBUG 2016-06-16 21:09:23,669 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String)  
      12. DEBUG 2016-06-16 21:09:23,794 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1  
      13. 总条数:11  
      14. DEBUG 2016-06-16 21:09:23,810 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d99d22e]  
      15. DEBUG 2016-06-16 21:09:23,810 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d99d22e]  
      16. DEBUG 2016-06-16 21:09:23,826 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 1033490990 to pool.  
      17. Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:   
      18. ### Error querying database.  Cause: java.lang.reflect.UndeclaredThrowableException  
      19. ### The error may exist in com\learn\mybatis\chapter1\sqlmap\role.xml  
      20. ### The error may involve com.learn.mybatis.chapter1.mapper.RoleMapper.selectAllRole-Inline  
      21. ### The error occurred while setting parameters  
      22. ### Cause: java.lang.reflect.UndeclaredThrowableException  
      23.     at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)  
      24.     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:122)  
      25.     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113)  
      26.     at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122)  
      27.     at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64)  
      28.     at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)  
      29.     at com.sun.proxy.$Proxy3.selectAllRole(Unknown Source)  
      30.     at com.learn.mybatis.chapter1.main.MyBatisExample.testException(MyBatisExample.java:33)  
      31.     at com.learn.mybatis.chapter1.main.MyBatisExample.main(MyBatisExample.java:18)  
      32. Caused by: java.lang.reflect.UndeclaredThrowableException  
      33.     at com.sun.proxy.$Proxy4.prepare(Unknown Source)  
      34.     at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:76)  
      35.     at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:61)  
      36.     at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:303)  
      37.     at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:154)  
      38.     at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:102)  
      39.     at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:82)  
      40.     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120)  
      41.     ... 7 more  
      42. Caused by: java.lang.Exception: 查询失败,查询页码【5】大于总页数【3】!!  
      43.     at com.learn.mybatis.plugin.PagingPlugin.checkPage(PagingPlugin.java:105)  
      44.     at com.learn.mybatis.plugin.PagingPlugin.intercept(PagingPlugin.java:73)  
      45.     at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)  
      46.     ... 15 more  
      47. C:\Users\ykzhen\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1  
      48. 构建失败 (总时间: 2 秒)  
      0 0
      原创粉丝点击