手敲Mybatis(16章)-一级缓存功能实现

1.实现目的

这一节的目的主要是实现SqlSession级别的缓存,也就是一级缓存,首先看下图一,用户可以通过设置来进行是否开启一级缓存,不设置的化默认开启一级缓存,localCacheScope=SESSION为要设置一级缓存,localCacheScope=STATEMENT为不要设置一级缓存,(所以后面在清理缓存时会进行判断,如果是STATEMENT就删除缓存)。

2.简单说明

然后我们就需要解析下缓存设置,拿到缓存级别,执行Sql语句前,将按Mybatis的规定处理缓存key(id,参数,Sql语句,环境等等,生成对应hash值),然后判断缓存中是否有当前key的结果数据,有的化结果数据直接返回,没有的话就去执行数据库查询,然后将查询的结果存储到一级缓存Map中,然后判断缓存级别是否是STATEMENT,是的话代表不进行缓存操作,那此时删除,下次进来还是继续查询库,不是的话就不删除,留着继续执行同一SqlSession会话使用。

其实不算难,还是很简单,也很有调理,这就是设计的魅力,把每个类与属性现实化,那对应需要改动哪里,就都很清晰。

3.XML图

XML类图就是对应上面所说的逻辑的实现。

1.XMLConfigBuilder里专门解析设置操作,Configuration则是缓存级别的存储,此时需要用到LocalCacheScope枚举类,

2.Executor类里query方法添加一个参数缓存Key参数(CacheKey),然后在BaseExecutor里用没有缓存key参数的quey方法来获取缓存key的操作(这里获取就是生成,将对应需要的参数传到CacheKey类里处理Hash),得到后调用有缓存Key参数的query方法,这时此方法根据当前key去缓存查询是否有数据,有的话缓存拿出,没有执行queryFromDatabase方法,从数据库获取,获取完毕存储缓存里(存储Cache接口PerpetualCache类的map里)

4.代码实现 

4.1 解析缓存设置

XMLConfigBuilder:解析配置XML构建器,这里需要添加私有方法settingsElement,主要解析缓存设置,解析完毕将缓存级别存储到configuration的LocalCacheScope枚举类下。

public class XMLConfigBuilder extends BaseBuilder {

   // 省略其他方法
   
    public Configuration parse() {
       // STEP-17 添加设置
       settingsElement(root.element("settings"));
    }

   /**
     * 解析配置在 XML 文件中的缓存机制。并把解析出来的内容存放到 Configuration 配置项中。
     * <settings>
     * <!--缓存级别:SESSION/STATEMENT-->
     * <setting name="localCacheScope" value="SESSION"/>
     * </settings>
     */
    private void settingsElement(Element context) {
        if (context == null) return;
        List<Element> elements = context.elements();
        Properties props = new Properties();
        for (Element element : elements) {
            props.setProperty(element.attributeValue("name"), element.attributeValue("value"));
        }
        // 设置缓存级别
        configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope")));
    }
}

Configuration:Configuration类里就针对缓存级别进行赋值操作。

public class Configuration {
     // 缓存机制,默认不配置的情况是 SESSION
    protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;

    public LocalCacheScope getLocalCacheScope() {
        return localCacheScope;
    }

    public void setLocalCacheScope(LocalCacheScope localCacheScope) {
        this.localCacheScope = localCacheScope;
    }
}

LocalCacheScope:缓存级别枚举,

/**
 * @Author df
 * @Description: 本地缓存机制;
 * SESSION 默认值,缓存一个会话中执行的所有查询
 * STATEMENT 不支持使用一级缓存,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不做数据共享
 * @Date 2024/1/9 10:10
 */
// step 17添加
public enum LocalCacheScope {
    SESSION,
    STATEMENT
}

4.2 执行器缓存处理

Executor:

1.Executor类的修改是关于query方法时新添加缓存Key(CacheKey)操作,

2.添加了清除一级缓存方法定义以及创建缓存Key的方法定义

然后在BaseExecutor执行query时执行缓存存储,并根据参数生成缓存key,调用createCacheKey方法,增删改时删除缓存操作调用clearLocalCache方法。

public interface Executor {
   // step-17 添加CacheKey参数
   <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql bo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值