mybatis的一级缓存和二级缓存

前言

本篇博客主要分享和梳理mybatis相关技术点

正文

Mybatis中的一级缓存和二级缓存:
一级缓存:
一级缓存作用域是SqlSession,缓存data为resultsets和auto-mappings的结果。
一级缓存默认开启,无法关闭。
一级缓存失效的四种情况:

  1. 不同的SqlSession对应不同的一级缓存。
  2. 同一个SqlSession但是查询条件不同,导致生成的SQL语句不同。
  3. 同一个SqlSession两次查询期间执行了任何一次增删改操作。
  4. 同一个SqlSession两次查询期间手工清空了一级缓存。
    二级缓存:
    二级缓存作用域是mapper,多个SqlSession共享。
    二级缓存默认不开启,需要手动在mapper配置文件中配置<cache/>来开启。
    二级缓存失效的三种情况:
  5. 不同的mapper对应不同的二级缓存。
  6. 同一个mapper两次查询期间执行了任何一次增删改操作。
  7. 手工清空二级缓存。
    二级缓存与一级缓存同时使用时,会优先查二级缓存,若二级缓存中存在,则直接拿来用;若二级缓存中不存在,则会查一级缓存,若一级缓存存在则直接用,若一级缓存也不存在,则会发起数据库查询,并将结果添加到一级缓存和二级缓存中。

一级缓存的代码示例:

SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);
User user2 = session.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);
// 由于查询条件相同,会从一级缓存中直接获取结果,不会发起第二次数据库查询

二级缓存的代码示例:

// UserMapper.xml
<cache/>  // 开启二级缓存
// 测试代码
SqlSession session1 = sqlSessionFactory.openSession();
User user1 = session1.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);
SqlSession session2 = sqlSessionFactory.openSession();
User user2 = session2.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);
// 由于开启了二级缓存,第二次查询会从二级缓存中获取结果,不会发起数据库查询

同时使用一级缓存和二级缓存的代码示例:

// UserMapper.xml
<cache/>   // 开启二级缓存
SqlSession session1 = sqlSessionFactory.openSession();  
User user1 = session1.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);  
// 同一个session,由于一级缓存存在,直接从一级缓存获取  
User user2 = session1.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1);  
// 新开一个session,由于二级缓存存在,从二级缓存获取  
SqlSession session2 = sqlSessionFactory.openSession();  
User user3 = session2.selectOne("com.zhaocunwei.mapper.UserMapper.findById", 1); 

Springboot 使用缓存
在Spring Boot中使用Mybatis二级缓存的步骤:

  1. 在Mapper接口方法上使用@CacheNamespace注解开启二级缓存:
    @CacheNamespace(blocking = true)
    public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(Integer id);
    }
  2. 在application.yml中配置二级缓存:
    mybatis:
    configuration:
    cache-enabled: true  # 开启全局二级缓存
    mapper-locations: classpath*:mapper/*.xml
  3. 实现Cache接口并注册到Spring容器中:
    @org.springframework.context.annotation.Configuration
    public class MybatisCacheConfig {
    @Bean
    public Cache getCache() {
        return new MybatisCache();
    }
    private class MybatisCache implements Cache {
        private final Map<String, Object> cache = new ConcurrentHashMap<>();
        @Override
        public String getId() {
            return getClass().getSimpleName();
        }
        @Override
        public void putObject(Object key, Object value) {
            cache.put(key.toString(), value);
        }
        @Override
        public Object getObject(Object key) {
            return cache.get(key.toString());
        }
        @Override
        public Object removeObject(Object key) {
            return cache.remove(key.toString());
        }
        @Override
        public void clear() {
            cache.clear();
        }
        @Override
        public int getSize() {
            return cache.size(); 
        }
    }
    }
  4. 测试二级缓存:
    @SpringBootTest
    class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void testCache() {
        User user1 = userMapper.findById(1);
        User user2 = userMapper.findById(1);
        assertSame(user1, user2);  // 从二级缓存获取
    }
    }

    在Spring Boot项目中使用Mybatis时,有几点需要注意:

  5. Mapper扫描。需要使用@MapperScan注解指定Mapper接口的包,否则Spring Boot无法识别Mapper接口。
  6. 配置文件位置。Mybatis的配置文件mapper.xml的位置应在resources目录下,或使用@MapperScan指定basePackages后,该注解会自动查找该包及子包下的mapper.xml文件。
  7. 数据库配置。数据库连接信息配置在application.yml中,使用spring.datasource开头的配置项指定。
  8. PageHelper分页插件的使用。如果需要使用Mybatis的PageHelper分页插件,需要在主程序入口处添加@EnablePageHelper注解启用该插件。
  9. 配置文件优先级。application.yml > mapper.xml > 代码注解。相同的配置,以优先级高的为准。
  10. Cache缓存注解。@CacheNamespace开启Mapper级别缓存,@Cacheable等注解在方法上指定 caching 规则。需要配置mybatis.configuration.cacheEnabled=true开启全局Cache。
  11. 类型别名。使用@Alias注解配置实体类的类型别名,方便在xml和注解中使用。
  12. 映射文件位置。mappper接口名和mapper.xml文件应同名,且放在同一路径下。也可以在@MapperScan中指定mappers属性指定映射文件位置。
  13. 插件使用。想要使用第三方Mybatis插件,需要配置在mybatis-config.xml文件中。
  14. 分页插件的使用。PageHelper分页插件的使用依赖pagehelper-spring-boot-starter启动器,使用很简单,在查询方法上加@PageHelper注解即可。
mybatis的一级缓存和二级缓存

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

滚动到顶部