【源码解读】Spring Boot中redis缓存如何在项目初次启动时加载
以若依开源框架为例,探究redis缓存中的数据,如何在项目启动时进行加载。
该缓存的加载涉及到两张表:sys_dict_data
(字典数据) 和 sys_dict_type
(字典类型)
- 加载字典类型
SysDictType
@Service
public class SysDictTypeServiceImpl implements ISysDictTypeService{
/**
* 项目启动时,初始化字典到缓存
*/
@PostConstruct
public void init()
{
loadingDictCache();
}
/**
* 加载字典缓存数据
*/
@Override
public void loadingDictCache()
{
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
for (SysDictType dictType : dictTypeList)
{
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
}
}
}
可以看到,它是通过注解@PostConstruct
实现的自动加载数据,带有该注解的方法会在依赖注入之后调用。
然后它调用dictTypeMapper.selectDictTypeAll()
查询到所有的SysDictType
集合。
dictTypeMapper中的SQL语句
<sql id="selectDictTypeVo">
select dict_id, dict_name, dict_type, status, create_by, create_time, remark
from sys_dict_type
</sql>
<select id="selectDictTypeAll" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
</select>
查询结果集:
接下来,它开始遍历结果集,获取dictType
属性,再去dictDataMapper
查询对应的SysDictData
。
- 加载字典数据
SysDictData
for (SysDictType dictType : dictTypeList){
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
}
dictDataMapper.selectDictDataByType 对应的SQL语句如下:
<sql id="selectDictDataVo">
select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark
from sys_dict_data
</sql>
<select id="selectDictDataByType" parameterType="SysDictData" resultMap="SysDictDataResult">
<include refid="selectDictDataVo"/>
where status = '0' and dict_type = #{dictType} order by dict_sort asc
</select>
查询结果集如下:
- 使用工具类封装数据
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
/**
* 设置字典缓存
* @param key 参数键
* @param dictDatas 字典数据列表
*/
public static void setDictCache(String key, List<SysDictData> dictDatas){
SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas);
}
/**
* 设置cache key
* @param configKey 参数键
* @return 缓存键key
*/
public static String getCacheKey(String configKey){
return Constants.SYS_DICT_KEY + configKey;
}
/**
* 字典管理 cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
在设置缓存时,通过getCacheKey(key)
方法对key进行了处理,在key的前面加上前缀 sys_dict:
这样,在redis缓存中,会把以这个前缀开头的所有key当初同一类数据。
阅读上会比较直观,比较美化。
以常用的状态字典sys_normal_disable
为例,看下redis中的数据结构
SQL结果集如下:
redis中的数据结构如下:
[
{
"@type": "com.ruoyi.system.api.domain.SysDictData",
"createBy": "admin",
"createTime": 1632793600000,
"cssClass": "",
"default": true,
"dictCode": 6,
"dictLabel": "正常",
"dictSort": 1,
"dictType": "sys_normal_disable",
"dictValue": "0",
"isDefault": "Y",
"listClass": "primary",
"params": {
"@type": "java.util.HashMap"
},
"remark": "正常状态",
"status": "0"
},
{
"@type": "com.ruoyi.system.api.domain.SysDictData",
"createBy": "admin",
"createTime": 1632793600000,
"cssClass": "",
"default": false,
"dictCode": 7,
"dictLabel": "停用",
"dictSort": 2,
"dictType": "sys_normal_disable",
"dictValue": "1",
"isDefault": "N",
"listClass": "danger",
"params": {
"@type": "java.util.HashMap"
},
"remark": "停用状态",
"status": "0"
}
]
常用的属性是dictLabel
,dictValue
和listClass
。
dictLabel 前台显示字段
dictValue 后台存储字段
listClass 前台的字段样式