首页 > 其他分享 >MyBatis-缓存

MyBatis-缓存

时间:2022-09-30 11:07:55浏览次数:43  
标签:emp01 缓存 System println session MyBatis out


MyBatis缓存

缓存的目的就是为了提高执行效率

**内存:**不能永久存储数据,我们都知道内存他是​​断电即丢失​​​的,我们要想把数据永久存储,可以写入到磁盘上,但是缺点就是慢,而且我们的数据也不都是必须要永久存储的所以这里我们就需要用到缓存上
**缓存:**可以读取效率高,而且只是临时存储,每次不必从磁盘或者数据库中拿。

MyBatis为我们提供了一个​​缓存​​​的机制,用于储存​​临时的​​​,​​热点​​的数据,经常使用的数据。这个缓存是存储是存储到内存中的。

MyBatis-缓存_二级缓存


缓存的重要性不言而喻的,使用缓存,我们可以避免频繁的与数据库操作,尤其是在查询较多,缓存命中的几率好越高的情况下,我们使用缓存效率就很明显。

MyBatis缓存机制

MyBatis是默认开的一级缓存,也就是Session范围级别的缓存

一级缓存

  1. 默认开启的,线程级别的缓存,​​SqlSession的缓存​
  2. 在一个SqlSession生命周期中有效,即当SqlSession.close()后,缓存就被清空。
  3. 在同一个SqlSession中,MyBatis会把执行的方法通过算法生成一个缓存的键值,将键值和结果封装到一个Map里,如果后续的键值一致,则会从map中获取值,不必再操作数据库。
  4. 不同的SqlSession之间的缓存是相互隔离的
  5. 用一个SqlSession,可以通过配置使得在查询前清空缓存—​​flushCache=“true”​
  6. 任何的UPDATE,INSERT,DELETE语句都会清空缓存

eg:例如MyBatis一级缓存实例

@Test
public void testQueryByNameDeptNo2() throws Exception {
SqlSession session = SessionUtils.getSession();
System.out.println("=============一级缓存(第一个sqlsession1)=============");
System.out.println("=============第一次查询sqlsession1=============");
List<Emp01> list = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list) {
System.out.println(emp01);
}

System.out.println("=============第二次查询=============");
List<Emp01> list2 = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list2) {
System.out.println(emp01);
}
session.commit();
session.close();
}

缓存采用的临时存储的概念,见下:

MyBatis-缓存_java_02


可以看到执行了两句相同的查询操作后,只执行了一条SQL语句,那么原因就是MyBatis默认将第一个SQL查询的结果与参数封装到一个Map里,第二次查会先匹配查询查询参数,与第一次查询的参数相同,ok—>直接去Map里去获取

一级缓存是SqlSession级别的,见下:

我们开启两条SqlSession–>

@Test
public void testQueryByNameDeptNo2() throws Exception {
SqlSession session = SessionUtils.getSession();
System.out.println("=============一级缓存(第一个sqlsession1)=============");
System.out.println("=============第一次查询sqlsession1=============");
List<Emp01> list = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list) {
System.out.println(emp01);
}

System.out.println("=============第二次查询=============");
List<Emp01> list2 = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list2) {
System.out.println(emp01);
}

System.out.println();
SqlSession session2 = SessionUtils.getSession();
System.out.println("=============一级缓存(第二个sqlsession2)=============");
System.out.println("=============第一次查询sqlsession2=============");
List<Emp01> list3 = session2.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list3) {
System.out.println(emp01);
}

System.out.println("=============第二次查询sqlsession2=============");
List<Emp01> list4 = session2.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list4) {
System.out.println(emp01);
}
session.commit();
session.close();

session2.commit();
session2.close();
}

MyBatis-缓存_redis_03


我们看到这是就开启了两条的SQL语句,原因就证明了一级缓存是SqlSession级别的。

更新操作会清空缓存,见下

@Test
public void testQueryByNameDeptNo2() throws Exception { //MARTIN
SqlSession session = SessionUtils.getSession();
System.out.println("=============一级缓存(第一个sqlsession1)=============");
System.out.println("=============第一次查询sqlsession1=============");
List<Emp01> list = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list) {
System.out.println(emp01);
}

System.out.println("=============修改操作=============");
Emp01 emp0 = new Emp01();
emp0.seteName("TYGGIRE");
emp0.setEmpNo(7654);
emp0.setSalary(4500F);
session.getMapper(EmpMapper.class).updateEmp(emp0);

