Mybatis的一级缓存和二级缓存的理解以及用法

简介: 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。

程序中为什么使用缓存?

 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。

 对缓存有了一定的了解以后就知道了使用缓存是为了减少和数据库的交互次数,提高执行效率。那么下一个问题来了,什么样的数据能使用缓存,什么样的数据不能使用呢?

 这是我们使用缓存必须要明确的事情,实际上适用于缓存的数据指:经常查询并且不经常改变的,并且数据的正确与否对最终结果影响不大的,不适用于缓存的数据:经常改变的数据,数据的正确与否对最终结果影响很大的。

 Mybatis中的一级缓存和二级缓存到底缓存了什么,缓存了以后又有什么效果,缓存的数据什么时候会被清空?

 一级缓存:它指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession中为我们提供的一块区域中,该区域的结构是一个Map,当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用,当SqlSession对象消失时,mybatis的一级缓存也就消失了,同时一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、添加、删除、commit(),close等方法时,就会清空一级缓存。

 二级缓存:他指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出的结果对象与第一次存入的对象是不一样的。

 通过简单的例子来加深理解一级缓存和二级缓存。

一级缓存

1.用户类

public class User implements Serializable{
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    get和set方法省略.....
}

2.Dao层

public interface UserDao {
    /**
     * 查询所有的用户
     *
     * @return
     */
    List<User> findAll();
    /**
     * 根据Id查询用户
     *
     * @return
     */
    User findById(Integer id);
    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);
}

3.UserDao.xml映射文件

<mapper namespace="com.example.dao.UserDao">
    <select id="findAll" resultType="com.example.domain.User">
        SELECT * FROM USER;
    </select>
    <select id="findById" resultType="com.example.domain.User" parameterType="INT">
        SELECT * FROM  USER  WHERE ID = #{ID}
    </select>
    <update id="updateUser" parameterType="com.example.domain.User">
        update USER
        <set>
            <if test="username != null">username=#{username},</if>
            <if test="password != null">birthday=#{birthday},</if>
            <if test="sex != null">sex=#{sex},</if>
            <if test="address != null">address=#{address},</if>
        </set>
        where id=#{id}
    </update>
</mapper>

在以上三步中这是mybatis的单表操作,下面通过根据用户ID查询用户的操作来观察一级缓存生效与否的区别  

4.测试

(1) 命中一级缓存的情况

测试代码:

@Test
public void findByIdTest(){
    session = factory.openSession();
    userDao = session.getMapper(UserDao.class);
    //第一次获取该用户
    User user1 = userDao.findById(45);
    System.out.println(user1);
    第二次获取该用户
    User user2 = userDao.findById(45);
    System.out.println(user2);
    System.out.println(user1 == user2);
    session.close();
}

测试结果:


(2)对SqlSession进行清除缓存的操作,即清楚一级缓存,然后再次进行测试。

@Test
public void findByIdTest(){
    session = factory.openSession();
    userDao = session.getMapper(UserDao.class);
    User user1 = userDao.findById(45);
    System.out.println(user1);
    //session.commit(); 调用SqlSession的commit方法清空缓存
    user1.setUsername("更新用户");
    user1.setAddress("更新地址");
    userDao.updateUser(user1);//通过更新SqlSession清空缓存
    User user2 = userDao.findById(45);
    System.out.println(user2);
    System.out.println(user1 == user2);
    session.close();
}

清空缓存的操作很多,可以都试试。测试结果:

二级缓存  

 再看一下Mybatis二级缓存是如何使用的,第一步让Mybatis框架支持二级缓存(在Mybatis的主配置文件中配置),第二步让当前的映射文件支持二级缓存(在Dao.xml映射文件中配置),第三步让当前的方法支持二级缓存(在标签中配置)。根据这个步骤将上面的查询用户的接口通过配置改造为可以支持二级缓存的方法。

1.配置Mybatis框架支持二级缓存

<setting name="cacheEnabled" value="true"/>

2.配置UserDao.xml支持二级缓存

<cache/>

3.配置查询的方法支持二级缓存

<select id="findById" resultType="com.example.domain.User" parameterType="INT" useCache="true">
    SELECT * FROM  USER  WHERE ID = #{ID}
</select>

4.测试

@Test
public void findByIdTest(){
    //第一次查询 并更新二级缓存
    SqlSession session1 = factory.openSession();
    UserDao userDao1 = session1.getMapper(UserDao.class);
    User user1 = userDao1.findById(45);
    System.out.println(user1);
    session1.commit(); //commit()方法提交二级缓存 同时清空一级缓存
    session1.close();//
  //user1.setUsername("更新用户");
  //user1.setAddress("更新地址");
  //userDao.updateUser(user1);//通过更新SqlSession清空缓存
    //第二次查找命中二级缓存
    SqlSession session2 = factory.openSession();
    UserDao userDao2 = session2.getMapper(UserDao.class);
    User user2 = userDao2.findById(45);
    session2.commit(); //commit()方法提交二级缓存 同时清空一级缓存
    session2.close();//
    System.out.println(user2);
    System.out.println(user1 == user2);
}

测试结果:

总结:mybatis的的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回。查询数据的时候,查询的流程是二级缓存>一级缓存>数据库。


目录
相关文章
|
26天前
|
存储 缓存 芯片
让星星⭐月亮告诉你,当我们在说CPU一级缓存二级缓存三级缓存的时候,我们到底在说什么?
本文介绍了CPU缓存的基本概念和作用,以及不同级别的缓存(L1、L2、L3)的特点和工作原理。CPU缓存是CPU内部的存储器,用于存储RAM中的数据和指令副本,以提高数据访问速度,减少CPU与RAM之间的速度差异。L1缓存位于处理器内部,速度最快;L2缓存容量更大,但速度稍慢;L3缓存容量最大,由所有CPU内核共享。文章还对比了DRAM和SRAM两种内存类型,解释了它们在计算机系统中的应用。
67 1
|
2月前
|
缓存 Java 数据库连接
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
|
5天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
5天前
|
SQL 缓存 Java
MyBatis如何关闭一级缓存(分注解和xml两种方式)
MyBatis如何关闭一级缓存(分注解和xml两种方式)
24 5
|
21天前
|
缓存 Java 数据库连接
使用MyBatis缓存的简单案例
MyBatis 是一种流行的持久层框架,支持自定义 SQL 执行、映射及复杂查询。本文介绍了如何在 Spring Boot 项目中集成 MyBatis 并实现一级和二级缓存,以提高查询性能,减少数据库访问。通过具体的电商系统案例,详细讲解了项目搭建、缓存配置、实体类创建、Mapper 编写、Service 层实现及缓存测试等步骤。
|
2月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
1月前
|
SQL XML Java
Mybatis的<where>,<if>等标签用法
这篇文章详细解释了Mybatis中<where>和<if>等标签的用法,展示了如何在SQL动态构建中有效地过滤条件和处理逻辑分支。
155 1
|
1月前
|
SQL Java 数据库连接
Mybatis的<insert>,<update>,<delete>标签用法
这篇文章详细讲解了Mybatis中<insert>, <update>, <delete>标签的使用方法,并提供了示例代码来展示如何执行数据库的增删改操作。
19 0
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
44 1
|
4月前
|
SQL 缓存 Java
【面试官】Mybatis缓存有什么问题吗?
面试官:你说下对MyBatis的理解?面试官:那SqlSession知道吧?面试官:Mybatis的缓存有哪几种?面试官:那Mybatis缓存有什么问题吗?面试官:Mybatis分页插件是怎么
【面试官】Mybatis缓存有什么问题吗?

热门文章

最新文章