SpringBoot+Redis实现数据字典的方法

网友投稿 453 2022-11-17


SpringBoot+Redis实现数据字典的方法

前言

我们在日常的开发过程中针对一些字段采用整型的方式去代替某些具体的含义,比如性别0代表男,1代表女。如果只是一些不会变更的转译我们可以采用常量或者枚举类的方式来实现,但是事实上我们也会遇到那种可能需要变更的,显然这种场景下使用枚举类这种方式是不合理的,那么如何动态地去进行转译呢?

正文

数据字典

数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序元数据的目录。主动数据字典是指在对数据库或应用程序结构进行修改时,其内容可以由DBMS自动更新的数据字典。被动数据字典是指修改时必须手工更新其内容的数据字典。

 我们通常会结合数据库来实现数据字典,但事实上数据字典经常会被使用到,如果频繁地去访问数据库,将会对数据库造成性能压力,事实上我们经常会采用Redis对数据字典进行缓存来提升系统性能。

使用Redis的优势:

1.绝大数的请求操作都是纯粹的内存操作。

2.采用了单线模式,避免了不必要的上下文切换和竞争条件这里的单线程指的是网络请求模块只使用了一个线程(所以不必考虑并发安全性),即一个请求处理所有网络请求,其他模块仍使用了多个线程。

3.采用了动态字符串(SDS),对于字符串会预留一定的空间,避免了字符串在做拼接和截取引起内存重新分配导致性能的损耗。

SpringBoot+Redis实现数据字典

依赖

org.springframework.boot

spring-boot-starter-data-redis

redis.clients

jedis

2.9.0

org.projectlombok

lombok

1.18.2

true

application.properties:配置类

#redis

spring.redis.host=127.0.0.1

spring.redis.port=6379

字典表:SYS_DICT

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for SYS_DICT

-- ----------------------------

DROP TABLE IF EXISTS `SYS_DICT`;

