因数据库中存的都是数字(数据字典),但是又没有数据字典表,只有后端知道是什么意思,查询返回给前端时,需要if-else进行转换成具体的值,很麻烦,现增加数据字典表,通过redis获取,转换成具体的值
1.建表
create table `data_dictionary` ( `id` bigint(20) not null comment '主键id', `module` varchar(255) character set utf8 collate utf8_general_ci not null default '' comment '归属模块', `name` varchar(255) character set utf8 collate utf8_general_ci not null default '' comment '字典名', `code` varchar(255) character set utf8 collate utf8_general_ci not null default '' comment '字典编码', `value` varchar(255) character set utf8 collate utf8_general_ci not null default '' comment '字典取值', `order` int(3) not null default -1 comment '排序', `state` tinyint(1) not null default -1 comment '启用状态 0:停用 1:启用', `create_time` datetime(0) null default null comment '创建时间', primary key (`id`) )engine = innodb character set = utf8 collate = utf8_general_ci comment = '数据字典表';
2.mybatisplus生成controller,service,mapper,do等
下面是用到的do,vo
@data
@tablename("data_dictionary")
@apimodel(value="datadictionarydo对象", description="数据字典表")
public class datadictionarydo implements serializable {
private static final long serialversionuid = 1l;
@apimodelproperty(value = "主键id")
@tableid(value = "id", type = idtype.assign_id)
private long id;
@apimodelproperty(value = "归属模块")
private string module;
@apimodelproperty(value = "字典名")
private string name;
@apimodelproperty(value = "字典编码")
private string code;
@apimodelproperty(value = "字典取值")
private string value;
@apimodelproperty(value = "排序")
private integer sort;
@apimodelproperty(value = "启用状态 0:停用 1:启用")
private integer state;
@apimodelproperty(value = "创建时间")
@tablefield(value = "create_time", fill = fieldfill.insert)
private date createtime;
}
@data
@apimodel(value = "datedictionaryvo对象", description = "数据字典vo")
@tostring
public class datadictionaryvo implements serializable {
private static final long serialversionuid = 1l;
@apimodelproperty(value = "字典编码")
private string code;
@apimodelproperty(value = "字典取值")
private string value;
@apimodelproperty(value = "redis key")
private string key;
}
3.数据字典常量
/**
* @description:数据字典常量
*/
public class datadictionaryconstant {
/**
* redis中数据字典key
*/
public static final string data_dictionary_key = "datadictionary";
/**
* 合同-执行状态
*/
public static final string contract_status = "contract:status";
}
4.redis配置
@configuration
public class redisconfig {
@bean
public redistemplate<string, object> redistemplate(redisconnectionfactory connectionfactory) {
// 创建redistemplate对象
redistemplate<string, object> template = new redistemplate<>();
// 设置连接工厂
template.setconnectionfactory(connectionfactory);
// 创建json序列化工具
genericjackson2jsonredisserializer jsonredisserializer = new genericjackson2jsonredisserializer();
// 设置key的序列化
template.setkeyserializer(redisserializer.string());
template.sethashkeyserializer(redisserializer.string());
// 设置value的序列化
template.setvalueserializer(jsonredisserializer);
template.sethashvalueserializer(jsonredisserializer);
// 返回
return template;
}
}
5.实现springboot启动查询数据字典表
将数据缓存到redis中,使用@postconstruct注解
/**
* @description:项目启动初始化数据字典到redis
*/
@slf4j
@component
public class initconfig {
@autowired
private datadictionarymapper datadictionarymapper;
@autowired
redistemplate<string, object> redistemplate;
@postconstruct
public void initdatadictionary() {
log.info("初始数据字典信息-开始");
if (boolean.true.equals(redistemplate.haskey(data_dictionary_key))) {
redistemplate.delete(data_dictionary_key);
}
list<datadictionarydo> dictionarydolist = datadictionarymapper.selectlist(null);
map<string, list<datadictionaryvo>> datamap = dictionarydolist.stream().map(obj -> {
datadictionaryvo datadictionaryvo = new datadictionaryvo();
datadictionaryvo.setcode(obj.getcode());
datadictionaryvo.setvalue(obj.getvalue());
datadictionaryvo.setkey(obj.getmodule() + ":" + obj.getname());
return datadictionaryvo;
}).collect(collectors.groupingby(datadictionaryvo::getkey));
redistemplate.opsforhash().putall(data_dictionary_key, datamap);
log.info("初始数据字典信息-结束");
}
}
6.往表中插入几条数据
再启动项目,看效果


7.redis中查看
可以看到redis在序列化对象时,把类信息(@class)也序列化进来了,这样存的作用是反序列化时知道反序列化成什么对象,但是浪费了内存空间;不想存类信息的话,需要手动序列化成字符串再存进来,获取时再手动反序列成对象,看你怎么选择了

8.将获取封装成一个工具方法
方便调用
@service
public class redisservice {
@autowired
private redistemplate redistemplate;
/**
* 缓存中查数据字典
* @param key redis key
* @param code 字典编码
* @return
*/
public string getdatadictionary(string key, string code) {
string value = null;
if (boolean.true.equals(redistemplate.haskey(data_dictionary_key))) {
list<datadictionaryvo> datadictionary = (list<datadictionaryvo>) redistemplate
.opsforhash().get(data_dictionary_key, key);
if (datadictionary.size() > 0) {
value = datadictionary.stream().filter(obj -> code.equals(obj.getcode()))
.findfirst().get().getvalue();
}
}
return value != null ? value : "";
}
}
为什么要这么写
boolean.true.equals(redistemplate.haskey(key))
而不是
redistemplate.haskey(data_dictionary_key)
这是因为idea提示可能会出现空指针,然后查资料修改成上面的写法:https://www.jb51.net/program/36014522y.htm

9.使用
//使用 string value = redisservice.getdatadictionary(contract_status, "0"); system.out.println(value);
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论