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

 更新时间:2020年04月22日 16:29:35   作者:~来了小老弟  
这篇文章主要为大家详细介绍了Java使用MyBatis框架分页的5种方式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了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.控制层直接调用

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

相关文章

  • springmvc用于方法鉴权的注解拦截器的解决方案代码

    springmvc用于方法鉴权的注解拦截器的解决方案代码

    这篇文章主要介绍了springmvc用于方法鉴权的注解拦截器的解决方案代码,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • mybatisplus实现自动填充时间的项目实践

    mybatisplus实现自动填充时间的项目实践

    在数据库操作中,频繁设置创建时间和更新时间字段非常繁琐,通过使用MyBatis-Plus的自动填充功能,可以简化操作,本文就来详细的介绍一下,感兴趣的可以了解一下
    2024-10-10
  • Spring Boot如何使用HikariCP连接池详解

    Spring Boot如何使用HikariCP连接池详解

    这篇文章主要给大家介绍了关于Spring Boot如何使用HikariCP连接池的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用springboot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Java基础之方法重写和多态示例

    Java基础之方法重写和多态示例

    这篇文章主要介绍了Java基础之方法重写和多态,结合实例形式分析了java方法重写和多态的相关原理与使用技巧,需要的朋友可以参考下
    2019-08-08
  • Java中SpringBoot的TCC事务详解

    Java中SpringBoot的TCC事务详解

    这篇文章主要介绍了Java中SpringBoot的TCC事务详解,近年来,随着微服务架构的普及,TCC 事务成为了一种非常流行的分布式事务解决方案,在 Spring Boot 中,我们可以很容易地使用 TCC 事务来管理分布式事务,需要的朋友可以参考下
    2023-07-07
  • 使用AOP+反射实现自定义Mybatis多表关联查询

    使用AOP+反射实现自定义Mybatis多表关联查询

    这篇文章主要介绍了使用AOP+反射实现自定义Mybatis多表关联,目前的需求是增强现有的查询,使用简单的注解即可实现多表关联,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Spring Boot集成SpringFox 3.0与Pageable参数处理方法

    Spring Boot集成SpringFox 3.0与Pageable参数处理方法

    这篇文章主要介绍了Spring Boot集成SpringFox 3.0与Pageable参数处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-10-10
  • Java下载文件的4种方式总结

    Java下载文件的4种方式总结

    这篇文章主要给大家总结介绍了关于Java下载文件的4种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • java实现dijkstra最短路径寻路算法

    java实现dijkstra最短路径寻路算法

    这篇文章主要为大家详细介绍了java实现dijkstra最短路径寻路算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • java正则表达式的应用 java读取文件并获取电话号码

    java正则表达式的应用 java读取文件并获取电话号码

    这篇文章主要介绍了java正则表达式的应用,应用的内容是java读取文件并获取电话号码,感兴趣的小伙伴们可以参考一下
    2015-11-11

最新评论