数据库json格式字段映射,以及泛型擦除笔记

如果使用了Mybatis-Plus(后文简称MP),则在实体类上增加注解:@TableName(value = "sys_menu", autoResultMap = true),并在对应字段上增加注解:@TableField(typeHandler = JacksonTypeHandler.class)即可。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.copm.ifm.base.basic.pojo.MenuContentList;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 系统菜单表
 *
 * @author zzf
 * @since 2020-12-14
 */
@Getter
@Setter
@ToString
@TableName(value = "sys_menu", autoResultMap = true)
@ApiModel("系统菜单表")
public class SysMenu {

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty("名称")
    private String name;

    @ApiModelProperty("操作权限")
    @TableField(typeHandler = JacksonTypeHandler.class)
    private MenuContentList operations;
}

上述解决方案只适用于MP提供的基础CRUD方法,当我们自己在.xml文件中自己写SQL时就不适用了,此时我们需要自定义resultMap,并在对应字段的<result>标签中增加typeHandler属性。

typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"

  只用了Mybatis的也是使用这种方式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.copm.ifm.servers.sys.mapper.SysMenuMapper">

    <resultMap id="BaseResultMap" type="com.copm.ifm.servers.sys.vo.SysMenuPageVO">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="operations" property="operations" 
        		typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>
    
    <select id="selectForPage" resultMap="BaseResultMap">
        SELECT
            id, 
            name, 
            operations
        FROM
            sys_menu
    </select>
</mapper>

json内字段作为查询条件:

LambdaQueryWrapper<TestData> wrapper = Wrappers.<TestData>lambdaQuery()
// 按事件类型
.apply(dto.getEventType() != null, "json_data->'$.event_type' = {0}", dto.getEventType());
补充:
【问题一】LocalDateTime 数据映射到json后变成了:

"createTime": {"hour": 14, "nano": 0, "year": 2022, "month": "FEBRUARY", "minute": 52, "second": 18, "dayOfWeek": "THURSDAY", "dayOfYear": 55, "chronology": {"id": "ISO", "calendarType": "iso8601"}, 

解决办法:

@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;

【问题二】 泛型擦除:

报错信息如下:java.lang.ClassCastException: java.util.HashMap cannot be cast to xxx:

解决办法:

实体类(entity)

添加内部类OperationList,修改属性类型:List<Operation> -> OperationList

// 修改前: 
private List<Operation> operations;  

// 修改后
private OperationList operations;
// 解决泛型擦除问题
public static class OperationList extends ArrayList<Operation> {}

Mapper.xml

添加:javaType="org.example.modules.business.entity.SysMenu$OperationList"

        <result column="operations" property="operations" 
javaType="org.example.modules.business.entity.SysMenu$OperationList"
        		typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>

参考:

1. 关于泛型,说明的非常详细的好文:Java 泛型,你了解类型擦除吗?_frank909的博客-CSDN博客_java泛型擦除

 2. 关于泛型擦除,以及解决办法说明的很详细:

一个Mybatis异常,引发出来的知识点:泛型类型擦除问题_小哥骑单车的博客-CSDN博客

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值