当前位置: 移动技术网 > IT编程>开发语言>Java > Java使用MyBatis框架分页的5种方式

Java使用MyBatis框架分页的5种方式

2019年09月07日  | 移动技术网IT编程  | 我要评论
本文为大家分享了java使用mybatis框架分页的五种方式,供大家参考,具体内容如下 初始准备 1.创建分页对象类,方便模块间传值 //pageinfo.j

本文为大家分享了java使用mybatis框架分页的五种方式,供大家参考,具体内容如下

初始准备

1.创建分页对象类,方便模块间传值

//pageinfo.java
import lombok.data;

@data
public class pageinfo {

 private int pageno;

 private int pagesize;

}

2.定义dao层接口

import org.apache.ibatis.session.rowbounds;
import org.springframework.stereotype.repository;

import java.util.list;

@repository
public interface usermapper {

 user selectbyuser(user user);
 list<user> selectall();
 list<user> selectbypageinfo(pageinfo info);
 list<user> selectbyinterceptor(pageinfo info);

 list<user> selectbyrowbounds(rowbounds rowbounds);

}

3.mapper中定义结果集合baseresult

<resultmap id="baseresult" type="cn.edu.yau.pojo.user">
  <id property="id" column="id" jdbctype="integer"></id>
  <result property="username" column="username" jdbctype="varchar"></result>
  <result property="password" column="password" jdbctype="varchar"></result>
 </resultmap>

一、原始切分:最原始方法,不建议使用

1.mapper代码:查询所有数据

<select id="selectall" resultmap="baseresult">
 select * from tb_user
</select>

2.业务层代码:利用list的sublist()方法对数据进行切片

public list<user> findbyall(pageinfo info) {
  list<user> users = usermapper.selectall();
  return users.sublist(info.getpageno(), info.getpagesize());
 }

3.控制层代码

@requestmapping(value = "/userlist_1", method = requestmethod.get)
@responsebody
 public result finduserbysublist(pageinfo info) {
  list<user> users = userservice.findbyall(info);
  if(users.size() == 0) {
   return resultgenerator.genfailresult("未查找到用户");
  }
  return resultgenerator.gensuccessresult(users);
 }

二、limit关键字

1.mapper代码:利用limit关键字实现分页

<select id="selectbypageinfo" resultmap="baseresult">
  select * from tb_user limit #{pageno}, #{pagesize}
</select>

2.业务层直接调用

public list<user> findbypageinfo(pageinfo info) {
  return usermapper.selectbypageinfo(info);
 }

3.控制层直接调用

三、rowbounds实现分页

1.在dao层定义好所要传输的分页信息,类型为rowbounds

2.mapper层:查询所有数据

3.业务层:将pageinfo信息封装成rowbounds,调用dao层方法

public list<user> findbyrowbounds(pageinfo info) {
  return usermapper.selectbyrowbounds(new rowbounds(info.getpageno(), info.getpagesize()));
 }

4.控制层直接调用

四、mybatis的interceptor实现:实现复杂,需要明白mybatis的实现

1.创建interceptor

import org.apache.ibatis.executor.parameter.parameterhandler;
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.properties;

/**
 * 利用mybatis拦截器进行分页
 *
 * @intercepts 说明是一个拦截器
 * @signature 拦截器的签名
 * type 拦截的类型 四大对象之一( executor,resultsethandler,parameterhandler,statementhandler)
 * method 拦截的方法
 * args 参数,高版本需要加个integer.class参数,不然会报错
 *
 */
@intercepts({@signature(type = statementhandler.class, method = "prepare", args = {connection.class, integer.class})})
public class definedpageinterceptor implements interceptor {

 @override
 public object intercept(invocation invocation) throws throwable {
  //获取statementhandler,默认的是routingstatementhandler
  statementhandler statementhandler = (statementhandler) invocation.gettarget();
  //获取statementhandler的包装类
  metaobject metaobject = systemmetaobject.forobject(statementhandler);
  //分隔代理对象
  while (metaobject.hasgetter("h")) {
   object obj = metaobject.getvalue("h");
   metaobject = systemmetaobject.forobject(obj);
  }
  while (metaobject.hasgetter("target")) {
   object obj = metaobject.getvalue("target");
   metaobject = systemmetaobject.forobject(obj);
  }
  //获取查看接口映射的相关信息
  mappedstatement mappedstatement = (mappedstatement) metaobject.getvalue("delegate.mappedstatement");
  string mapid = mappedstatement.getid();
  //拦截以byinterceptor结尾的请求,统一实现分页
  if (mapid.matches(".+byinterceptor$")) {
   system.out.println("log:已触发分页拦截器");
   //获取进行数据库操作时管理参数的handler
   parameterhandler parameterhandler = (parameterhandler) metaobject.getvalue("delegate.parameterhandler");
   //获取请求时的参数
   pageinfo info = (pageinfo) parameterhandler.getparameterobject();
   //获取原始sql语句
   string originalsql = (string) metaobject.getvalue("delegate.boundsql.sql");
   //构建分页功能的sql语句
   string sql = originalsql.trim() + " limit " + info.getpageno() + ", " + info.getpagesize();
   metaobject.setvalue("delegate.boundsql.sql", sql);
  }
  //调用原对象方法,进入责任链下一级
  return invocation.proceed();
 }

