【Java】MyBatis-Plus 分页查询以及自定义sql分页

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

老炮说Java发布于 今天 14:13

欢迎微信搜索公众号【java版web项目】获取资源:java学习视频/设计模式笔记/算法手册/java项目

一、引言

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

物理分页:相当于执行了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, [email protected], 1088248166370832385, 2019-01-14 09:15:15

TRACE<== Row: 3, 刘红雨, 31, [email protected], 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:

[email protected]

胡伯云

安元慧

总页数 = 59

近期热文推荐:
SpringCloud微服务电商项目教程

java程序员分页mybatis-plus

本文系转载,阅读原文

https://www.laopaojava.com/posts/38510.html

阅读 48发布于 今天 14:13

avatar

老炮说Java

完整电商项目,包含视频教程,详细文档:https://www.laopaojava.com/posts/38510.html

10 声望

1 粉丝

0 条评论

得票时间

avatar

老炮说Java

完整电商项目,包含视频教程,详细文档:https://www.laopaojava.com/posts/38510.html

10 声望

1 粉丝

宣传栏

欢迎微信搜索公众号【java版web项目】获取资源:java学习视频/设计模式笔记/算法手册/java项目

一、引言

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

物理分页:相当于执行了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, [email protected], 1088248166370832385, 2019-01-14 09:15:15

TRACE<== Row: 3, 刘红雨, 31, [email protected], 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:

[email protected]

胡伯云

安元慧

总页数 = 59

近期热文推荐:
SpringCloud微服务电商项目教程

以上是 【Java】MyBatis-Plus 分页查询以及自定义sql分页 的全部内容, 来源链接: www.h5w3.com/114008.html

回到顶部