一、使用工具
- 后端开发工具:IntelliJ IDEA 2020.3
- 前端开发工具:Microsoft VS Code 1.50.1
- 数据库工具:Navicat Premium 15.0.20
- Redis可视化工具:RDM
二、创建Maven项目
由于项目包含用户、账户、字典等多个部分,每部分分别建立module,因此字典的外层命名为basic-dictionary,其中分为dictionary-api和dictionary-biz两个module。
——api中放字典表实体bean和vo;
——biz中放启动加载数据至redis方法和字典表增删改查并对redis进行操作的后端代码。
下图是已建立完成的目录结构,启动类DictionaryBizApplication
三、配置nacos
在dictionary-biz的resources中建立bootstrap.yml文件配置nacos的ip端口和命名空间id
spring:
profiles:
active: dev
application:
name: uip-dictionary-biz
cloud:
nacos:
config:
server-addr: ip地址:默认8848
file-extension: yaml
namespace: 命名空间id
group: 组名
涂抹部分为命名空间id
在命名空间下创建字典相关配置yaml
Data Id:uip-dictionary-biz-dev.yaml
Group:与配置文件中的组名相同
配置内容:
##端口号
server:
port: 7707
##Nacos安全隐患问题修正
nacos:
core:
auth:
enable:
userAgentAuthWhite: false
spring:
cloud:
nacos:
discovery:
server-addr: ${spring.cloud.nacos.config.server-addr}
namespace: ${spring.cloud.nacos.config.namespace}
group: ${spring.cloud.nacos.config.group}
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://数据库ip:3306/库名?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&useSSL=false
username: 用户名
password: 密码
redis:
database: 0 ##分配在redis的db0中(db0-db15)
host: redis服务器ip
port: 6379
password: 密码
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: DELETED # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 'Y' # 逻辑已删除值(默认为 1)
logic-not-delete-value: 'N' # 逻辑未删除值(默认为 0)
四、创建实体
1、创建表实体
已有数据库表uip-dictionary如下所示
在dictionary-api的entity文件夹中创建表实体
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("uip_dictionary")
@Accessors(chain = true)
public class UipDictionary extends BaseEntity<UipDictionary> {
private static final long serialVersionUID = 1L;
@TableField("name")
@ApiModelProperty(value = "字典名称")
private String name;
@TableField("sort_code")
@ApiModelProperty(value = "同级排序代码")
private String sortCode;
@TableField("value")
@ApiModelProperty(value = "字典值")
private String value;
@TableField("type_code")
@ApiModelProperty(value = "字典类型代码")
private String typeCode;
@TableField("status")
@ApiModelProperty(value = "字典状态 0-已启用,1-已禁用")
private String status;
@TableField("defaulted")
@ApiModelProperty(value = "默认标志 Y-已默认,N-未默认")
private String defaulted;
@TableField("remark")
@ApiModelProperty(value = "菜单描述")
private String remark;
}
继承的BaseEntity中将id、乐观锁等全部表共同字典提取出来。
@Data
@EqualsAndHashCode(callSuper=true)
@ApiModel
public abstract class BaseEntity<T extends Model<?>> extends Model<T> implements Serializable {
private static final long serialVersionUID = 1L;
@JsonSerialize(using= ToStringSerializer.class)
@TableId(value = "id", type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "唯一标识")
public Long id;
@Version
@ApiModelProperty(value = "乐观锁")
private Long revision;
@TableField(value = "created_by", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建人")
private String createdBy;
@TableField(value = "created_time", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private LocalDateTime createdTime;
@TableField(value = "updated_by", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新人")
private String updatedBy;
@TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private LocalDateTime updatedTime;
}
※注意:由于id字段使用的分布式id类型IdType.ASSIGN_ID,保存数据时自动生成19位纯数字,数据库字段是bigint类型,在前端获取时由于精度不同会导致最后3位数据全部是000,因此在所有id相关字段加上此注解@JsonSerialize(using= ToStringSerializer.class)
2、创建vo
在dictionary-api的vo文件夹中创建RedisDictionariesVO,此文件只用于前台查询redis数据使用
@Data
@NoArgsConstructor
public class RedisDictionariesVO implements Serializable {
//实现Serializable 否则Application启动时redis加载数据会报错,此VO无法序列化
@ApiModelProperty(value = "字典名称")
private String name;
@ApiModelProperty(value = "字典值")
private String value;
}
关于实现Serializable的问题,我在开发的过程中,如果没加这个实现会导致启动服务时报错,而其他同事开发别的redis服务时没有添加也可启动。
五、创建启动
在dictionary-biz中的component文件夹中创建InitDictionariesCacheRunner
@Component
@AllArgsConstructor
@Slf4j
public class InitDictionariesCacheRunner implements CommandLineRunner {
private final RedisTemplate redisTemplate;
private final DictionaryBizService dictionaryBizService;
@Override
public void run(String... args) throws Exception {
redisTemplate.delete(BasicConstants.DICTIONARIES_KEY);
//查询所有字典数据
List<UipDictionary> uipDictionaries = dictionaryBizService.list();
//定义字典type数组
List<String> typeCodeList = uipDictionaries.stream().map(UipDictionary::getTypeCode).collect(Collectors.toList());
//遍历type_code数组
typeCodeList.forEach(str->{
//根据type_code查询对应的name和value
List<RedisDictionariesVO> listmap = dictionaryBizService.queryByTypeCode(str);
Map<String, List<RedisDictionariesVO>> dictionariesMap = new TreeMap<>();
Optional.ofNullable(listmap).orElse(new ArrayList<>()).forEach(uipDictionary -> {
dictionariesMap.put(str, listmap);
});
redisTemplate.opsForHash().putAll(BasicConstants.DICTIONARIES_KEY, dictionariesMap);
});
}
}
BasicConstants.DICTIONARIES_KEY是自定义的内容
/**
* Redis缓存字典规则Key(Key-Value)
*/
String DICTIONARIES_KEY = "basic:dictionaries";
至此,启动Application后即可在RDM中查看是否将字典表中已有数据加载。
key:字典类型,表字段type_code
value:字典code和value的list集合。
内容仅供参考,一切请与实际开发为准。