Mybatis一级缓存源码整理

  1. 使用一级缓存
    @Service
    public class UserService extends ServiceImpl<UserMapper, UserEntity>{
        @Autowired
        private UserMapper userMapper ;
    
        //1. 这里添加@Transactional 注解
        @Transactional(rollbackFor = Exception.class)
        public List<UserEntity> listUser(UserEntity entity){
            LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>(entity) ;
            //2. 首次查询
            List<UserEntity> list = baseMapper.selectList(wrapper);
            //3. 再次查询, 这一会一级缓存
            list = baseMapper.selectList(wrapper);
            return list ;
        }
    }
    
  2. 关闭一级缓存
    mybatis-plus.configuration.local-cache-scope=statement
    
  3. 一级缓存生效两个条件, 1. 添加事务注解,2. 事务方法重再次同样的查询
缓存原理
  1. 添加@Transactional注解主要是为了保证两次查询使用同一个SqlSession对象
    private class SqlSessionInterceptor implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
                    SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
            try {
                Object result = method.invoke(sqlSession, args);
                if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
                    sqlSession.commit(true);
                }
                return result;
            } finally {
                if (sqlSession != null) {
                    closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
                }
            }
        }
    }
    
  2. DefaultSqlSessionFactory#openSessionFromDataSource中新创建Executor: SimpleExecutor 继承 BaseExecutor
    public class DefaultSqlSessionFactory{
       private SqlSession openSessionFromDataSource(
               ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
           final Environment environment = configuration.getEnvironment();
           final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
           Transaction tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
           final Executor executor = configuration.newExecutor(tx, execType);
           return new DefaultSqlSession(configuration, executor, autoCommit);
       }
    }
    
  3. BaseExecutor构造函数初始化一级缓存对象 localCache:PerpetualCache
  4. BaseExecutor#query 方法中业务逻辑
    public class BaseExecutor{
       public <E> List<E> query(
               MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
               CacheKey key, BoundSql boundSql) throws SQLException {
          // 1. 从localCache缓存中获取数据
          List<E> list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
          if (list == null) {
             // 2. 如果缓存数据不存在则从数据库查询数据 
             list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
          } 
          // 3. 当local-cache-scope配置为statement时,清空localCache中缓存
          if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
             // issue #482
             clearLocalCache();
          }
          return list;
       }
    }
    
  5. BaseExecutor#queryFromDatabase 方法中业务逻辑
    public class BaseExecutor{
        private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds,
             ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
           // 1. 从数据库中查询数据
           List<E> list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
           // 2. 将查询到的数据放入localCache缓存中
           localCache.putObject(key, list);
           return list;
         }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值