mybatis分页如何实现?有几种常用分页方式?

TheDisguiser 2020-05-13 21:27:50 java常见问答 3882

说起数据库操作,分页绝对是少不了的,一般网站几乎都会有分页功能,下面我们就来了解一下基于mybatis和MySql的分页功能的几种实现方式吧。

一、Sql分页

具体实现:

1.接口下定义分页的方法

List < Student > queryStudentsBySql(Map < String, Object > data);

2.通过对应的xml文件获取所需节点的所有信息

<select id="queryStudentsBySql" parameterType="map" resultMap="studentmapper">
        select * from student limit #{currIndex} , #{pageSize}
</select>

3.编写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);
}

二、数组分页

具体实现:

1.接口定义所需方法

List < Student > queryStudentsByArray();

2.xml中获取需要节点

 <select id="queryStudentsByArray"  resultMap="studentmapper">
        select * from student
 </select>

3.service层的定义

接口
List < Student > queryStudentsByArray(int currPage, int pageSize);
实现接口
@Override
public 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中截取
}

4.编写控制层实现实现方法

  @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;
  }

三、拦截器分页

具体实现:

1.创建拦截器,拦截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");
    }
}

2.配置文件SqlMapConfig.xml

<configuration>
    <plugins>
        <plugin interceptor="com.autumn.interceptor.MyPageInterceptor">
            <property name="limit" value="10"/>
            <property name="dbType" value="mysql"/>
        </plugin>
    </plugins>
</configuration>

3.配置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>

4.service定义

  public List < AccountExt > getAllBookByPage(String pageNo, String pageSize)
    {
        return accountMapper.getAllBookByPage(Integer.parseInt(pageNo), Integer.parseInt(pageSize));
    }

5.编写controller

@RequestMapping("/getAllBook")
@ResponseBody
public 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;
}

以上就是mybatis分页的所有内容了,更多java常见问答相关知识请持续关注奇Q工具网了解吧。

推荐阅读:

mybatis批量insert该怎么实现?都有几种实现方式?

mybatis一级缓存和二级缓存是什么?有什么区别?

mybatis一对多是什么?有何作用?