也许分页插件是你最为感兴趣的东西,那好我们开完成一个分页插件。
好长的代码,hold住哦。 博主今天累了,改天再和你们解释一下这个插件的设计思想。
package com.learn.mybatis.plugin; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Map; import java.util.Properties; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.scripting.defaults.DefaultParameterHandler; import org.apache.ibatis.session.Configuration; /** * * @author ykzhen2015 */ @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})}) public class PagingPlugin implements Interceptor { private Integer defaultPage; private Integer defaultPageSize; private Boolean defaultUseFlag; private Boolean defaultCheckFlag; @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler stmtHandler = getUnProxyObject(invocation); MetaObject metaStatementHandler = SystemMetaObject.forObject(stmtHandler); String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql"); //不是select语句. if (!this.checkSelect(sql)) { return invocation.proceed(); } BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql"); Object parameterObject = boundSql.getParameterObject(); PageParams pageParams = null; if (parameterObject instanceof Map) { Map parameterMap = (Map) parameterObject; pageParams = (PageParams) parameterMap.get("$pageParams"); } else if (parameterObject instanceof PageParams) { pageParams = (PageParams) parameterObject; } if (pageParams == null) { throw new Exception("没有获得分页参数!!,请正确使用分页参数!!"); } //获取参数. Integer pageNum = pageParams.getPage() == null? this.defaultPage : pageParams.getPage(); Integer pageSize = pageParams.getPageSize() == null? this.defaultPageSize : pageParams.getPageSize(); Boolean useFlag = pageParams.getUseFlag() == null? this.defaultUseFlag : pageParams.getUseFlag(); Boolean checkFlag = pageParams.getCheckFlag() == null? this.defaultCheckFlag : pageParams.getCheckFlag(); if (!useFlag) { //不使用分页插件. return invocation.proceed(); } int total = this.getTotal(invocation, metaStatementHandler, boundSql); pageParams.setTotal(total); //计算总页数. int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1; pageParams.setTotalPage(totalPage); //检查当前页码的有效性. this.checkPage(checkFlag, pageNum, totalPage); //修改sql this.changeSQL(metaStatementHandler, boundSql, pageNum, pageSize); //执行查询,得到最后的结果. Object data = invocation.proceed(); // PageDataPO pageData = this.dealPageData(data, pageTotal, total, pageSize, pageNum); return data; } /** * 判断是否sql语句. * @param sql * @return */ private boolean checkSelect(String sql) { String trimSql = sql.trim(); int idx = trimSql.toLowerCase().indexOf("select"); return idx == 0; } /** * 检查当前页码的有效性. * @param checkFlag * @param pageNum * @param pageTotal * @throws Throwable */ private void checkPage(Boolean checkFlag, Integer pageNum, Integer pageTotal) throws Throwable { if (checkFlag) { //检查页码page是否合法. if (pageNum > pageTotal) { throw new Exception("查询失败,查询页码【" + pageNum + "】大于总页数【" + pageTotal + "】!!"); } } } /** * 修改当前查询的SQL * @param metaStatementHandler * @param boundSql * @param page * @param pageSize */ private void changeSQL(MetaObject metaStatementHandler, BoundSql boundSql, int page, int pageSize) { //获取当前需要执行的SQL String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql"); /** * TODO 这里使用的是MySQL其他数据库需要修改. * 根据你的数据库,修改分页的SQL */ String newSql = "select * from (" + sql + ") $_paging_table limit " + (page - 1) * pageSize + ", " + pageSize; //修改当前需要执行的SQL metaStatementHandler.setValue("delegate.boundSql.sql", newSql); } /** * 获取综述. * * @param ivt Invocation * @param metaStatementHandler statementHandler * @param boundSql sql * @return sql查询总数. * @throws Throwable 异常. */ private int getTotal(Invocation ivt, MetaObject metaStatementHandler, BoundSql boundSql) throws Throwable { //获取当前的mappedStatement MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); //配置对象 Configuration cfg = mappedStatement.getConfiguration(); //当前需要执行的SQL String sql = (String) metaStatementHandler.getValue("delegate.boundSql.sql"); /** * TODO 如果是其他的数据库需要按你数据库的SQL规范改写. * 改写为统计总数的SQL */ String countSql = "select count(*) as total from (" + sql + ") $_paging"; //获取拦截方法参数,我们知道是Connection对象. Connection connection = (Connection) ivt.getArgs()[0]; PreparedStatement ps = null; int total = 0; try { //预编译统计总数SQL ps = connection.prepareStatement(countSql); //构建统计总数SQL BoundSql countBoundSql = new BoundSql(cfg, countSql, boundSql.getParameterMappings(), boundSql.getParameterObject()); //构建MyBatis的ParameterHandler用来设置总数Sql的参数。 ParameterHandler handler = new DefaultParameterHandler(mappedStatement, boundSql.getParameterObject(), countBoundSql); //设置总数SQL参数 handler.setParameters(ps); //执行查询. ResultSet rs = ps.executeQuery(); while (rs.next()) { total = rs.getInt("total"); } } finally { //这里不能关闭Connection否则后续的SQL就没法继续了。 if (ps != null && ps.isClosed()) { ps.close(); } } System.err.println("总条数:" + total); return total; } /** * 从代理对象中分离出真实对象. * * @param ivt --Invocation * @return 非代理StatementHandler对象 */ private StatementHandler getUnProxyObject(Invocation ivt) { StatementHandler statementHandler = (StatementHandler) ivt.getTarget(); MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler); // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过循环可以分离出最原始的的目标类) Object object = null; while (metaStatementHandler.hasGetter("h")) { object = metaStatementHandler.getValue("h"); } if (object == null) { return statementHandler; } return (StatementHandler) object; } @Override public Object plugin(Object statementHandler) { return Plugin.wrap(statementHandler, this); } @Override public void setProperties(Properties props) { String strDefaultPage = props.getProperty("default.page", "1"); String strDefaultPageSize = props.getProperty("default.pageSize", "50"); String strDefaultUseFlag = props.getProperty("default.useFlag", "false"); String strDefaultCheckFlag = props.getProperty("default.checkFlag", "false"); this.defaultPage = Integer.parseInt(strDefaultPage); this.defaultPageSize = Integer.parseInt(strDefaultPageSize); this.defaultUseFlag = Boolean.parseBoolean(strDefaultUseFlag); this.defaultCheckFlag = Boolean.parseBoolean(strDefaultCheckFlag); } }
注意:在代码注解的地方有些地方有TODO,这里我采用的是MySQL修改语句,如果你是其他数据库需要在哪里修改为对应数据库的SQL语句。
有了这个插件,还不行哦,还要配置一下:
<plugins> <plugin interceptor="com.learn.mybatis.plugin.PagingPlugin"> <!--默认第1页--> <property name="default.page" value="1" /> <!--默认每页20条--> <property name="default.pageSize" value="20" /> <!--默认不启用分页插件--> <property name="default.useFlag" value="false" /> <!--默认不检查页码--> <property name="default.checkFlag" value="false" /> </plugin> </plugins>
这样在MyBatis上下文就可以引用这个插件了。
这里的配置:
- default.page -- 缺省页码的时候,采用第1页
- default.pageSize -- 缺省每页多少条配置的时候,才有每页20条
- default.useFlag -- 查询是否启用分页插件,如果为false则不启用。
- default.checkFlag -- 查询是否检查page当前页有效。如最大页码是2,程序传递为3,如此项为true,则抛出异常提示错误。如果为false则不抛出异常
以上的默认参数都可以通过这个类进行改变:
package com.learn.mybatis.plugin; /** * * @author ykzhen2015 */ public class PageParams { private Integer page; private Integer pageSize; private Boolean useFlag; private Boolean checkFlag; private Integer total; private Integer totalPage; public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Boolean getUseFlag() { return useFlag; } public void setUseFlag(Boolean useFlag) { this.useFlag = useFlag; } public Boolean getCheckFlag() { return checkFlag; } public void setCheckFlag(Boolean checkFlag) { this.checkFlag = checkFlag; } public Integer getTotal() { return total; } public void setTotal(Integer total) { this.total = total; } public Integer getTotalPage() { return totalPage; } public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; } }
当以下属性被设置会有这样的效果:
- page --插件默认设置default.page作废,采取这个值
- pageSize --插件默认设置default.pageSize作废,采取这个值
- useFlag --插件默认设置default.useFlag作废,采取这个值
- checkFlag --插件默认设置default.checkFlag作废,采取这个值
而:
total ——代表总条数,插件回自动帮我们回填
totalPage ——代表总页数,插件回自动帮我们回填
有了这个类,我们来举例如何使用它,我们先定义Mapper接口。
package com.learn.mybatis.chapter1.mapper; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Param; import com.learn.mybatis.chapter1.po.TRole; import com.learn.mybatis.plugin.PageParams; import com.learn.mybatis.plugin.TestParams; public interface RoleMapper { public TRole getRole(Long id); public List<TRole> selectAllRole(TestParams pageParams); public List<TRole> selectRoleByMap(Map<String, Object> params); //"$pageParams"这个键不能修改 public List<TRole> selectRoleByMap(@Param("roleName") String roleName, @Param("$pageParams") PageParams pageParams); }
好,这里有三个select开头的方法,参数分别为POJO, map和MyBatis的注解型。这三种类型这个插件都可以适用。
让我们看看POJO---TestParams,它继承了PageParams
package com.learn.mybatis.plugin; public class TestParams extends PageParams { String roleName; public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
这时候我们看看roleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.learn.mybatis.chapter1.mapper.RoleMapper"> <select id="getRole" parameterType="long" resultType="com.learn.mybatis.chapter1.po.TRole"> select id, role_name as roleName, note from t_role where id=#{id} </select> <select id="selectAllRole" parameterType="com.learn.mybatis.plugin.TestParams" resultType="com.learn.mybatis.chapter1.po.TRole"> select id, role_name as roleName, note from t_role <where> <if test="roleName != null"> role_name like concat('%', #{roleName}, '%') </if> </where> </select> <select id="selectRoleByMap" parameterType="map" resultType="com.learn.mybatis.chapter1.po.TRole"> select id, role_name as roleName, note from t_role <where> <if test="roleName != null"> role_name like concat('%', #{roleName}, '%') </if> </where> </select> <select id="selectRoleByKey" resultType="com.learn.mybatis.chapter1.po.TRole"> select id, role_name as roleName, note from t_role <where> <if test="roleName != null"> role_name like concat('%', #{roleName}, '%') </if> </where> </select> </mapper>
可以看好,三个select都有方法了。
我们用main方法测试一下:
public static void main(String[] args) { testParams(); testPOJO(); testMap(); } public static void testPOJO() { SqlSession sqlSession = null; try { sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession(); RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); TestParams params = new TestParams(); params.setUseFlag(true); params.setCheckFlag(false); params.setPage(2); params.setPageSize(5); params.setRoleName("test"); List<TRole> pageData = roleMapper.selectAllRole(params); System.err.println("#######################测试POJO##################"); System.err.println("总页数:" + params.getTotalPage()); System.err.println("总条数:" + params.getTotal()); } finally { sqlSession.close(); } } public static void testMap() { SqlSession sqlSession = null; try { sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession(); RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); Map<String, Object> paramMap = new HashMap<String, Object>(); PageParams pageParams = new PageParams(); pageParams.setUseFlag(true); pageParams.setCheckFlag(false); pageParams.setPage(2); pageParams.setPageSize(5); paramMap.put("roleName", "test"); paramMap.put("$pageParams", pageParams);//"$pageParams"这个键不能修改 List<TRole> pageData2 = roleMapper.selectRoleByMap(paramMap); System.err.println("#######################测试Map##################"); System.err.println("总页数:" + pageParams.getTotalPage()); System.err.println("总条数:" + pageParams.getTotal()); } finally { sqlSession.close(); } } public static void testParams() { SqlSession sqlSession = null; try { sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession(); RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); PageParams pageParams2 = new PageParams(); pageParams2.setUseFlag(true); pageParams2.setCheckFlag(true); pageParams2.setPage(2); pageParams2.setPageSize(5); List<TRole> pageData3 = roleMapper.selectRoleByMap("test", pageParams2); System.err.println("#######################测试@Param##################"); System.err.println("总页数:" + pageParams2.getTotalPage()); System.err.println("总条数:" + pageParams2.getTotal()); } finally { sqlSession.close(); } }
好,他们都执行相同的查询,并且打印了总页数和总条数,会不会成功呢?我们看看打印的日志:
run: DEBUG 2016-06-16 21:03:46,208 org.apache.ibatis.logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. DEBUG 2016-06-16 21:03:46,818 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:03:46,834 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:03:47,583 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection DEBUG 2016-06-16 21:03:48,646 org.apache.ibatis.datasource.pooled.PooledDataSource: Created connection 2042495840. DEBUG 2016-06-16 21:03:48,646 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [[email protected]] 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 DEBUG 2016-06-16 21:03:48,802 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:03:48,896 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1 总条数:11 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 5, 5 DEBUG 2016-06-16 21:03:48,912 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 5 #######################测试@Param################## 总页数:3 总条数:11 DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [[email protected]] DEBUG 2016-06-16 21:03:48,927 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connectio[email protected]] DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.datasource.pooled.PooledDataSource: Checked out connection 2042495840 from pool. DEBUG 2016-06-16 21:03:48,943 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [[email protected]] 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 DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1 总条数:11 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 5, 5 DEBUG 2016-06-16 21:03:48,958 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 5 #######################测试POJO################## 总页数:3 总条数:11 DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [[email protected]] DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [[email protected]] DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.datasource.pooled.PooledDataSource: Checked out connection 2042495840 from pool. DEBUG 2016-06-16 21:03:48,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [[email protected]] 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 DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) 总条数:11 DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1 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 5, 5 DEBUG 2016-06-16 21:03:48,990 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 5 #######################测试Map################## 总页数:3 总条数:11 DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [[email protected]] DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [[email protected]] DEBUG 2016-06-16 21:03:49,005 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 2042495840 to pool. 成功构建 (总时间: 5 秒)
好,我们看到,我们的分页参数的总条数和总页数被回填了。而且我们可以通过useFlag属性来控制是否启用分页,这样对于select count(*) from t_role这样的语句我们通过设置参数,就可以不启用这个分页功能了。
此外还有检查页码的功能,只要设置了属性,checkFlag插件会为我们检查这个页码的正确性,让我们看看:
public static void testException() { SqlSession sqlSession = null; try { sqlSession = MyBatisUtil.getSqlSessionFactroy().openSession(); RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); TestParams params = new TestParams(); params.setUseFlag(true); params.setCheckFlag(true);//检查页码正确性 params.setPage(5);//故意超过最大页数 params.setPageSize(5); params.setRoleName("test"); List<TRole> pageData = roleMapper.selectAllRole(params); System.err.println("#######################测试POJO##################"); System.err.println("总页数:" + params.getTotalPage()); System.err.println("总条数:" + params.getTotal()); } finally { sqlSession.close(); } }
params.setCheckFlag(true);//检查页码正确性
注意这里设置了需要检验
params.setPage(5);//故意超过最大页数
这样让他超过了最大的页数。
我们测试它,得到日志:
run: DEBUG 2016-06-16 21:09:22,123 org.apache.ibatis.logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:09:22,341 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections. DEBUG 2016-06-16 21:09:22,732 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection DEBUG 2016-06-16 21:09:23,482 org.apache.ibatis.datasource.pooled.PooledDataSource: Created connection 1033490990. DEBUG 2016-06-16 21:09:23,482 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [[email protected]] 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 DEBUG 2016-06-16 21:09:23,669 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: test(String) DEBUG 2016-06-16 21:09:23,794 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1 总条数:11 DEBUG 2016-06-16 21:09:23,810 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [[email protected]] DEBUG 2016-06-16 21:09:23,810 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [[email protected]] DEBUG 2016-06-16 21:09:23,826 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 1033490990 to pool. Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.reflect.UndeclaredThrowableException ### The error may exist in com\learn\mybatis\chapter1\sqlmap\role.xml ### The error may involve com.learn.mybatis.chapter1.mapper.RoleMapper.selectAllRole-Inline ### The error occurred while setting parameters ### Cause: java.lang.reflect.UndeclaredThrowableException at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:122) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113) at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53) at com.sun.proxy.$Proxy3.selectAllRole(Unknown Source) at com.learn.mybatis.chapter1.main.MyBatisExample.testException(MyBatisExample.java:33) at com.learn.mybatis.chapter1.main.MyBatisExample.main(MyBatisExample.java:18) Caused by: java.lang.reflect.UndeclaredThrowableException at com.sun.proxy.$Proxy4.prepare(Unknown Source) at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:76) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:61) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:303) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:154) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:102) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:82) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120) ... 7 more Caused by: java.lang.Exception: 查询失败,查询页码【5】大于总页数【3】!! at com.learn.mybatis.plugin.PagingPlugin.checkPage(PagingPlugin.java:105) at com.learn.mybatis.plugin.PagingPlugin.intercept(PagingPlugin.java:73) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ... 15 more C:\Users\ykzhen\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1 构建失败 (总时间: 2 秒)
我们看到了,异常,并且指明超过了最大总页数