1.数组分页
查询出全部数据,然后再list中截取需要的部分。
mybatis接口
List<Student> queryStudentsByArray();
xml配置文件
<select id="queryStudentsByArray" resultMap="studentmapper">select * from student</select>
service
接口
List<Student> queryStudentsByArray(int currPage, int pageSize);
实现接口@Overridepublic List<Student> queryStudentsByArray(int currPage, int pageSize) {//查询全部数据List<Student> students = studentMapper.queryStudentsByArray();//从第几条数据开始int firstIndex = (currPage - 1) * pageSize;//到第几条数据结束int lastIndex = currPage * pageSize;return students.subList(firstIndex, lastIndex); //直接在list中截取}
controller
@ResponseBody@RequestMapping("/student/array/{currPage}/{pageSize}")public List<Student> getStudentByArray(@PathVariable("currPage") int currPage, @PathVariable("pageSize") int pageSize) {List<Student> student = StuServiceIml.queryStudentsByArray(currPage, pageSize);return student;}
2.sql分页
mybatis接口
List<Student> queryStudentsBySql(Map<String,Object> data);
xml文件
<select id="queryStudentsBySql" parameterType="map" resultMap="studentmapper">select * from student limit #{currIndex} , #{pageSize}
</select>
service
接口
List<Student> queryStudentsBySql(int currPage, int pageSize);
实现类
public List<Student> queryStudentsBySql(int currPage, int pageSize) {Map<String, Object> data = new HashedMap();data.put("currIndex", (currPage-1)*pageSize);data.put("pageSize", pageSize);return studentMapper.queryStudentsBySql(data);}
3.拦截器分页
创建拦截器,拦截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;
@Overridepublic Object intercept(Invocation invocation) throws Throwable {//获取StatementHandler,默认是RoutingStatementHandlerStatementHandler 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$")) {//获取进行数据库操作时管理参数的handlerParameterHandler 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();}
//获取代理对象@Overridepublic Object plugin(Object o) {//生成object对象的动态代理对象return Plugin.wrap(o, this);}
//设置代理对象的参数@Overridepublic void setProperties(Properties properties) {//如果项目中分页的pageSize是统一的,也可以在这里统一配置和获取,这样就不用每次请求都传递pageSize参数了。参数是在配置拦截器时配置的。String limit1 = properties.getProperty("limit", "10");this.pageSize = Integer.valueOf(limit1);this.dbType = properties.getProperty("dbType", "mysql");}
}
配置文件SqlMapConfig.xml
<configuration><plugins><plugin interceptor="com.autumn.interceptor.MyPageInterceptor"><property name="limit" value="10"/><property name="dbType" value="mysql"/></plugin></plugins></configuration>
mybatis配置
<!--接口-->
List<AccountExt> getAllBookByPage(@Param("currPage")Integer pageNo,@Param("pageSize")Integer pageSize);
<!--xml配置文件--><sql id="getAllBooksql" >acc.id, acc.cateCode, cate_name, user_id,u.name as user_name, money, remark, time</sql><select id="getAllBook" resultType="com.autumn.pojo.AccountExt" >select<include refid="getAllBooksql" />from account as acc</select>
service
public List<AccountExt> getAllBookByPage(String pageNo,String pageSize) {return accountMapper.getAllBookByPage(Integer.parseInt(pageNo),Integer.parseInt(pageSize));}
controller
@RequestMapping("/getAllBook")@ResponseBodypublic Page getAllBook(String pageNo,String pageSize,HttpServletRequest request,HttpServletResponse response){pageNo=pageNo==null?"1":pageNo; //当前页码pageSize=pageSize==null?"5":pageSize; //页面大小//获取当前页数据List<AccountExt> list = bookService.getAllBookByPage(pageNo,pageSize);//获取总数据大小int totals = bookService.getAllBook();//封装返回结果Page page = new Page();page.setTotal(totals+"");page.setRows(list);return page;}
Page实体类
package com.autumn.pojo;import java.util.List;/*** Created by Autumn on 2018/6/21.*/
public class Page {private String pageNo = null;private String pageSize = null;private String total = null;private List rows = null;public String getTotal() {return total;}public void setTotal(String total) {this.total = total;}public List getRows() {return rows;}public void setRows(List rows) {this.rows = rows;}public String getPageNo() {return pageNo;}public void setPageNo(String pageNo) {this.pageNo = pageNo;}public String getPageSize() {return pageSize;}public void setPageSize(String pageSize) {this.pageSize = pageSize;}}
拦截器分页插件
使用pageHelper插件分页、主要是通过mybatis拦截器实现的
导入pageHelper包
<!--分页插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-autoconfigure</artifactId><version>1.4.1</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency>
配置文件中配置对应的属性
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/emp_dep?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTCusername: rootpassword: rootpagehelper:#指定数据库的方言helper-dialect: mysql#分页合理化参数,默认值为false。当该参数设置为 true 时,#pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。reasonable: true#支持通过 Mapper 接口参数来传递分页参数,默认值false,#分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页support-methods-arguments: true#为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值params: =count=countSql
配置完成之后,只需要在需要分页的service层代码,查询数据集合的上一行加一代码开启分页 PageHelper.startPage(pageNo,pageSize);
4.RowBounds分页
数据量小时,RowBounds不失为一种好办法。但是数据量大时,实现拦截器就很有必要了。
mybatis接口加入RowBounds参数
public List<UserBean> queryUsersByPage(String userName, RowBounds rowBounds);
service
@Override@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.SUPPORTS)public List<RoleBean> queryRolesByPage(String roleName, int start, int limit) {return roleDao.queryRolesByPage(roleName, new RowBounds(start, limit));}