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

前言

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

正文

数据字典

数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序元数据的目录。主动数据字典是指在对数据库或应用程序结构进行修改时,其内容可以由DBMS自动更新的数据字典。被动数据字典是指修改时必须手工更新其内容的数据字典。
 我们通常会结合数据库来实现数据字典,但事实上数据字典经常会被使用到,如果频繁地去访问数据库,将会对数据库造成性能压力,事实上我们经常会采用Redis对数据字典进行缓存来提升系统性能。

使用Redis的优势:

1.绝大数的请求操作都是纯粹的内存操作。
2.采用了单线模式,避免了不必要的上下文切换和竞争条件这里的单线程指的是网络请求模块只使用了一个线程(所以不必考虑并发安全性),即一个请求处理所有网络请求,其他模块仍使用了多个线程。
3.采用了动态字符串(SDS),对于字符串会预留一定的空间,避免了字符串在做拼接和截取引起内存重新分配导致性能的损耗。

SpringBoot+Redis实现数据字典

依赖

<!--redis-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
 <groupId>redis.clients</groupId>
 <artifactId>jedis</artifactId>
 <version>2.9.0</version>
</dependency>
<!--lombok-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <optional>true</optional>
</dependency>

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<String, Object> stringSerializerRedisTemplate() {
    RedisSerializer<String> 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> T getBean(Class<T> clazz){
    return getApplicationContext().getBean(clazz);
  }

  //通过name,以及Clazz返回指定的Bean
  public static <T> T getBean(String name,Class<T> 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<SysDictPojo> 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 id="getall" resultType="com.luo.dao.entity.SysDictPojo">
 select
 t1.name,
 t1.value,
 t2.value typeCodeValue
 from SYS_DICT t1
 left join SYS_DICT_TYPE t2 on t2.code =t1.type_code
</select>

验证

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查询用户信息:

到此这篇关于SpringBoot+Redis实现数据字典的方法的文章就介绍到这了,更多相关SpringBoot+Redis数据字典内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot中实现数据字典的示例代码

    我们在日常的项目开发中,对于数据字典肯定不模糊,它帮助了我们更加方便快捷地进行开发,下面一起来看看在 SpringBoot 中如何实现数据字典功能的 一.简介 1.定义 数据字典是指对数据的数据项.数据结构.数据流.数据存储.处理逻辑等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明,使用数据字典为简单的建模项目.简而言之,数据字典是描述数据的信息集合,是对系统中使用的所有数据元素的定义的集合. 数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序元数

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

    前言 我们在日常的开发过程中针对一些字段采用整型的方式去代替某些具体的含义,比如性别0代表男,1代表女.如果只是一些不会变更的转译我们可以采用常量或者枚举类的方式来实现,但是事实上我们也会遇到那种可能需要变更的,显然这种场景下使用枚举类这种方式是不合理的,那么如何动态地去进行转译呢? 正文 数据字典 数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序元数据的目录.主动数据字典是指在对数据库或应用程序结构进行修改时,其内容可以由DBMS自动更新的数据字典.被动数据字

  • SpringBoot使用Redis缓存的实现方法

    (1)pom.xml引入jar包,如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> (2)修改项目启动类,增加注解@EnableCaching,开启缓存功能,如下: package springboot; import org

  • SpringBoot+redis配置及测试的方法

    1.创建项目时选择redis依赖 2.修改配置文件,使用SpringBoot就避免了之前很多的xml文件 2.1学过redis的同学都知道这个东西有集群版也有单机版,无论哪个版本配置起来都很简单 2.1.1首先找到配置文件 2.1.2然后配置集群版,直接在配置文件内编辑即可 2.1.3配置单机版 3.测试 找到测试文件夹,自动注入redis模板 4.分别测试操作String和Hash类型的数据 4.1操作String @Test public void testString(){ //操作Str

  • Springboot Redis设置key前缀的方法步骤

    properties中配置 #redis redis.masterClusterNodes=10.40.57.197:7000;10.40.57.198:7002;10.40.57.199:7004 redis.slaveClusterNodes=10.40.57.197:7001;10.40.57.198:7003;10.40.57.199:7005 redis.maxTotal=50 redis.maxIdle=10 redis.minIdle=1 redis.maxWaitMillis=1

  • SpringBoot 开启Redis缓存及使用方法

    目录 Redis缓存 主要步骤 具体实践 整体目录结构 yml文件里配置Redis集群 设置序列化的Bean 编写业务Controller 关于缓存的其他注解 检验结果 之前不是说过Redis可以当作缓存用嘛 现在我们就配置一下SpringBoot使用Redis的缓存 Redis缓存 为什么用Redis作缓存 用redis做缓存,是因为redis有着很优秀的读写能力,在集群下可以保证数据的高可用 主要步骤 1.pom.xml文件添加依赖 2.yml文件配置redis集群 3.编写RedisCon

  • SpringBoot+Redis+Lua防止IP重复防刷攻击的方法

    黑客或者一些恶意的用户为了攻击你的网站或者APP.通过肉机并发或者死循环请求你的接口.从而导致系统出现宕机. 针对新增数据的接口,会出现大量的重复数据,甚至垃圾数据会将你的数据库和CPU或者内存磁盘耗尽,直到数据库撑爆为止. 针对查询的接口.黑客一般是重点攻击慢查询,比如一个SQL是2S.只要黑客一致攻击,就必然造成系统被拖垮,数据库查询全都被阻塞,连接一直得不到释放造成数据库无法访问. 具体要实现和达到的效果是: 需求:在10秒内,同一IP 127.0.0.1 地址只允许访问30次. 最终达到

  • SpringBoot使用Redis缓存MySql的方法步骤

    目录 1项目组成 2运行springboot 2.1官网download最基本的restful应用 2.2运行应用 3访问mysql 4设置redis缓存 1 项目组成 应用:springboot rest api 数据库:mysql jdbc框架:jpa 缓存中间件:redis 2 运行springboot 2.1 官网download最基本的restful应用 教程地址:https://spring.io/guides/gs/rest-service/ 直接download成品,找到git命

  • SpringBoot结合Redis实现序列化的方法详解

    目录 前言 配置类 配置 Jackson2JsonRedisSerializer 序列化策略 配置  RedisTemplate 配置缓存策略 测试代码 完整代码 前言 最近在学习Spring Boot结合Redis时看了一些网上的教程,发现这些教程要么比较老,要么不知道从哪抄得,运行起来有问题.这里分享一下我最新学到的写法 默认情况下,Spring 为我们提供了一个 RedisTemplate 来进行对 Redis 的操作,但是 RedisTemplate 默认配置的是使用Java本机序列化.

  • 基于springboot实现redis分布式锁的方法

    在公司的项目中用到了分布式锁,但只会用却不明白其中的规则 所以写一篇文章来记录 使用场景:交易服务,使用redis分布式锁,防止重复提交订单,出现超卖问题 分布式锁的实现方式 基于数据库乐观锁/悲观锁 Redis分布式锁(本文) Zookeeper分布式锁 redis是如何实现加锁的? 在redis中,有一条命令,实现锁 SETNX key value 该命令的作用是将 key 的值设为 value ,当且仅当 key 不存在.若给定的 key 已经存在,则 SETNX不做任何动作.设置成功,返

随机推荐