当前位置:   article > 正文

【BUG 记录】MyBatis-Plus 处理枚举字段和 JSON 字段_mybatis plus 查询枚举属性

mybatis plus 查询枚举属性


在这里插入图片描述

一、枚举字段(mysql环境已测、postgresql环境已测)

1.1 场景


User 实体类中有一个枚举字段(GenderEnum):

@Data
@TableName("test_user")
public class UserEntity {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private String name;

    private Integer age;

    private GenderEnum gender;

    private String address;

    private String phone;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

  像这种字段我们一般会定义一个枚举,做业务判断的时候就可以直接基于枚举做比较。但是我们数据库采用的是 int 类型,对应的 PO 也是Integer。因此业务操作时必须手动把枚举与 Integer 转换,非常麻烦。因此,Mybatis Plus提供了一个处理枚举的类型转换器,可以帮我们把枚举类型与数据库类型自动转换。

1.2 定义枚举常量


  首先,我们为用户表中的这个状态字段定义一个枚举常量:

@Getter
public enum GenderEnum{

    WOMAN(0,"女"),
    MAN(1, "男");


    @EnumValue
    private final Integer code;
    @JsonValue
    private final String desc;

    GenderEnum(Integer code,String desc){
        this.code = code;
        this.desc = desc;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

要让 Mybatis Plus处理枚举与数据库类型自动转换,我们必须告诉 Mybatis Plus,枚举中的哪个字段的值作为数据库值。Mybatis Plus 提供了 @EnumValue 注解来标记枚举属性

并且,在GenderEnum枚举中通过@JsonValue注解标记 JSON 序列化时展示的字段是 desc

1.3 配置枚举处理器


  在application.yml 文件中添加以下配置,以开启枚举处理器的功能:

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler # 枚举处理器
  • 1
  • 2
  • 3

1.4 测试


  例如,根据id查询某个用户:
  此时,查询出的User类的 status 字段会是枚举类型。
1703574125196.png

二、JSON字段(mysql环境已测)

2.1 导包


<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.79</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

2.2 使用对象接受


@Data
@TableName(value= "test_user" ,autoResultMap = true)
public class UserEntity {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private String name;

    private Integer age;

    private GenderEnum gender;

    @TableField(typeHandler = FastjsonTypeHandler.class)
    private JSONObject address;

    private String phone;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:

  1. 添加 autoResultMap = true,开启自动映射
  2. 添加 @TableField(typeHandler = FastjsonTypeHandler.class),JSON处理器
  3. 字段类型修改为 JSONObject

2.3 测试


image.png

image.png

三、JSON 字段 (postgresql环境 已测)

3.1 postgresql 数据库中的字段类型设置为 jsonb


image.png

3.2 创建实体类


  • 在实体类上加上 @TableName(value = "表名", autoResultMap = true)
  • jsonb属性上加上 @TableField(value = "字段", typeHandler = JsonbTypeHandler.class)

JsonbTypeHandler 这个类在下面创建

@Data
@TableName(value= "test_user" ,autoResultMap = true)
public class UserEntity {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    private String name;

    private Integer age;

    private GenderEnum gender;

    @TableField(value = "address", typeHandler = JsonbTypeHandler.class)
    private Object address;

    private String phone;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.3 创建 jsonb 类型处理器

3.3.1 方式一


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

@MappedTypes({Object.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class JsonbTypeHandler extends AbstractJsonTypeHandler<Object> {
    private static final PGobject jsonObject = new PGobject();
    private final Class<?> type;

    public JsonbTypeHandler(Class<?> type) {
        this.type = type;
    }

    /**
     * 重写设置参数
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        if (ps != null) {
            jsonObject.setType("jsonb");
            jsonObject.setValue(JSON.toJSONString(parameter));
            ps.setObject(i, jsonObject);
        }
    }

    /**
     * 根据列名,获取可以为空的结果
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Object v = rs.getObject(columnName);
        return toFill(v);
    }

    /**
     * 根据列索引,获取可以为空的结果
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Object v = rs.getObject(columnIndex);
        return toFill(v);
    }

    @Override
    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Object v = cs.getObject(columnIndex);
        return toFill(v);
    }

    @Override
    protected Object parse(String json) {
        return JSON.parseObject(json, this.type);
    }

    /**
     * 必须将 v 转成 PGObject 处理
     * @param v
     * @return
     */
    private Object toFill(Object v) {
        if (v != null && v instanceof PGobject) {
            PGobject p = (PGobject) v;
            String pv = p.getValue();
            if (Objects.nonNull(pv) && ("jsonb".equals(p.getType()) || "json".equals(p.getType()))) {
                return parse(p.getValue());
            }
        }
        return v;
    }

    @Override
    protected String toJson(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

3.3.2 方式二


package com.xawl.webenum.handler;

import com.alibaba.fastjson.JSON;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@MappedTypes({Object.class})
public class JsonbDataTypeHandler extends BaseTypeHandler<Object> {
    private static final PGobject jsonObject = new PGobject();

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
        if (preparedStatement != null) {
            jsonObject.setType("jsonb");
            jsonObject.setValue(JSON.toJSONString(o));
            preparedStatement.setObject(i, jsonObject);
        }
    }

    @Override
    public Object getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return JSON.parse(resultSet.getString(s));
    }

    @Override
    public Object getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return JSON.parse(resultSet.getString(i));
    }

    @Override
    public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return JSON.parse(callableStatement.getString(i));
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

3.4 测试


  1. 测试 save

image.png 插入成功
image.png

  1. 测试 get

image.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/988936
推荐阅读
相关标签
  

闽ICP备14008679号