目录
一. 特殊符号处理
二. MyBatis缓存机制
1. 什么是缓存?
2. 一级缓存
3. 二级缓存
一. 特殊符号处理
1. 在 mybatis 中的 xml 文件,一些特殊符号需要转译:
<!--转义字符 " <" 号会报错,">" 号不会报错 -->
<select id="teachers" resultType="Teacher">
select * from teacher where age < 30
</select>
2. 使用 <![CDATA[]]>
通过 <![CDATA[ 特殊字符 ]]> 包裹特殊字符也可以
<select id="teachers" resultType="Teacher">
select * from teacher where age <![CDATA[<]]> 30
</select>
注意:
- " <" 号会报错,">" 号不会报错;
- 如果<![CDATA[ ]]> 里有<if> </if> <where> </where><choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小<![CDATA[ ]]>的范围。
二. MyBatis缓存机制
1. 什么是缓存?
缓存 (Cache):是一种用于临时存储数据的技术,将数据临时存储在内存中。
缓存的作用:让数据离我们的执行程序更近,让程序能够快速的获取到数据,减少对数据库的访问压力。
缓存的主要类型有:
CPU缓存:处理器内置的缓存,分为L1、L2和L3级别,存储经常使用的指令和数据,减少处理器访问主内存的时间。
硬盘缓存:硬盘驱动器内部的缓存,暂存读写数据,以提高数据传输速度。
Web缓存:在浏览器或代理服务器中缓存网页内容,以减少网络请求次数,加快页面加载速度。
数据库缓存:在数据库中使用缓存技术,存储查询结果,以加速数据库的响应时间。
➱ MyBatis 提供了一级缓存和二级缓存来提高数据库查询的性能。
2. 一级缓存
MyBatis一级缓存默认是SqlSession级别的,在同一个SqlSession中查询到数据先缓存到SqlSession对象中,第二次查询数据时,先从SqlSession中查询,如果有直接返回,没有再去查询数据库。
代码演示:
Mapper接口:
Teacher findTeacherById(int id);
sql语句:
<select id="findTeacherById" resultType="Teacher">
select * from teacher where id = #{id}
</select>
测试代码: (重复查询三次id为1的老师信息)
@Test
public void test() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sessionFactory.openSession();
TeacherDao teacherDao = sqlSession.getMapper(TeacherDao.class);
Teacher teacher1 = teacherDao.findTeacherById(1);
Teacher teacher2 = teacherDao.findTeacherById(1);
Teacher teacher3 = teacherDao.findTeacherById(1);
System.out.println(teacher1);
System.out.println(teacher2);
System.out.println(teacher3);
sqlSession.close();
}
打印日志:(日志中只显示一条查询)
一级缓存失效的情况:
- sqlSession.close();
- sqlSession.clearCache();
- SqlSession 中执行了任何一个修改操作(update()、delete()、insert()) ,都会清空缓存的数据。
3. 二级缓存
• MyBatis二级缓存是SqlSessionFactory级别的,可以让多个SqlSession共享数据。
• MyBatis默认没有开启二级缓存,使用时需要配置并手动开启
• 若开启了二级缓存,当SqlSession关闭时,会将一级缓存中的数据存储到二级缓存中,其他的SqlSession就可以从二级缓存中查询到之前SqlSession查询的数据。
要开启二级缓存,需要进行以下步骤:
- 在 MyBatis 全局配置文件中的
<settings>
标签中配置开启二级缓存,设置cacheEnabled
为true
(默认值就是true
,也可以省略这一步) - 在具体的 mapper.xml 文件中添加
<cache/>
标签。 - 被缓存的 POJO(实体类)必须实现序列化接口(
implements Serializable
)
测试:
@Test
public void test() throws IOException {
SqlSession sqlSession1 = MyBatisUtil.getSQlSession();
TeacherDao teacherDao1 = sqlSession1.getMapper(TeacherDao.class);
Teacher teacher1 = teacherDao1.findTeacherById(1);
System.out.println(teacher1);
sqlSession1.close();
SqlSession sqlSession2 = MyBatisUtil.getSQlSession();
TeacherDao teacherDao2 = sqlSession2.getMapper(TeacherDao.class);
Teacher teacher2 = teacherDao2.findTeacherById(1);
System.out.println(teacher2);
sqlSession2.close();
}
二级缓存的特点包括:
- mapper 映射文件中的所有 select 语句将会被缓存。
- mapper 映射文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 二级缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。
- 如果在加入
<cache>
标签的前提下让个别 select 元素不使用缓存,可以使用useCache
属性,设置为false
。 - 缓存默认使用最近最少使用(LRU)算法来收回。
- 根据时间表,如
noFlushInterval
(没有刷新间隔),缓存不会以任何时间顺序来刷新。 - 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
- 缓存会被视为是可读/可写(read/write)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,不干扰其他调用者或线程所做的潜在修改。
<cache>
标签还有一些可选属性,用于更精细地控制缓存行为,例如:
eviction
:缓存的回收策略,默认是lru
(最近最少使用,移除最长时间不被使用的对象),还可以选择fifo
(先进先出,按对象进入缓存的顺序来移除它们)、soft
(软引用,移除基于垃圾回收器状态和软引用规则的对象)、weak
(弱引用,更积极地移除基于垃圾收集器和弱引用规则的对象)。flushInterval
:缓存刷新间隔,设置一个毫秒值表示多长时间清空一次缓存,默认不清空。readonly
:是否只读,true
(只读)表示 MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据,这样可以加快获取数据的速度;false
(读写,默认)表示 MyBatis 觉得获取的数据可能会被修改,会利用序列化或反序列化的技术克隆一份新的数据,速度相对较慢。size
:缓存存放元素的数量。type
:指定自定义缓存的全类名(实现Cache
接口即可)。
本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见
海漫浩浩,我亦苦作舟!大家一起学习,一起进步! 本人微信:g2279605572(欢迎大家与我交流 )