欢送微信搜寻公众号【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, 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
作者:IT 贱男
起源:https://jiannan.blog.csdn.net…
近期热文举荐:
SpringCloud 微服务电商我的项目教程