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

目录
  • 前言
  • 应用场景介绍
  • 数据字典案例实践
    • 表结构
    • 实体类
    • 关系映射
    • 泛型擦除问题解决(7.21新增)
  • 效果展示
  • 总结

前言

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

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

(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!所以在后面的遍历时报类型转换失败的错,这就是典型的泛型擦除问题!

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

解决方案1:

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

8.11新增:解决方案2:

效果展示

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

总结

JSON类型的功能十分强大,可以通过MySQL提供的JSON相关的方法直接操作JSON字段中的某个属性值,也可以针对JSON类型字段的数据进行各种操作。

相对于使用字符串类型保存JSON字符串的方式而言,使用JSON类型的另外一个好处是可以在程序上定义JSON格式,提供更友好而规范的API文档。

另外如果不想使用JSON类型,直接用Varchar类型也是可以的哦!如果用JSON类型可以根据JSON对象的字段进行条件查询!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • MybatisPlus如何处理Mysql的json类型

    目录 MybatisPlus处理Mysql的json类型 MyBatis Plus - xml中如何使用autoResultMap构造的ResultMap MyBatis-Plus - JacksonTypeHandler VS FastjsonTypeHandler MybatisPlus读写Mysql的json字段 前置条件 一.新建mysql表增加json字段 二.pojo类 三.测试类 MybatisPlus处理Mysql的json类型 1.在数据库表定义JSON字段: 2.在实体类加上

  • Mybatis-Plus读写Mysql的Json字段的操作代码

    目录 前置条件 一.新建mysql表增加json字段 二.pojo类 三.测试类 前置条件 确保mysql的版本是5.7+ 一.新建mysql表增加json字段 二.pojo类 package com.cxstar.domain; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.

  • mybatis plus实体类中字段映射mysql中的json格式方式

    目录 mybatis plus实体类中字段映射mysql中的json格式 1.实体类中有个属性是其他对象 2.那么取出时怎么进行映射呢,有分为两种情况 mybatis-plus 实体 json 处理 本文总共三个步骤 mybatis plus实体类中字段映射mysql中的json格式 1.实体类中有个属性是其他对象 或者是List:在数据库中存储时使用的是mysql的json格式,此时可以用mybatis plus的一个注解 @TableField(typeHandler = JacksonTy

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

    目录 前言 应用场景介绍 数据字典案例实践 表结构 实体类 关系映射 泛型擦除问题解决(7.21新增) 效果展示 总结 前言 JSON类型是MySQL5.7.8中新加入的一种数据类型,并在后续版本尤其是MySQL8.0中得到了大幅增强,现在的JSON类型的功能十分强大,合理使用能让我们的开发更加有效! 但本文不准备花篇幅来介绍MySQL的JSON类型字段的相关API,因为官方文档里面写得已经十分详细了,大家如果对MySQL的JSON类型还不怎么了解的话可以看看官方文档: MySQL5.7 JSO

  • MySQL之JSON类型字段的使用技巧分享

    目录 准备工作 JSON对象基础操作 JSON数组操作 更多操作 JSON字段在JAVA中的实践 测试环境: MySQL8.0.19 准备工作 CREATE TABLE json_demo ( `id` INT ( 11 ) NOT NULL PRIMARY KEY, `content` json NOT NULL ); INSERT INTO json_demo ( id, content ) VALUES /*这条是数组*/ ( 1, '[{"key": 1, "orde

  • mysql中json类型字段的基本用法实例

    目录 前言 基本环境 JSON类型字段常用操作 插入JSON类型数据 查询JSON类型数据 更新JSON类型数据中的特定字段 匹配JSON类型数据中的特定字段 结语 前言 mysql从5.7.8版本开始原生支持了JSON类型数据,同时可以对JSON类型字段中的特定的值进行查询和更新等操作,通过增加JSON类型的属性可以大大的提高我们在mysql表中存储的数据的拓展性,无需每次新增字段时都进行表结构的调整,下面我们不深入讲解底层的实现原理,我们主要来梳理一下我们在日常工作中使用实践 基本环境 my

  • MySQL对JSON类型字段数据进行提取和查询的实现

    目录 前言 1. 问题现象 2. 解决方案 3. JSON数据查询 3.1 一般基础查询操作 3.2 一般函数查询操作 4. JSON数据新增更新删除 前言 昨天上线后通过系统报警发现了一个bug,于是紧急进行了回滚操作,但是期间有用户下单,数据产生了影响,因此需要排查影响了哪些订单,并对数据进行修复. 1. 问题现象 由于bug导致了订单表的customer_extra_info字段的hasFreightInsurance误更新成了“是”,因此需要查询回滚前一共有多少被误更新为“是”的订单,如

  • Django中模型Model添加JSON类型字段的方法

    本文实例讲述了Django中模型Model添加JSON类型字段的方法.分享给大家供大家参考.具体如下: Django里面让Model用于JSON字段,添加一个JSONField自动类型如下: class JSONField(models.TextField): __metaclass__ = models.SubfieldBase description = "Json" def to_python(self, value): v = models.TextField.to_pytho

  • Postgresql数据库中的json类型字段使用示例详解

    目录 1. Json概述 2. Postgresql数据库中使用Json类型字段 2.1. 创建表定义字段信息 2.2. 增加 2.3. 查询键值 2.3.1. 查询键 2.3.2. 查询值 2.3.3. where查询条件使用json键值作为条件 PostgreSQL 最重要的文档性数据类型就是JSON了,与 MongoDB 的BSON相比较,PostgreSQL 或许更加强大,因为它能与原有的关系性范式兼容,给数据库存储与维护带来了更多的可行性和便利性. 1. Json概述 JSON 代表

  • MYSQL SET类型字段的SQL操作知识介绍

    复制代码 代码如下: <em>`mark` set('index','best','hot')</em> 用的人少,懂的人也少,找了很久,总算凑齐了一套知识点看上面的结构,MYSQL不傻,会存index吗,不会,存的是数字SET字段是利用二进制数字来一一对应你设置的值,比如index,排在第0位,那么2的零次方等于1 复制代码 代码如下: update from table SET mark=1 复制代码 代码如下: update from table SET mark='inde

  • Mysql 5.7 新特性之 json 类型的增删改查操作和用法

    目录 插入数据 :insert操作 更新记录:update 追加内容: 更新记录:追加内容到数组: 更新记录:update 修改json属性: 删除记录: 查询记录: 扩展: 一.插入一条数据: 1.查找 JSON 中的某个字段: 2.根据JSON中的某个字段查询表中记录: 二.修改 JSON 1.修改 JSON 中的某个字段: 2.往 JSON 中插入一个新的字段: 近几年来,nosql大行其道,json更是火的一塌糊涂,作为数据库的元老,mysql在5.7版本中添加了对json数据的支持.这

  • Java将Date日期类型字段转换成json字符串的方法

    想必我们在做项目的时候,都会遇到服务端与客户端交互数据.一般情况下我们都会采用json格式或者xml格式,将服务端的数据转换成这两种格式之一. 但是,如果我们将数据转换成json格式的时候,我们也许会遇到Date日期型的数据转换成json格式后,并不是我们想要的格式.下面我们通过简单的demo 来说明这个问题. 我们按照一般json格式生成,会出现以下问题: 采用json:将数据生成json格式,需要导入相应的jar包,如下图: Student.java package com.xbmu.bea

随机推荐