 @override
 public object plugin(object target) {
  //生成object对象的动态代理对象
  return plugin.wrap(target, this);
 }

 @override
 public void setproperties(properties properties) {
  //如果分页每页数量是统一的,可以在这里进行统一配置,也就无需再传入pageinfo信息了
 }
}

2.将interceptor添加至mybatisconfig中,这里采用javaconfig的方式

@bean
 public sqlsessionfactorybean sqlsession() {
  sqlsessionfactorybean sqlsession = new sqlsessionfactorybean();
  sqlsession.setdatasource(datasource());
  try {
   resource[] resources = new pathmatchingresourcepatternresolver().getresources("classpath:mapper/*.xml");
   sqlsession.setmapperlocations(resources);
   //配置自定义的interceptro作为mybatis的interceptor,完成分页操作
   definedpageinterceptor definedpageinterceptor = new definedpageinterceptor();
   sqlsession.setplugins(new interceptor[]{definedpageinterceptor});
   return sqlsession;
  } catch (ioexception e) {
   e.printstacktrace();
  }
  return null;
 }

3.dao层接口方法名需要和代码中自定义的".+byinterceptor$"正则表达式相匹配,mapper的书写依然是查询所有数据

<select id="selectbyinterceptor" resultmap="baseresult">
  select * from tb_user
</select>

4.业务层直接调用

5.控制层直接调用

五、开源项目pagehelper实现:本质还是自己封装了个interceptor

1.引入pagehelper的jar包

<dependency>
  <groupid>com.github.pagehelper</groupid>
  <artifactid>pagehelper</artifactid>
  <version>5.1.10</version>
</dependency>

2.配置pageinterceptor

public pageinterceptor initpageinterceptor(){
  pageinterceptor pageinterceptor = new pageinterceptor();
  properties properties = new properties();
  //设置数据库类型
  properties.setproperty("helperdialect", "mysql");
  //该参数默认为false
  //设置为true时,会将rowbounds第一个参数offset当成pagenum页码使用
  //和startpage中的pagenum效果一样
  properties.setproperty("offsetaspagenum", "true");
  //该参数默认为false
  //设置为true时,使用rowbounds分页会进行count查询
  properties.setproperty("rowboundswithcount", "true");
  pageinterceptor.setproperties(properties);
  return pageinterceptor;
 }

 @bean
 public sqlsessionfactorybean sqlsession() {
  sqlsessionfactorybean sqlsession = new sqlsessionfactorybean();
  sqlsession.setdatasource(datasource());
  try {
   resource[] resources = new pathmatchingresourcepatternresolver().getresources("classpath:mapper/*.xml");
   sqlsession.setmapperlocations(resources);
   //配置pagehelper作为mybatis的interceptor,完成分页操作
   pageinterceptor pageinterceptor = this.initpageinterceptor();
   //配置自定义的interceptro作为mybatis的interceptor,完成分页操作
   definedpageinterceptor definedpageinterceptor = new definedpageinterceptor();
   sqlsession.setplugins(new interceptor[]{pageinterceptor, definedpageinterceptor});
   return sqlsession;
  } catch (ioexception e) {
   e.printstacktrace();
  }
  return null;
 }

3.mapper依然是查询所有数据

4.为dao层再封装一次方法

@repository
public class pagehelperhandler {

 @autowired
 private sqlsessionfactory sqlsessionfactory;

 public list<user> findbypagehelper(pageinfo info) {
  sqlsession session = sqlsessionfactory.opensession();
  pagehelper.startpage(info.getpageno(), info.getpagesize());
  //写到要使用到的类名和方法名
  list<user> users = session.selectlist("cn.edu.yau.mapper.usermapper.selectall");
  return users;
 }

}

6.业务层直接调用handler

7.控制层直接调用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网