Mysql json类型字段Java+Mybatis数据字典功能的实践方式

作者:keep丶 时间:2024-01-22 00:24:34 

前言

JSON类型是MySQL5.7.8中新加入的一种数据类型,并在后续版本尤其是MySQL8.0中得到了大幅增强,现在的JSON类型的功能十分强大,合理使用能让我们的开发更加有效!        

但本文不准备花篇幅来介绍MySQL的JSON类型字段的相关API,因为官方文档里面写得已经十分详细了,大家如果对MySQL的JSON类型还不怎么了解的话可以看看官方文档:

  • MySQL5.7 JSON功能介绍:https://dev.mysql.com/doc/refman/5.7/en/mysql-nutshell.html  (搜 JSON support)

  • MySQL8.0 JSON增强说明:https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html  (搜 JSON enhanc)

  • MySQL8.0 JSON功能介绍:https://dev.mysql.com/doc/refman/8.0/en/json.html

(ps:英语相对较差的小伙伴可以用chrome浏览器打开,然后用自带的翻译工具翻译后看哦~)

应用场景介绍

JSON的应用场景还是挺多的,我能想到的两个是:

数据字典

  • 基本上所有系统都会有数据字典,比如各种下拉框的内容,这种数据如果需要支持让用户自定义,那么基本上就是使用数据字典,而字典内容则是标准的JSON对象,用JSON保存再好不过!

动态表单

  • 如一些信息收集的表单,需要提供用户自定义信息时,这些信息也是JSON对象,也可以通过JSON字段保存。

数据字典案例实践

  • 本文将针对数据字典使用JSON类型案例进行详细介绍,本文中使用的ORM框架是Mybatis,其他ORM框架应该也大同小异。如果其他框架使用出现问题,可以留言一起讨论哦~

  • 本文中还是用了Swagger、Mybatis Plus、Lombok等工具,如果这些还不熟悉的可以先去做做功课哦,这些都是开发中非常强大而给力的工具,让我们编码时如虎添翼,效率翻倍~

功能方面需要明确的是:

枚举选项是严禁直接删除的。

  • 字典内容只能增加不能减少,因为一旦删除一个选项,会导致拥有这个选项的数据无法找到对应枚举,导致显示异常。

  • 当然,如果非要有删除功能,我们也能像表数据那样增加一个逻辑删除功能。

枚举选项的键是严禁修改的。

  • 这个就不用过多解释了,键就相当于表的ID一样,肯定是不允许修改的,用于展示的值可修改。

可以增加一些辅助功能。

  • 可以对选项增加一个排序功能,让客户能自定义排序。

  • 可以增加创建修改信息字段,记录选项改动信息。

表结构

CREATE TABLE `sys_dict` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `code` varchar(30) NOT NULL COMMENT '编码',
 `name` varchar(40) NOT NULL COMMENT '展示名称',
 `content` json NOT NULL COMMENT '内容',
 /* 下面六个字段根据需要增加 */
 `description` varchar(200) DEFAULT NULL COMMENT '描述',
 `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 [0未删除 1已删除]',
 `create_by` int(11) DEFAULT NULL COMMENT '创建人',
 `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 `update_by` int(11) DEFAULT NULL COMMENT '修改人',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统字典表';

实体类

@Getter
@Setter
@TableName(value = "sys_dict", autoResultMap = true)
@ApiModel("系统字典实体类")
public class SysDict extends BaseDO {
@TableId(type = IdType.AUTO) //id自增
   private Integer id;
@ApiModelProperty("编码")
   private String code;
@ApiModelProperty("名称")
   private String name;
@TableField(typeHandler = JacksonTypeHandler.class)
   @ApiModelProperty("内容列表")
   private List<DictContent> content;
@Getter
   @Setter
   @NoArgsConstructor
   @ApiModel("系统字典内容实体类")
   public static class DictContent {
@ApiModelProperty("键")
       private Integer key;
@ApiModelProperty("值")
       private String value;
@ApiModelProperty("排序,数字越小越前面")
       private Integer order;
@ApiModelProperty("是否删除 [0:未删除 1:已删除]")
   private Integer deleted;
//辅助字段根据需求来定,有必要的情况下可以继承BaseDO,增加那6个字段!
   }
}
@Getter
@Setter
public abstract class BaseDO implements Serializable {
@ApiModelProperty("备注")
   private String description;
@ApiModelProperty("是否删除 [0:未删除 1:已删除]")
   private Integer deleted;
@ApiModelProperty("创建人")
   private Integer createBy;
//JSONFormat是格式化时间的输入输出格式
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
   @ApiModelProperty("创建时间")
   private LocalDateTime createTime;
@ApiModelProperty("修改人")
   private Integer updateBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
   @ApiModelProperty("修改时间")
   private LocalDateTime updateTime;
}

这里为了方便,将创建修改信息等6个字段抽象出来了,以后创建实体类就直接继承该类就行,同时该类声明了序列化,所以其子类也不需要再单独实现Serializable接口,一举多得~ 

