让 MyBatis-Plus 自动把 Java 对象转成 JSON 存数据库,查的时候再自动转回来
实现原理:
插入时 :@TableField 告诉 MP 用哪个 TypeHandler 把对象转成 JSON 字符串。
查询时 :autoResultMap 生成带 TypeHandler 的 ResultMap,MyBatis 用 TypeHandler 把 JSON 字符串转回对象。
核心 :TypeHandler 是桥梁,负责 Java 对象 ↔ JSON 字符串的双向转换。
1 建表,注意有几个字段类型为json
CREATE TABLE `order` (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID',
order_no VARCHAR(32) NOT NULL COMMENT '订单编号',
user_id BIGINT NOT NULL COMMENT '用户ID',
product_info JSON COMMENT '商品信息 {"name":"iPhone","price":5999}',
address_info JSON COMMENT '地址信息 {"province":"广东","city":"深圳"}',
extra_data JSON COMMENT '扩展数据 ["发票","保修"] 或 {"source":"app"}',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
2 修改pojo,注意:autoResultMap 声明自动映射 , typeHandler 声明类型处理器
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Data
@TableName(value = "`order`", autoResultMap = true)
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
private String orderNo;
private Long userId;
//JSON 对象
@TableField(typeHandler = JacksonTypeHandler.class)
private ProductInfo productInfo;
@TableField(typeHandler = JacksonTypeHandler.class)
private AddressInfo addressInfo;
//JSON 可以是 List 或 Map,这里用 Object 兼容
@TableField(typeHandler = JacksonTypeHandler.class)
private Object extraData;
private LocalDateTime createTime;
}
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ProductInfo {
private String name;
private BigDecimal price;
private String sku;
}
import lombok.Data;
@Data
public class AddressInfo {
private String province;
private String city;
private String detail;
}
3 mapper接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplus.entity.Order;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
int batchInsert(@Param("list") List<Order> orders);
}
4 OrderMapper.xml ,注意:typeHandler
<?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.example.mybatisplus.mapper.OrderMapper">
<resultMap id="map1" type="com.example.mybatisplus.entity.Order">
<id property="id" column="id"/>
<result property="orderNo" column="order_no"/>
<result property="userId" column="user_id"/>
<result property="productInfo" column="product_info" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result property="addressInfo" column="address_info" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result property="extraData" column="extra_data" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
</resultMap>
<insert id="batchInsert">
INSERT INTO `order` (order_no, user_id, product_info, address_info, extra_data) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.orderNo}, #{item.userId},
#{item.productInfo,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
#{item.addressInfo,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
#{item.extraData,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler})
</foreach>
</insert>
</mapper>
5 核心要改的 , 总结
|---------|--------------------------------------------------------------------------------------------|
| 实体类 | @TableName(autoResultMap = true) + @TableField(typeHandler = JacksonTypeHandler.class) |
| XML | #{field,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} |