CREATE TABLE `SYS_DICT` (

`code` varchar(36) NOT NULL COMMENT '主键',

`type_code` varchar(36) DEFAULT NULL COMMENT '类型code',

`name` varchar(50) DEFAULT NULL COMMENT '展示值',

`value` int(20) DEFAULT NULL COMMENT '使用值',

`fixed` int(2) DEFAULT NULL COMMENT 'default 0不固定,固定的话用1',

`creater` varchar(20) DEFAULT NULL COMMENT '新建人',

`create_time` datetime DEFAULT NULL COMMENT '新建时间',

`updater` varchar(20) DEFAULT NULL COMMENT '编辑人',

`update_time` datetime DEFAULT NULL COMMENT '编辑时间',

PRIMARY KEY (`code`),

KEY `sys_type` (`type_code`),

CONSTRAINT `sys_type` FOREIGN KEY (`type_code`) REFERENCES `SYS_DICT_TYPE` (`code`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of SYS_DICT

-- ----------------------------

INSERT INTO `SYS_DICT` VALUES ('182d4db6-aa50-11ea-aa1b-00163e08c9ed', '9ed92c7e-aa4f-11ea-aa1b-00163e08c9ed', '男', '0', '1', null, null, null, null);

INSERT INTO `SYS_DICT` VALUES ('222cf983-aa50-11ea-aa1b-00163e08c9ed', '9ed92c7e-aa4f-11ea-aa1b-00163e08c9ed', '女', '1', '1', null, null, null, null);

字典类型表SYS_DICT_TYPE

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for SYS_DICT_TYPE

-- ----------------------------

DROP TABLE IF EXISTS `SYS_DICT_TYPE`;

CREATE TABLE `SYS_DICT_TYPE` (

`code` varchar(36) NOT NULL,

`name` varchar(50) DEFAULT NULL COMMENT '用于展示',

`value` varchar(50) DEFAULT NULL COMMENT '用于前段(建立唯一索引)',

`creater` varchar(20) DEFAULT NULL COMMENT '新建人',

`create_time` datetime DEFAULT NULL COMMENT '新建时间',

`updater` varchar(20) DEFAULT NULL COMMENT '编辑人',

`updater_time` datetime DEFAULT NULL COMMENT '编辑时间',

PRIMARY KEY (`code`),

UNIQUE KEY `key_value` (`value`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of SYS_DICT_TYPE

-- ----------------------------

INSERT INTO `SYS_DICT_TYPE` VALUES ('9ed92c7e-aa4f-11ea-aa1b-00163e08c9ed', '性别', 'sex', null, null, null, null);

RedisConfigurtion:Redis配置类,解决Redis数据同步时字符串格式问题

@Configuration

public class RedisConfigurtion {

@Autowired

private RedisTemplate redisTemplate;

@Bean

public RedisTemplate stringSerializerRedisTemplate() {

RedisSerializer stringSerializer = new StringRedisSerializer();

redisTemplate.setKeySerializer(stringSerializer);

redisTemplate.setValueSerializer(stringSerializer);

redisTemplate.setHashKeySerializer(stringSerializer);

redisTemplate.setHashValueSerializer(stringSerializer);

return redisTemplate;

}

}

SpringUtil:用于加载Spring容器

@Component

public class SpringUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext = null;

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

if(SpringUtil.applicationContext == null){

SpringUtil.applicationContext = applicationContext;

}

}

//获取applicationContext

public static ApplicationContext getApplicationContext() {

return applicationContext;

}

//通过name获取 Bean.

public static Object getBean(String name){

return getApplicationContext().getBean(name);

}

//通过class获取Bean.

public static T getBean(Class clazz){

return getApplicationContext().getBean(clazz);

}

//通过name,以及Clazz返回指定的Bean

public static T getBean(String name,Class clazz){

return getApplicationContext().getBean(name, clazz);

}

}

RedisDistUtil:Spring容器不允许普通Pojo调用Service,所以采用以下方式手动通过Spring容器去加载Bean.

public class RedisDistUtil {

private static ApplicationContext context;

/**

* 转化码值

* @param distname

* @param value

* @return

* @throws Exception

*/

public static String transformStr(String distname, int value) {

ApplicationContext context = SpringUtil.getApplicationContext();

ISysDictService iSysDictService =context.getBean(ISysDictService.class);

return iSysDictService.transformStr(distname,value);

}

}

SysDictService

transformStr:从Redis中获取字典值。

refreshCache:用于将数据库数据字典表数据同步到Redis中。

@Transactional

@Service

@Slf4j

public class SysDictService implements ISysDictService {

@Autowired

SysDictPojoMapper sysDictPojoMapper;

@Autowired

RedisTemplate redisTemplate;

/**

* 转化码值

*

* @param distname

* @param value

* @return

* @throws Exception

*/

@Override

public String transformStr(String distname, int value) {

return redisTemplate.opsForValue().get(distname + "_" + value) != null ?

redisTemplate.opsForValue().get(distname + "_" + value).toString() : String.valueOf(value);

}

/**

* 刷新缓存

*/

@Override

public void refreshCache() {

log.info("start 刷新码表缓存");

List sysDictPojoList = sysDictPojoMapper.getall();

long startTime = System.currentTimeMillis();

for (SysDictPojo sysDictPojo : sysDictPojoList) {

redisTemplate.opsForValue().set(sysDictPojo.getTypeCodeValue() + "_" + sysDictPojo.getValue(), sysDictPojo.getName());

}

long endTime = System.currentTimeMillis();

log.info("end 刷新码表缓存,总计:" + sysDictPojoList.size() + "条,用时:" + (endTime - startTime) + "毫秒");

}

}

SysDictPojo:数据字典的实体类

@Setter

@Getter

@ToString

public class SysDictPojo implements Serializable {

private static final long serialVersionUID = 7845051152365224116L;

private String code;

private String typeCode;

private String typeCodeValue;

private String name;

private Integer value;

private Integer fixed;

private String creater;

private Date createTime;

private String updater;

private Date updateTime;

}

getall:查询数据库的所有数据字典值

select

t1.name,

t1.value,

t2.value typeCodeValue

from SYS_DICT t1

left join SYS_DICT_TYPE t2 on t2.code =t1.type_code

验证

UserPojoRes :在get方法里进行数据字典值的替换

@Setter

@Getter

@ToString

public class UserPojoRes implements Serializable {

private static final long serialVersionUID = -2145503717390503506L;

/**

* 主键

*/

private String id;

/**

* 姓名

*/

private String name;

/**

* 性别

*/

private int sex;

/**

* 性别展示

*/

private String sexStr;

/**

* 消息

*/

private String msg;

public String getSexStr() {

return RedisDistUtils.transformStr("sex",this.sex);

}

}

访问模拟接口,根据id查询用户信息:


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot中EasyExcel实现Excel文件的导入导出
下一篇:Spring Security 安全认证的示例代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~