System.out.println("=============第二次查询=============");
List<Emp01> list2 = session.getMapper(EmpMapper.class).selectEmpByNameDeptNo2("MARTIN", 30);
for (Emp01 emp01 : list2) {
System.out.println(emp01);
}
session.commit();
session.close();
}

MyBatis-缓存_缓存_04


我们可以看到,之要执行了DML操作后,就会清空缓存,下次再查询相同条件的时候就不会再查询到原来的数据了,这也是符合正常的业务逻辑的,保证了数据的一致性。

二级缓存

  1. 进程级别的缓存,​​SqlSessionFactory的缓存​
  2. 在一个SqlSessionFactory的生命周期内有效,可以在多个SqlSession生命周期中共享
    3.​​​ 默认关闭​​​,需要使用的时候,需要为某个命名空间开启二级缓存在mapper.xml文件里中配置一个​​cache标签​​。
<!--开启二级缓存 需要对实体类进行是实体化-->
<cache />
  1. 由于在更新是会刷新缓存,因此需要注意使用场景,查询频率很高,更新频率很低时使用,即经常使用select,相对较少使用delete,insert,update语句的时候
  2. 二级缓存是以namespace为单位的,不同的namepace,尽量是在单表操作的时候使用二级缓存。

二级缓存的应用场景

  1. 对于访问多的查询请求并且用户但对查询的结构实时性要求较不高的情况下,可以使用MyBatis的二级缓存,降低数据的访问量,提高访问效率,如电话账单查询。
  2. 根据需求设置相应的FlushInterval:刷新间隔时间,比如二十分钟等等。

eg:二级缓存实例
开启二级缓存

1.首先在mybatis-config.xml里配置全局的缓存开关

<settings>
<setting name = "cacheEnabled" value = "true" />
</settings>
  1. 在对应的XXXmapper.xml里使用标签​​<cache/>​​开启二级缓存
  2. 将pojomapper映射类实现Serializable接口

    标签:emp01,缓存,System,println,session,MyBatis,out
    From: https://blog.51cto.com/u_14957231/5725617

相关文章

  • MyBatis加载Mapper映射文件的方式
    MyBatis加载Mapper的映射文件的方式我们都知道MyBatis是一款半自动的ORM框架,它的特点就是具有灵活的sql操作MyBatis是利用mapper的映射文件,来将数据库的中字段与Java的属性......
  • MYBatis-动态SQL
    MyBatis动态SQL什么是动态SQL?官方给出动态SQL的解释是一个基于OGNL的表达式,MyBatis3替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少......
  • MyBatis批量修改-Oracel
    MyBatis批量修改再利用MyBatis操作Oracle实现批量的修改操做的时候,需要用到存储过程的知识点批量修改,不同于批量的插入,批量修改可以同时操作不同表,但是如何保证他们是在同......
  • MyBatis-Plus 条件查询器
    MyBatis-Plus剩余内容​​本篇的主要代码依赖于之前的通用Mapper和通用Service篇​​前两个星期忙着转正的事情,比较忙。所以快两个周每太更新博客,这周末抓紧时间把剩余的MP......
  • SpringBoot之Mybatis开启SQL记录和Pagehelper
    配置mybatismybatis:#mapper路径mapper-locations:classpath:mapper/*.xmlconfiguration:#日志输出log-impl:org.apache.ibatis.logging.stdout.StdO......
  • CDN的缓存与回源机制解析
    CDN(ContentDeliveryNetwork,即内容分发网络)指的是一组分布在各个地区的服务器。这些服务器存储着数据的副本,因此服务器可以根据哪些服务器与用户距离最近,来满足数据的......
  • MyBatis
    1.概念Mybatis是一款半ORM(对象关系映射)的持久层框架,支持定制化SQL、存储过程以及高级映射。避免了几乎所有的JDBC代码和手动设置参数及获取结果集。可以使用注解或......
  • Mybatis学习
    什么是Mybatis?看官网的定义:MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的......
  • Mybatis(2022-09-29)
    SSMSpringMVC+Spring+Mybatis3SpringMVC:充当的就是Servlet的角色。可以理解为SpringMVC是Spring的WEB支持。1Mybatis:充当的就是Dao层。2Spring:充当的时一个润滑油......
  • springboot+mybatis 双数据源配置
    maven依赖spring-boot-starter-webmybatis-spring-boot-startermysql-connector-javalombokapplication.ymlserver:port:8080#启动端口spring:datasource:......