mybatis四种分页方式
一
dao层是mybatis
不考虑前端分页的情况
二 数组分页
直接java代码
public List<User> queryByArray(int currPage, int pageSize) { //查询数据 List<User> list= mapper.query(); //从第几条数据开始 int firstIndex = (currPage - 1) * pageSize; //到第几条数据结束 int lastIndex = currPage * pageSize; //直接在list中截取 return list.subList(firstIndex, lastIndex); }
三 sql分页
xml添加
<select id="queryBySql" parameterType="map" resultMap="usermapper"> select * from user limit #{currIndex} , #{pageSize} </select>
java代码
public List<User> queryBySql(int currPage, int pageSize) { Map<String, Object> data = new HashedMap(); data.put("currIndex", (currPage-1)*pageSize); data.put("pageSize", pageSize); return mapper.queryBySql(data); }
四 拦截器分页
创建拦截器,拦截mybatis接口方法id以ByPage结束的语句
package com.autumn.interceptor; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import java.sql.Connection; import java.util.Map; import java.util.Properties; /** * @Intercepts 说明是一个拦截器 * @Signature 拦截器的签名 * type 拦截的类型 四大对象之一( Executor,ResultSetHandler,ParameterHandler,StatementHandler) * method 拦截的方法 * args 参数,高版本需要加个Integer.class参数,不然会报错 */ @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})}) public class MyPageInterceptor implements Interceptor { //每页显示的条目数 private int pageSize; //当前现实的页数 private int currPage; //数据库类型 private String dbType; @Override public Object intercept(Invocation invocation) throws Throwable { //获取StatementHandler,默认是RoutingStatementHandler StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); //获取statementHandler包装类 MetaObject MetaObjectHandler = SystemMetaObject.forObject(statementHandler); //分离代理对象链 while (MetaObjectHandler.hasGetter("h")) { Object obj = MetaObjectHandler.getValue("h"); MetaObjectHandler = SystemMetaObject.forObject(obj); } while (MetaObjectHandler.hasGetter("target")) { Object obj = MetaObjectHandler.getValue("target"); MetaObjectHandler = SystemMetaObject.forObject(obj); } //获取连接对象 //Connection connection = (Connection) invocation.getArgs()[0]; //object.getValue("delegate"); 获取StatementHandler的实现类 //获取查询接口映射的相关信息 MappedStatement mappedStatement = (MappedStatement) MetaObjectHandler.getValue("delegate.mappedStatement"); String mapId = mappedStatement.getId(); //statementHandler.getBoundSql().getParameterObject(); //拦截以.ByPage结尾的请求,分页功能的统一实现 if (mapId.matches(".+ByPage$")) { //获取进行数据库操作时管理参数的handler ParameterHandler parameterHandler = (ParameterHandler) MetaObjectHandler.getValue("delegate.parameterHandler"); //获取请求时的参数 Map<String, Object> paraObject = (Map<String, Object>) parameterHandler.getParameterObject(); //也可以这样获取 //paraObject = (Map<String, Object>) statementHandler.getBoundSql().getParameterObject(); //参数名称和在service中设置到map中的名称一致 currPage = (int) paraObject.get("currPage"); pageSize = (int) paraObject.get("pageSize"); String sql = (String) MetaObjectHandler.getValue("delegate.boundSql.sql"); //也可以通过statementHandler直接获取 //sql = statementHandler.getBoundSql().getSql(); //构建分页功能的sql语句 String limitSql; sql = sql.trim(); limitSql = sql + " limit " + (currPage - 1) * pageSize + "," + pageSize; //将构建完成的分页sql语句赋值个体'delegate.boundSql.sql',偷天换日 MetaObjectHandler.setValue("delegate.boundSql.sql", limitSql); } //调用原对象的方法,进入责任链的下一级 return invocation.proceed(); } //获取代理对象 @Override public Object plugin(Object o) { //生成object对象的动态代理对象 return Plugin.wrap(o, this); } //设置代理对象的参数 @Override public void setProperties(Properties properties) { //如果项目中分页的pageSize是统一的,也可以在这里统一配置和获取,这样就不用每次请求都传递pageSize参数了。参数是在配置拦截器时配置的。 String limit1 = properties.getProperty("limit", "10"); this.pageSize = Integer.valueOf(limit1); this.dbType = properties.getProperty("dbType", "mysql"); } }
大部分框架都是用这种实现方法,建议直接看框架的代码实现,此处做了解即可
四 RowBounds分页
mybatis接口加入RowBounds参数 ,在数据量小时,RowBounds不失为一种好办法。但是数据量大时,实现拦截器就很有必要了。
public List<User> queryByRowBounds( int start, int limit) { return mapper.query(new RowBounds(start, limit)); }
五 扯开了说
分页不应该一次查一页,最后就是一次查多几页,我的老大是这么要求的
也就是说上述查一页的方法有点落后了,不过改起来也简单
但是我和他说,连百度都是一页一页的查...
我和他都沉默了