Mybatis的分页,延迟加载和缓存

目录

分页:

[方式一:利用 limit 实现物理分页](#方式一:利用 limit 实现物理分页)

利用limit的关键字分页

方式二:RowBounds集合逻辑分页

方式三:插件分页

延迟加载和立即加载:

什么是立即加载:

什么是延迟加载

延迟加载的配置

缓存:

什么是缓存:

特点:

限制:

缓存的术语:

什么是Mybatis缓存:

缓存的适用性:

Mybatis缓存的分类:

一级缓存:

一级缓存失效的情况:

二级缓存:

自定义缓存:


在Mybatis中,我们对于查询到的大量数据有不同的需求,那么在处理时,必然涉及到分页问题,拿去数据时,必然会涉及缓存问题。下面,我将对Mybatis中的分页和缓存作以详解

分页:

方式一:利用 limit 实现物理分页

特点:此种方式,本身就会在数据库分好页,将所需的数据IO读取。

利用limit的关键字分页

例如:(以注解为例)

接口中:

vbnet 复制代码
@Select("select * from student  limit #{weizhi},#{bc}")
	public List<Student> findStudentlimit(
			@Param("weizhi")int  weizhi,
			@Param("bc")int bc);

测试:

vbnet 复制代码
public static void main(String[] args) {
		
		SqlSession sqlSession = DaoUtil.getSqlSession();
		
		StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //位置是从0开始的,
        //此处为从第二条数据开始,取三条数据
        List<Student> list = mapper.findAllStudentlimit(1,3);
        
        list.forEach(System.out::println);
}

结果

方式二:RowBounds集合逻辑分页

特点:此种方式会将所有的数据先IO读取到内存,再分页。

此种方式需要创建一个RowBounds对象,内部有参构造表示,其实位置和步长

接口方法

vbnet 复制代码
	//方式er:RowBounds  逻辑分页
	@Select("select * from student")
	public List<Student> findAllStudent(RowBounds rs);

测试:

vbnet 复制代码
public static void main(String[] args) {
		
		SqlSession sqlSession = DaoUtil.getSqlSession();
		StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //注意:内部有参构造
        //第一个:第几页
        //第二个:表示步长
        RowBounds rs  = new RowBounds(3,2);
		List<Student> list1 = mapper.findAllStudent(rs);
		list1.forEach(System.out::println);
}

结果:

方式三:插件分页

注意:此种方式可以获取page对象和pageInfo都西昂

page对象:内部包含了pageNum表示当前页码,pageSize表示每页显示的数据条数等

pageInfo对象:比page包含更加全面,涉及页码等,展示。

所需插件jar:

jsqlparser-3.2.jar

pagehelper-5.2.0.jar

地址:

链接: https://pan.baidu.com/s/1scBpuL4Pf3kt0MIu_qc6ig?pwd=1111 提取码: 1111
此种方式也需要先在主配置文件配置插件

接口

vbnet 复制代码
//方式三:第三方插件  PageHelper
	@Select("select * from student")
	public List<Student> findAllStudentPageHelper();

测试:

vbnet 复制代码
public static void main(String[] args) {
		
		SqlSession sqlSession = DaoUtil.getSqlSession();
		StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
		
		//参数一:页数
		//参数二:步长
		Page<Object> page = PageHelper.startPage(7,2);
		
		
		List<Student> list = mapper.findAllStudentPageHelper();
		
		PageInfo<Student> pageInfo = new PageInfo<Student>(list);
		list.forEach(System.out::println);
		
		System.out.println(page);
		
		System.out.println(pageInfo);
		DaoUtil.closeResouces(sqlSession);
		
	}

结果

延迟加载和立即加载:

什么是立即加载:

不管信息用不用,只要调用,马上发起查询并进行加载
比如:
当我们查询学生信息时,就需要知道学生在哪个班级中,所以就需要立马去查询班级的信息
通常:当 一对一或者 多对一的时候需要立即加载

什么是延迟加载

在真正使用数据时才发起查询,不用的时候不查询
比如:
在查询班级信息,每个班级都会有很多的学生(假如每个班有100个学生),如果我们只是查看
班级信息,但是学生对象也会加载到内存中,会造成浪费。
所以我门需要进行懒加载,当确实需要查看班级中的学生信息,我门在进行加载班级中的学生信息。
通常: 一对多,或者多对多的是需要使用延迟加载

延迟加载的配置

全局配置

单个级联懒加载配置

lazy=true:表明开启懒加载

vbnet 复制代码
 <!-- 用户对订单的一对多关联配置 -->
  <resultMap id="userOrderMap" type="com.example.model.User">
    <id property="id" column="user_id"/>
    <result property="username" column="username"/>
    <collection property="orders" ofType="com.example.model.Order" 
                select="selectOrdersByUser" column="user_id" lazy="true"/>
  </resultMap>

缓存:

什么是缓存:

缓存(cache),数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据去除,放置在缓冲区中,应用程序从缓冲区读取数据。

特点:

数据库取出的数据保存在内存中,具备快速读取和使用

限制:

读取时无须再从数据库获取,数据可能不是最新的。

缓存的术语:

命中:需要的数据在缓存中找到结果

未命中:需要的数据在缓存中未找到,重新获取。

什么是Mybatis缓存:

功能: 减少与数据库交互次数,从而提升程序运行效率

方式:配置和定制

缓存的适用性:

适合缓存:

经常查询,并且不经常改变的

数据的正确与否对最终结果影戏不大的

比如,一个公司的介绍,新闻等

不适合缓存

经常改变的数据

数据的正确与否对最终结果影响很大的

比如商品的库存,股市的牌价

Mybatis缓存的分类:

一级缓存:SqlSession级别的缓存,针对一次会话操作内

二级缓存:映射器级别的缓存,针对factory级别的

自定义缓存:自定义缓存实现,例如redis

一级缓存:

任何一次增删改操作都会清空缓存

测试:


一级缓存的工作流程:

1.对于某个select statement,根据该statement生成key

2.判断 Loca Cache中,该key是否对应的数据存在

3.如果命中,则跳过查询数据库,继续往下走
缓存命中


缓存未命中:

4.如果未命中,去数据库中查询数据,得到查询结果

5.将key 和查询到的结果作为key和value,放入Local Cache中

6.将查询结果返回

7.判断缓存级别是否为Statement级别,如果是,清空本地缓存

一级缓存失效的情况:

1.不同的SqlSession对应不同的一级缓存

2.同一个SqlSession但查询条件不同

3.一个SqlSession 两次查询期间完成了任何一次增删改操作

4.同一个SqlSession两次查询期间手动清空了缓存

二级缓存:

配置二级缓存:

注解式配置


二级缓存小结(现在不用了):

Mybatis的二级缓存相对于一级缓存来说,实现了缓存数据的共享,可控性也更强

极大可能会数据出多,有设计缺陷,安全使用的条件苛刻

分布式环境下,必然会出现读取到错误数据,不推荐使用

自定义缓存:

实现缓存接口:实现 org. apache. ibatis. cache. Cache 接口自定义缓存;

引入第三方缓存:引入 Redis 等第三方内存库 作为 MyBatis 缓存。

相关推荐
懒羊羊不懒@4 分钟前
JavaSe—集合框架、Collection集合
java·开发语言
霸道流氓气质9 分钟前
Java中Stream使用示例-对实体List分组且保留原数据顺序并对分组后的每组内的数据进行部分业务逻辑修改操作
java·list
java1234_小锋42 分钟前
Spring事件监听的核心机制是什么?
java·spring·面试
星释1 小时前
Rust 练习册 16:Trait 作为返回类型
java·网络·rust
2301_796512521 小时前
Rust编程学习 - 如何理解Rust 语言提供了所有权、默认move 语义、借用、生命周期、内部可变性
java·学习·rust
乐悠小码1 小时前
Java设计模式精讲---03建造者模式
java·设计模式·建造者模式
一个人的幽默2 小时前
聊一下java获取客户的ip
java
披着羊皮不是狼2 小时前
Spring Boot——从零开始写一个接口:项目构建 + 分层实战
java·spring boot·后端·分层
Deamon Tree3 小时前
【设计题】如何实现限流器
java
短视频矩阵源码定制3 小时前
矩阵系统哪个好?2025年全方位选型指南与品牌深度解析
java·人工智能·矩阵·架构·aigc