MyBatis-Plus 分页查询以及自定义sql分页的实现

一、引言

分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页。

物理分页:相当于执行了limit分页语句,返回部分数据。物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性比较强,一般适用于数据量比较大,数据更新比较频繁的场景。

逻辑分页:一次性把全部的数据取出来,通过程序进行筛选数据。如果数据量大的情况下会消耗大量的内存,由于逻辑分页只需要读取数据库一次,不能获取数据库最新状态,实施性比较差,适用于数据量小,数据稳定的场合。

那么MP中的物理分页怎么实现呢? 往下看往下看

二、配置

创建MybatisPlusConfig配置类,需要配置分页插件,小编使用的Spring boot配置方式。

/**
 * @Auther: IT贱男
 * @Date: 2019/6/12 15:06
 * @Description: MybatisPlus配置类
 */
@Configuration
public class MyBatisPlusConfig {

  /**
   * 分页插件
   * @return
   */
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
  }
}

三、具体分页实现

MP的Wrapper提供了两种分页查询的方式,源码如下:

  /**
   * 根据 entity 条件,查询全部记录(并翻页)
   *
   * @param page     分页查询条件(可以为 RowBounds.DEFAULT)
   * @param queryWrapper 实体对象封装操作类(可以为 null)
   */
  IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

  /**
   * 根据 Wrapper 条件,查询全部记录(并翻页)
   *
   * @param page     分页查询条件
   * @param queryWrapper 实体对象封装操作类
   */
  IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

可见两个分页方法参数都是一致的,只是返回参数略有不同,具体选择根据实际业务为准。

  /**
   * 分页查询
   */
  @Test
  public void selectByPage() {
    QueryWrapper<User> wrapper = new QueryWrapper();
    wrapper.like("name", "雨").lt("age", 40);

    Page<User> page = new Page<>(1,2);

    //IPage<User> userIPage = userMapper.selectPage(page, wrapper);

    IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, wrapper);

    System.out.println("总页数"+mapIPage.getPages());
    System.out.println("总记录数"+mapIPage.getTotal());
    List<Map<String, Object>> records = mapIPage.getRecords();
    records.forEach(System.out::println);
  }

以上分页查询执行sql如下,先是查询了一次总记录数,然后在查询的数据。

DEBUG==>  Preparing: SELECT COUNT(1) FROM user WHERE name LIKE ? AND age < ?
DEBUG==> Parameters: %雨%(String), 40(Integer)
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 2
DEBUG==>  Preparing: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ? LIMIT ?,?
DEBUG==> Parameters: %雨%(String), 40(Integer), 0(Long), 2(Long)
TRACE<==    Columns: id, name, age, email, manager_id, create_time
TRACE<==        Row: 2, 张雨琪, 31, zjq@baomidou.com, 1088248166370832385, 2019-01-14 09:15:15
TRACE<==        Row: 3, 刘红雨, 31, lhm@baomidou.com, 1088248166370832385, 2019-01-14 09:48:16
DEBUG<==      Total: 2
总页数1
总记录数2

现在我们有需求只要查询数据即可, 不关心总记录数等,如果使用默认的方式就消耗不必要的性能。那么解决办法也是很简单的,只需要在创建page对象时传入第三个参数为false即可。

 Page<User> page = new Page<>(1,2,false);

四、自定义sql分页查询

有时候查询的数据难免会出现多表连接查询,或者是一些复杂的sql语句,但是这些语句也是需要支持分页查询的,

先定义查询接口,第一个参数要是分页的参数,小编这里演示就写简单的sql。

步骤一:在mapper文件中,编写对应的分页查询接口。

