Mybatis一级缓存和二级缓存初识

313 阅读3分钟

前言

Mybatis是一种Java持久层框架,常用于与关系型数据库交互。Mybatis的缓存机制是提高其性能的关键之一。Mybatis的缓存机制分为一级缓存和二级缓存两种,下面就一一介绍。

一级缓存

Mybatis的一级缓存是默认开启的,是指在一个SqlSession中,直接执行一次select语句所得到的结果被缓存起来,以便在后续执行相同的select语句时能够减少对数据库的访问。一级缓存的作用域是SqlSession,是线程内共享的缓存。在同一 SqlSession 中,多次执行相同的查询,只会查询一次数据库,后续查询直接从缓存中获取结果。一级缓存的生命周期与SqlSession的生命周期相同。

Mybatis的一级缓存是以HashMap的形式实现的,存储的是查询结果对象。在执行查询操作时,Mybatis会在一级缓存中通过查询key去匹配查询结果,如果查找到结果,则直接返回结果。如果查找不到结果,则通过执行SQL语句并将结果存入缓存中,当下一次再有相同的查询操作时,Mybatis会直接从一级缓存中获取结果,而不需要再去执行SQL语句。一级缓存所占内存是比较小的,优点是可控性强,缺点是只能在同一线程内共享。

二级缓存

Mybatis的二级缓存是与SqlSessionFactory相关联的缓存。它的作用域是mapper级别的,可以多个SqlSession共享数据。当同一个Mapper的SqlSession执行同一条SQL语句时,二级缓存可被使用,提高了查询效率。二级缓存存储的是缓存key对应的查询结果对象,可以理解为将多个SqlSession的一级缓存数据共享的缓存。

二级缓存是通过存储相应的命名空间缓存mapper级别的 select 查询、映射的集合结果集进行操作的。它的实现方式可以使用First level cache一样的hashMap,但是在Mybatis中通常使用第三方缓存框架如Ehcache、Redis等来实现。使用Ehcache和Redis等第三方缓存解决两个问题:缓存的分布式和共享问题。 Mybatis默认是不开启二级缓存的,需要在 Mybatis 配置文件中设置标签的type属性为“org.mybatis.caches.ehcache.EhcacheCache”或者“org.mybatis.caches.redis.RedisCache”。

二级缓存的使用需要遵循以下的条件:

  1. 对应的sql语句必须是相同的,如果不一样,那么将无法从缓存中获取数据。

  2. 二级缓存的查询结果,需要是可序列化的。这个也是使用二级缓存的弊端之一,将查询结果序列化和反序列化,会耗费很多的时间和系统资源。

  3. 对应的查询结果,不能是一个集合,例如List这样的对象是不能作为查询结果的,但是使用了ResultMap,可以将查询结果封装到一个POJO中。

总结

总体来说,Mybatis缓存机制的基本思想就是,将查询结果缓存到内存中,避免多次查询SQL,从而提高系统的查询性能,同时能够通过配置来控制缓存策略和缓存数量,从而避免缓存导致的内存性能问题。当然,Mybatis缓存机制并非万能,仍需要根据实际情况进行调整,才能发挥出最佳的性能效果。