【mybatis-plus实体类复杂对象字段json自动相互转换,以及自定义字段类型解析器】

文章介绍了如何使用Mybatis-Plus的@TableField注解结合JacksonTypeHandler进行JSON字段的自动转换,以及当遇到复杂对象时,如何自定义类型处理器MyFieldTypeHandler进行处理。通过这种方式,可以在插入/更新数据库时自动将对象转换为JSON,查询时再自动转换回对象,避免手动转换的繁琐操作。

引言:

  1. mybatis-plus集合对象字段json如何自动进行相互的转换?
  2. 怎样在使用mybatis-plus操作数据表的时候自动对实体类属性进行自动解析?


前言

我们平时在做开发的时候,会遇到一个字段保存json串的情况。一般情况下mybatis-plus在做插入/更新之前将对象手动转换成json串,查询要用的时候再手动的从json转换成对象,非常的low。有没有什么方案将这个过程进行自动转换呢?


有,通过 @TableField 这个注解实现

一、@TableField是什么?

说明:@TableField是mybatis-plus的一种字段处理器,该处理器可以解决字段类型转换的问题,但是需要
typeHandler Class<? extends TypeHandler> 类型处理器进行转换。

二、@TableField使用

代码如下(示例):

	@TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> abcList;

但是JacksonTypeHandler处理类只适用于简单的对象字段属性类型,遇到更复杂的嵌套json串,就需要我们自己去定义类型处理器来处理。如下类D的属性字段aList:

@Data
public class D {

    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<A> aList;

    @Data
    public static class A {
        private Map<String, B> bList;
    }

    @Data
    public static class B {
        private E e;
    }

    @Data
    public static class E {
        private String str;
    }
}

三、自定义复杂对象的处理

1. 先看下JacksonTypeHandler是怎么处理简单json对象的:

@MappedTypes({Object.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class JacksonTypeHandler extends AbstractJsonTypeHandler<Object> {
    private static final Logger log = LoggerFactory.getLogger(JacksonTypeHandler.class);
    private static ObjectMapper OBJECT_MAPPER;
    private final Class<?> type;

    public JacksonTypeHandler(Class<?> type) {
        if (log.isTraceEnabled()) {
            log.trace("JacksonTypeHandler(" + type + ")");
        }

        Assert.notNull(type, "Type argument cannot be null", new Object[0]);
        this.type = type;
    }
	// 这里对json串进行解析
    protected Object parse(String json) {
        try {
            return getObjectMapper().readValue(json, this.type);
        } catch (IOException var3) {
            throw new RuntimeException(var3);
        }
    }
	// 这里将对象转换成了json串
    protected String toJson(Object obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (JsonProcessingException var3) {
            throw new RuntimeException(var3);
        }
    }

    public static ObjectMapper getObjectMapper() {
        if (null == OBJECT_MAPPER) {
            OBJECT_MAPPER = new ObjectMapper();
        }

        return OBJECT_MAPPER;
    }

    public static void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "ObjectMapper should not be null", new Object[0]);
        OBJECT_MAPPER = objectMapper;
    }
}

2. 模仿JacksonTypeHandler来进行自定义字段类型解析器:MyFieldTypeHandler


@MappedTypes({Object.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class MyFieldTypeHandler extends AbstractJsonTypeHandler<Object> {
    private static final Logger log = LoggerFactory.getLogger(com.xxx.handlers.MyFieldTypeHandler.class);
    private static ObjectMapper objectMapper = new ObjectMapper();

    public MyFieldTypeHandler(Class<?> type) {
        if (log.isTraceEnabled()) {
            log.trace("JacksonTypeHandler(" + type + ")");
        }
        Assert.notNull(type, "Type argument cannot be null", new Object[0]);
    }
	
    protected Object parse(String json) {
        try {
        	// 这里进行了json解析,同样在这里也可以进行字段查询后的处理,如对象内部的手机号字段的加密展示等
            return objectMapper.readValue(json, new TypeReference<List<A>>(){});
        } catch (IOException var3) {
            throw new RuntimeException(var3);
        }
    }

    protected String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException var3) {
            throw new RuntimeException(var3);
        }
    }
    public static void setObjectMapper(ObjectMapper om) {
        objectMapper = om;
    }
}

那么字段上的处理器就换成自己定义的类型解析器,即可

	@TableField(typeHandler = MyFieldTypeHandler.class)
    private List<A> aList;

注意:实体类@TableName(value = “表名”, autoResultMap = true),autoResultMap 需要 是 true

总结

以上就是mybatis-plus集合对象字段json自动相互转换的内容,本文仅仅简单介绍了@TableField注解配合typeHandler的使用,其他用途下次在进行总结。

