mybatis -- 7、一级缓存、二级缓存、第三方缓存(桌面自动创建缓存文件、自动生成java文件方便crud等)

目录

4、缓存

1、一级缓存:

在某些情况下,一级缓存可能会失效?

    1、

    2、

    3、

2、二级缓存:

(1)缓存的使用

(2)缓存的属性

(3)二级缓存的作用范围:

3、整合第三方缓存

(1)桌面自动创建缓存文件

(2)自动创建文件、自动设置好代码(能够运行基本增删改查操作,但是除了没有toSping)

(3)自动生成文件(@Generated系列):


4、缓存

    MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。

    默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

当添加上该标签之后,会有如下效果:

  1. 映射语句文件中的所有 select 语句的结果将会被缓存。
  2. 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  3. 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  4. 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  5. 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  6. 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

在进行配置的时候还会分为一级缓存和二级缓存:

一级缓存:线程级别的缓存,是本地缓存,sqlSession级别的缓存

二级缓存:全局范围的缓存,不止局限于当前会话

mybatis中的缓存机制:
    如果没有缓存,那么每次查询的时候都需要从数据库中加载数据,这回造成io的性能问题,所以,在很多情况下
    如果连续执行两条相同的sql语句,可以直接从缓存中获取,如果获取不到,那么再去查询数据库,这意味着查询完成的结果需要放到缓存中。

 

缓存分类:
    1、一级缓存:表示sqlSession线程级别的缓存,每次查询的时候会开启一个会话,此会话相当于一次连接,关闭之后自动失效
    2、二级缓存:全局范围内的缓存,sqlSession线程关闭之后才会生效
    3、第三方缓存:继承第三方的组件,来充当缓存的作用

1、一级缓存:

一级缓存:表示将数据存储在sqlsession线程中,关闭之后自动失效,

默认情况下是开启的
    在同一个会话之内,如果执行了多个相同的sql语句,那么除了第一个之外,所有的数据都是从缓存中进行查询的

MyTest.java

    @Test
    public void test07() throws IOException {
//获取与数据库相关的会话
        SqlSession sqlSession线程 = sqlSessionFactory.openSession();
//获取对应的映射接口对象
        EmpDao mapper映射 = sqlSession.getMapper(EmpDao.class);
        Emp emp = mapper.selectEmpByEmpno(7369);
        System.out.println(emp);
        sqlSession.close();
    }

MyTest.java

@Test
    public void test07() throws IOException {
//获取与数据库相关的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
//获取对应的映射接口对象
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        Emp emp = mapper.selectEmpByEmpno(7369);
        System.out.println(emp);

================================== 添加 =======================================
        Emp emp2 = mapper2.selectEmpByEmpno(7369);
        System.out.println(emp2);
===============================================================================
        sqlSession.close();
    }

在某些情况下,一级缓存可能会失效?

    1、

在同一个方法中,可能会开启多个会话,那么会造成缓存失效。此时需要注意,会话跟方法没有关系,不是一个方法就只能由一个会话,所以严格记住,缓存的数据是保存在sqlsession线程中的

MyTest.java

@Test
    public void test07() throws IOException {
//获取与数据库相关的会话
        SqlSession sqlSession线程 = sqlSessionFactory.openSession();
//获取对应的映射接口对象
        EmpDao mapper映射 = sqlSession.getMapper(EmpDao.class);
        Emp emp = mapper.selectEmpByEmpno(7369);
        System.out.println(emp);

================================== 添加 =======================================
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);
===============================================================================
        Emp emp2 = mapper2.selectEmpByEmpno(7369);
        System.out.println(emp2);
        sqlSession.close();
        sqlSession2.close();
    }

    2、

当传递对象的时候,如果对象中的属性值不一致,也不会走缓存

MyTest.java

    Emp emp = new EmpDao();
@Test
    public void test08() throws IOException {
//获取与数据库相关的会话
        SqlSession sqlSession线程 = sqlSessionFactory.openSession();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
//获取对应的映射接口对象
        EmpDao mapper映射 = sqlSession.getMapper(EmpDao.class);

        emp.setEmpno (7369);
        Emp emp2 = mapper.selectEmpCondition(emp);
        System.out.println(emp2);

        emp.setEmpno (7340);
        Emp emp3 = mapper.selectEmpCondition(emp);
        System.out.println(emp3);

        sqlSession.close();
    }

    3、

在多次查询过程中,如果修改了数据,那么缓存也会失效

EmpDao.java

public interface EmpDao {

    public Emp selectEmpByEmpno(Integer empno);
    public Emp selectEmpByStep(Integer empno);
    public Emp selectEmpByStep2(Integer deptno);
    public Emp selectEmpByCondition(Emp emp);
    public List<Emp> selectEmpByDeptnos(@Param("deptnos") List<Integer> deptnos);
================================== 添加 =======================================
    public Integer update(Emp emp);
===============================================================================
}

EmpDao.xml

<update id="update更新">
    update emp set ename=#{ename} where empno = #{empno}
</update>

MyTest.java

    @Test
    public void test08() throws IOException {
//获取与数据库相关的会话
        SqlSession sqlSession线程 = sqlSessionFactory.openSession();
//获取对应的映射接口对象
        EmpDao mapper映射 = sqlSession.getMapper(EmpDao.class);
        Emp emp = mapper.selectEmpByEmpno(7369);
        System.out.println(emp);
        System.out.println("==================");

        emp.setEname("Teacher教师");
        Integer update更新 = mapper.update(emp);
        System.out.println(update);
        System.out.println("==================");
        emp = mapper.selectEmpByEmpno(7369);
        System.out.println(emp);
        sqlSession.close();
    }

//输出共三个

第一查询,第二更新,第三没查询,而是直接输出缓存的数据

   4、如果在一个会话过程中,过程中手动清空了缓存,那么缓存也会失效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值