这里有两个个细节:

  • 将BaseDO类声明成抽象类:如果不声明成抽象类的话,在丝袜哥(Swagger)接口文档中就只会显示父类BaseDO的信息,不会显示其子类信息。(我之前就是没有声明成抽象类,出现了这个问题,纠结了一阵。。。)

  • 将内部类DictContent用static修饰:如果用static修饰的话,其他地方就无法直接使用该类的构造方法;在查询数据时,Mybatis就无法实例化该对象,会报错的哦。

关系映射

通过Mybatis Plus注解实现

上文中的@TableName和@TableField是Mybatis Plus提供的注解,@TableName的autoResultMap属性一般与content字段的@TableField的typeHandler属性一起使用,表示会自动创建resultMap处理查询返回值,但这个操作仅限于Mybatis Plus提供的查询方法,自定义方法不会自动创建。

通过ResultMap实现

需要注意的是:如果你在对应的Mapper文件中自定义了类型为这个实体类的ResultMap的话,上述操作也不会执行。也就是说如果需要自定义ResultMap,则需要手动增加typeHandler属性:

没有使用Mybatis Plus的小伙伴也是通过下述这种方式进行类型转换~~ 

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.copm.ifm.servers.insp.entity.SysDict">
   <id column="id" property="id" />
   <result column="code" property="code" />
   <result column="name" property="name" />
   <!-- 这里显示指定typeHandler属性值 -->
   <result column="content" property="content"
   jdbcType="JAVA_OBJECT" javaType="java.util.List"
           typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
   <result column="description" property="description" />
   <result column="deleted" property="deleted" />
   <result column="create_by" property="createBy" />
   <result column="create_time" property="createTime" />
   <result column="update_by" property="updateBy" />
   <result column="update_time" property="updateTime" />
</resultMap>

上述代码中使用的jdbcType="JAVA_OBJECT"中,jdbcType的取值范围来源于org.apache.ibatis.type.JdbcType枚举。

content的javaType不要写成了SysDict#DictContent 哦!他的java类型是List,DictContent是List的泛型。

只要存在type=“com.copm.ifm.servers.insp.entity.SysDict” 的resultMap,就会使Mybatis Plus的 @TableName(autoResultMap = true) 失效。

泛型擦除问题解决(7.21新增)

昨天在实际应用过程中遇到了泛型擦除问题,如下图,content字段List的泛型明明是DictContent,但是其实际泛型却是LinkedHashMap!所以在后面的遍历时报类型转换失败的错,这就是典型的泛型擦除问题!

详细解决方案请看:>>泛型擦除问题解决传送门<< 

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

解决方案1:

自定义一个指定泛型的集合类替代List<T>即可。

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

8.11新增:解决方案2:

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

效果展示

本文通过swagger文档添加操作进行效果展示

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

Mysql json类型字段Java+Mybatis数据字典功能的实践方式

来源:https://blog.csdn.net/qq_38688267/article/details/107386138

标签:Mysql,Java,Mybatis,数据字典
0
投稿

猜你喜欢

  • python中的一些类型转换函数小结

    2021-11-01 10:42:11
  • pycharm无法安装cv2模块问题及解决方案

    2023-02-14 21:20:49
  • vscode写python时的代码错误提醒和自动格式化的方法

    2023-02-25 12:54:59
  • Python中return用法案例详解

    2022-09-09 10:35:40
  • python机器学习之神经网络(二)

    2021-12-21 08:41:54
  • 关于Python中*args和**kwargs的深入理解

    2021-04-07 17:45:06
  • python迭代器实例简析

    2023-07-26 07:40:29
  • 古老的问题:清除浮动

    2009-02-12 11:21:00
  • 详解Python并发编程之创建多线程的几种方法

    2023-03-31 19:34:37
  • Golang中基于HTTP协议的网络服务

    2024-05-21 10:23:55
  • 对PyQt5中树结构的实现方法详解

    2021-02-07 16:19:20
  • python3使用matplotlib绘制条形图

    2022-06-06 16:31:17
  • Java正则表达式的基本用法和实例大全

    2023-04-14 06:17:22
  • Python类中__init__() 和self的详细解析

    2021-04-22 22:05:06
  • 关于python通过新建环境安装tfx的问题

    2022-06-28 19:47:21
  • Python 变量类型及命名规则介绍

    2022-09-17 20:21:22
  • Mysql数据库性能优化三(分表、增量备份、还原)

    2024-01-21 00:38:54
  • ubuntu kylin 14.10下多个mysql 5.7.14安装教程

    2024-01-24 12:50:13
  • numpy拼接矩阵的实现

    2021-02-09 06:35:07
  • SQL Server 压缩日志与减少SQL Server 文件大小的方法

    2024-01-22 04:26:45
  • asp之家 网络编程 m.aspxhome.com