<think>好的,我现在需要帮助用户解决如何使用MyBatis-Plus将数据库中的JSON类型字段映射为实体类中的Map属性的问题。首先,我需要回顾一下MyBatis-Plus字段映射机制,特别是处理复杂类型如JSON的情况。 根据用户提供的引用内容,MyBatis-Plus主要通过注解来实现字段映射,比如@TableField。引用[3]提到如何处理数据库中的bit类型到Java的boolean类型,这可能涉及到类型处理器(TypeHandler)。对于JSON类型,应该也需要类似的类型处理器来转换数据库中的JSON字符串到Java的Map结构。 接下来,我需要确认MyBatis-Plus是否内置了对JSON类型的支持。根据经验,MyBatis-Plus通常依赖MyBatis本身的TypeHandler来处理不同类型的数据转换。例如,对于JSON字段,可能需要自定义一个TypeHandler,将数据库中的JSON字符串转换为Map,反之亦然。 用户的问题涉及到将数据库的JSON字段映射为实体类的Map属性,所以步骤可能包括: 1. 在实体类中使用@TableField注解,并指定typeHandler为某个处理JSON的TypeHandler。 2. 可能需要引入JSON处理库,比如Jackson或Fastjson,来实现JSON字符串与Map之间的转换。 3. 在数据库表中,对应的字段类型应为JSON(如果数据库支持,如MySQL的JSON类型)或者VARCHAR等文本类型来存储JSON字符串。 引用[1]提到实体类字段与数据库表字段的映射方式,其中可能包括TypeHandler的使用。引用[3]中的例子展示了如何处理布尔类型,类似的逻辑可以应用到JSON转换上。 另外,需要确保自定义的TypeHandler被正确注册到MyBatis-Plus的配置中,或者在字段注解中明确指定。例如,使用JacksonTypeHandler来处理JSON转换。 可能还需要考虑数据库驱动是否支持JSON类型,以及在实体类中定义Map属性时的泛型类型,比如Map<String, Object>。 总结步骤: - 创建实体类,定义Map类型的属性,并使用@TableField注解指定自定义的TypeHandler。 - 实现或引用现有的TypeHandler,如JacksonTypeHandler。 - 配置MyBatis-Plus以使用该TypeHandler,可能需要在配置类中注册或者在注解中直接指定。 - 确保数据库字段类型正确,如使用VARCHAR或JSON类型存储JSON字符串。 还需要验证这些步骤是否正确,以及处理可能出现的异常情况,比如JSON解析错误,或者数据库字段Java类型不匹配的问题。 最后,生成相关问题需要考虑用户可能遇到的后续问题,例如如何处理复杂的嵌套JSON结构,或者性能优化的建议等。</think>### MyBatis-PlusJSON 字段与 Map 属性的映射方法 在 MyBatis-Plus 中,将数据库的 JSON 类型字段映射为实体类的 `Map` 属性,需结合 **字段注解** 和 **类型处理器(TypeHandler)** 实现。以下是具体步骤: --- #### 1. 实体类定义 在实体类中,使用 `@TableField` 注解并指定 `typeHandler` 属性。例如,若数据库字段为 `json_data`,则映射如下: ```java public class YourEntity { @TableField(value = "json_data", typeHandler = JacksonTypeHandler.class) private Map<String, Object> jsonData; // 使用 Map 接收 JSON 数据 } ``` **说明**: - `JacksonTypeHandler` 是 MyBatis-Plus 内置的处理器,可自动JSON 字符串与 `Map` 或自定义对象互相转换[^1]。 - 若需自定义逻辑(如处理复杂嵌套结构),可继承 `BaseTypeHandler` 实现自己的处理器。 --- #### 2. 数据库表设计 确保数据库字段类型支持 JSON 存储: - **MySQL**: 使用 `JSON` 类型字段(推荐)或 `VARCHAR`。 - **PostgreSQL**: 使用 `JSONB` 类型。 - **其他数据库**: 若不支持 JSON 类型,使用 `TEXT` 或 `VARCHAR`。 --- #### 3. 依赖配置 在 `pom.xml` 中添加 JSON 处理库(如 Jackson)依赖: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> </dependency> ``` --- #### 4. 全局配置(可选) 在 `application.yml` 中启用 MyBatis-Plus自动类型处理器匹配: ```yaml mybatis-plus: configuration: default-scripting-language: org.apache.ibatis.scripting.xmltags.XMLLanguageDriver map-underscore-to-camel-case: true type-handlers-package: com.example.handler # 自定义处理器包路径 ``` --- #### 5. 查询与写入验证 - **插入数据**:直接操作 `Map` 属性,MyBatis-Plus自动转换JSON 字符串。 - **查询数据**:查询结果中的 `json_data` 字段自动反序列化为 `Map`。 --- ### 常见问题解决 1. **类型转换异常** 检查 JSON 字符串格式是否正确,或尝试手动指定 `ObjectMapper` 配置: ```java @Bean public JacksonTypeHandler jacksonTypeHandler(ObjectMapper objectMapper) { return new JacksonTypeHandler(objectMapper); } ``` 2. **嵌套对象映射** 若 JSON 包含嵌套对象,可定义子类并通过 `TypeReference` 指定泛型类型: ```java new TypeReference<Map<String, NestedObject>>() {} ``` --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值