步骤二:在xml中编写对应的sql语句,小编这里演示的 “${ew.customSqlSegment}”,这个是如果你想自定义的sql语句,也想使用wrapper查询条件构造器,则需要在mapper接口中添加参数,以及xml中也要有固定。

  /**
   * 自定义sql分页
   * @param page
   * @param queryWrapper 看这里看这里,如果自定义的方法中需要用到wrapper查询条件,需要这样写
   * @return
   */
  IPage<User> selectMyPage(IPage<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">

  <select id="selectMyPage" resultType="com.example.demo.model.User">
    SELECT * FROM user ${ew.customSqlSegment}
  </select>

</mapper>
  /**
   * 自定义sql分页查询
   */
  @Test
  public void selectByMyPage() {
    QueryWrapper<User> wrapper = new QueryWrapper();
    wrapper.like("name", "雨").lt("age", 40);
    Page<User> page = new Page<>(1,2);
    IPage<User> mapIPage = userMapper.selectMyPage(page, wrapper);

    System.out.println("总页数"+mapIPage.getPages());
    System.out.println("总记录数"+mapIPage.getTotal());
    List<User> records = mapIPage.getRecords();
    records.forEach(System.out::println);
  }

五、多表sql分页查询

看评论有小伙伴反馈多表连接查询怎么分页,其实道理都是一样的。

小编以简单的为主,sql如下: his_ipd_encounter、his_user 两张表

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">

  <select id="selectByHisName" resultType="java.lang.String">
    select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
  </select>

</mapper>

mapepr如下:需要传入分页的参数,返回的类型也需要是分页对象

/**
 * <p>
 * 用户 Mapper 接口
 * </p>
 *
 * @author IT贱男
 * @since 2019-06-14
 */
public interface UserMapper extends MyMapper<User> {

  /**
   * 多表查询分页
   * @param page
   * @return
   */
  IPage<String> selectByHisName(IPage<User> page);
}

测试如下:通过查看日志,执行的sql加了分页条件的。

  @Test
  public void select(){
    // 创建分页参数
    Page<User> page = new Page<>(1,2);
    IPage<String> result = userMapper.selectByHisName(page);
    // 获取数据
    List<String> records = result.getRecords();
    records.forEach(System.out::println);
    System.out.println("总页数 = "+ result.getPages());
  }

ARNWarn: Could not find @TableId in Class: com.example.demo.model.HisUser.
INFOStarted UserMapperTest in 2.428 seconds (JVM running for 2.959)
select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
DEBUG==>  Preparing: SELECT COUNT(1) FROM his_ipd_encounter e, his_user u WHERE e.his_uid = u.his_uid
DEBUG==> Parameters:
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 117
DEBUG==>  Preparing: select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid LIMIT ?,?
DEBUG==> Parameters: 0(Long), 2(Long)
TRACE<==    Columns: realname
TRACE<==        Row: 胡伯云
TRACE<==        Row: 安元慧
DEBUG<==      Total: 2
 Time:20 ms - ID:com.example.demo.mapper.UserMapper.selectByHisName
Execute SQL:
    com.p6spy.engine.wrapper.PreparedStatementWrapper@61bcbcce

胡伯云
安元慧
总页数 = 59

到此这篇关于MyBatis-Plus 分页查询以及自定义sql分页的实现的文章就介绍到这了,更多相关MyBatis-Plus 自定义sql分页内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MyBatis-Plus多表联合查询并且分页(3表联合)

    这3张表的关系是模型表Model  ===> 训练表Training ===>应用表Application(大概的逻辑是:选择应用,然后训练,然后成为模型) 首先我们先建立实体Model(我使用的data注解不需要get set  @TableField(exist = false) 注解下的属性 是相关联表的属性) package cn.com.befery.dataai.po; import java.util.Date; import org.springframework.boot.j

  • Mybatis-Plus 多表联查分页的实现代码

    上一节,简单讲述了 Mybatis-Plus 搭建与使用入门,这一节,简单讲一下如何使用 MP 实现多表分页. 分析 使用的工程,依旧是 spring-boot,关于分页,官网给出了一个单表的demo,其实多表分页实现原理相同,都是通过 mybatis 的拦截器 (拦截器做了什么?他会在你的 sql 执行之前,为你做一些事情,例如分页,我们使用了 MP 不用关心 limit,拦截器为我们拼接.我们也不用关心总条数,拦截器获取到我们 sql 后,拼接 select count(*) 为我们查询总条

  • MyBatis-Plus 分页查询以及自定义sql分页的实现

    一.引言 分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页. 物理分页:相当于执行了limit分页语句,返回部分数据.物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性比较强,一般适用于数据量比较大,数据更新比较频繁的场景. 逻辑分页:一次性把全部的数据取出来,通过程序进行筛选数据.如果数据量大的情况下会消耗大量的内存,由于逻辑分页只需要读取数据库一次,不能获取数据库最新状态,实施性比较差,适用于数据量小,数据稳定的场合. 那么MP中的物理分页怎么实现

  • JPA原生SQL(自定义SQL)分页查询逻辑详解

    目录 JPA原生SQL(自定义SQL)分页查询 经过测试下面方法可以 pageable对象里定义排序的字段 JPA原生SQL分页查询踩坑记录 1.问题简述 2.解决方案 JPA原生SQL(自定义SQL)分页查询 JPA自己写SQL查询的话,分页还稍微麻烦 经过测试下面方法可以 @Query(nativeQuery = true, value = "select * from goods where " + " codeName like CONCAT('%',?1,'%')

  • MybatisPlus实现分页查询和动态SQL查询的示例代码

    目录 一.描述 二.实现方式 三. 总结 一.描述 实现下图中的功能,分析一下该功能,既有分页查询又有根据计划状态.开始时间.公司名称进行动态查询. 二.实现方式 Controller层 /** * @param userId 专员的id * @param planState 计划状态 * @param planStartTime 计划开始时间 * @param emtCode 公司名称-分身id * @return java.util.List<com.hc360.crm.entity.po.

  • Mybatis多表查询与动态SQL特性详解

    目录 1.较复杂的查询操作 1.1 参数占位符 #{} 和 ${} 1.2SQL注入 1.3like查询 1.4resultType与resultMap 1.4多表查询 1.4.1一对一表映射 1.4.2一对多表映射 2.动态SQL 2.1if标签 2.2trim标签 2.3where标签 2.4set标签 2.5foreach标签 总结 1.较复杂的查询操作 1.1 参数占位符 #{} 和 ${} #{}:预处理符,如将id=#{2}替换为id=?,然后使用2替换?. ${}:替换符,如将id

  • Java IPage分页操作 附加自定义sql

    目录 引入依赖 User实体类 controller service impl impl常规操作 impl自定义参数重写Sql 直接在impl 中写好 Sql 当作参数传入xml 引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.2</version&g

  • mybatis-plus实现自定义SQL、多表查询与多表分页查询语句实例

    目录 前言 1.自定义SQL 2.多表查询 3.多表分页查询 4.多表分页条件查询 总结 前言 本文介绍了在mybatis-plus中如何实现:自定义SQL语句,多表查询语句,多表分页查询语句 在说怎么实现之前我们要先明白一个概念,就是mybatis-plus是在mybatis的基础上进行增强,并不做改变,所以mybatis的操作在mybatis-plus中也是一样可以使用的,咱们直接上代码 1.自定义SQL 在mapper中自定义一个方法即可 @Repository public interf

  • Java Fluent Mybatis 分页查询与sql日志输出详解流程篇

    目录 前言 准备数据 Sql日志配置 官方分页查询 PageHelper分页查询 总结 前言 接着我上一章:Java Fluent Mybatis 项目工程化与常规操作详解流程篇 下 上一章我把项目做了一部分工程化包装,主要还是想要之后的调试能够方便一些.那么这一章接着上一章的内容,做一下查询分页,并且将每次请求所调用的sql语句写在日志里面,便于我们观察定位问题.代码之后还是会上传到github. GitHub代码仓库地址:GitHub仓库 准备数据 简单的准备了一些数据. Sql日志配置 之

  • MyBatis如何使用PageHelper实现分页查询

    目录 使用PageHelper实现分页查询 1.创建数据表 2.创建项目 2.1 创建实体类(Entity层) 2.2 数据库映射层(Mapper层) 3.运行测试 MyBatis PageHelper的使用 1.引入pagehelper的jar包 2.在mybatis的配置文件中配置拦截(也可以在spring配置文件中配置) 3.代码中如何实现 4.注意事项 分页不安全的情况 使用PageHelper实现分页查询 [实例]MyBatis使用PageHelper实现分页查询,并显示分页信息.执行

  • mysql oracle和sqlserver分页查询实例解析

    最近简单的对oracle,mysql,sqlserver2005的数据分页查询作了研究,把各自的查询的语句贴出来供大家学习..... (一).mysql的分页查询 mysql的分页查询是最简单的,借助关键字limit即可实现查询,查询语句通式: selecto.*from(sql)o limit firstIndex,pageSize 如下面的截图,每页显示的记录数为20: 查询(1-20)这20条记录 查询(21-40)这20条记录 mysql的分页查询就这么简单...... (二).sqls

  • MVC+EasyUI+三层新闻网站建立 分页查询数据功能(七)

    MVC新闻网站建立,完成分页查询数据功能. 1.在Model里面建立NewInfo(里面存放的是新闻信息的实体信息) 然后在DAL层中建立NewInfoDal (里面存放对新闻信息的操作) 写入分页查询的代码 /// <summary> /// 分页查询 /// </summary> /// <param name="start">分页开始条数</param> /// <param name="end">分

随机推荐