Skip to content

开发技巧之枚举类型的序列化

【一】保存枚举的 name() 到数据库

在使用 JSON 传值的时候,对于枚举类型的处理是比较麻烦的,因为基本上默认都只会按照枚举的名称来序列化和反序列化。

  1. 使用 @JsonFormat(shape = JsonFormat.Shape.OBJECT) 注解来让枚举按照类(对象)的格式进行序列化。
  2. 使用 @JsonCreator 注解标记一个通过枚举码来查询枚举的方法,Jackson 会使用这个有参构造器进行反序列化。
java
package com.github.mengweijin.mybatisplus.demo.enums;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;

/**
 * @author mengweijin
 */
@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Gender {

    MALE(1, "男"), FEMALE(2, "女"), OTHER(3, "其他");

    private int code;
    private String value;

    Gender(int code, String value) {
        this.code = code;
        this.value = value;
    }

    /**
     * 数据库保存的是什么,这里的参数就要用什么来做。比如:这个例子中使用的是 Gender.name() 属性(MALE, FEMALE, OTHER)保存在数据库中的。
     *
     * @param name MALE, FEMALE, OTHER
     * @return Gender
     */
    @JsonCreator
    public static Gender ofName(String name) {
        for (Gender gender: Gender.values()) {
            if (gender.name().equalsIgnoreCase(name)) {
                return gender;
            }
        }
        return Gender.OTHER;
    }
}
java
package com.github.mengweijin.mybatisplus.demo.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.github.mengweijin.mybatisplus.demo.enums.Gender;
import com.github.mengweijin.quickboot.mybatis.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * @author mengweijin
 */
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("SYS_USER")
public class User extends BaseEntity {

    @TableField("name")
    private String name;

    private Gender gender;

    private Integer deleted;
}

保存的时候传入枚举参数

示例:

本示例中可选的参数:MALE, FEMALE, OTHER

java
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @PostMapping("/save")
    public void addUser(@RequestBody User user){
        userService.saveOrUpdate(user);
    }
}

序列化后的 JSON

可以看出,在枚举类中使用 @JsonFormat(shape = JsonFormat.Shape.OBJECT)后,gender 展示的 JSON 为 Object 的结构,而不是默认的 String 结构。

默认就只展示:{ "gender": "MALE" } 的样子。

json
[
  {
    "id": "1",
    "createTime": "2021-10-18T14:10:02.526304",
    "createBy": "SYSTEM",
    "updateTime": "2021-10-18T14:10:02.526304",
    "updateBy": "SYSTEM",
    "name": "张三",
    "gender": {
      "code": 1,
      "value": "男"
    },
    "deleted": 0
  }
]

【二】保存枚举中指定的字段

比如,上面 Gender 枚举类中的 code 字段到数据库。

这就需要在 MyBatis 中作转换,自定义类型转换器。

参考 MyBatis-Plus 的实现:https://baomidou.com/guide/enum.html

com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler.java
com.baomidou.mybatisplus.annotation.IEnum.java
com.baomidou.mybatisplus.annotation.EnumValue.java