数据库JSON类型到映射JAVA上

Mysql存放JSON数据如何映射JAVA实体类

概述:最近写在写SKU模块中,需要表中字段存放JSON类型数据,mybatis-plus在查询的时候如何跟JSON类型所匹配呢?再次记录一下。

直接上代码,后面有解释到底如何映射上的。

Mysql表数据

在这里插入图片描述

JAVA实体类

@Data
public class TSku {
    private Long id;
    private Long bookId;
    private Long inventory;
    private BigDecimal oldPrice;
    private String picture;
    private BigDecimal price;
    private String skuCode;
    // 自定义类型处理器,表示java类型与数据库类型双向转换
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private JSONObject skuProperties;
    private String specs1;
    private String specsValue1;
    private String specs2;
    private String specsValue2;
    // 自定义类型处理器,表示java类型与数据库类型双向转换
    @TableField(typeHandler = FastjsonTypeHandler.class)
    private JSONArray skuPropertiesName;

    @TableField(exist = false)
    private List<SkusSpec> specs;
}

XML查询SQL

<select id="getTSkuList" resultMap="skuList">
        select * from t_sku
        where book_id = #{bookId}
    </select>

    <resultMap id="skuList" type="org.dromara.library.domain.TSku">
        <!-- 转换JSONObject-->
        <result column="sku_properties"
                property="skuProperties"
        jdbcType="OTHER" javaType="com.alibaba.fastjson.JSONObject"
        typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler" />
        <!-- 转换JSONArray-->
        <result column="sku_properties_name"
                property="specs"
                jdbcType="OTHER" javaType="com.alibaba.fastjson.JSONArray"
                typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler" />
    </resultMap>
属性名称作用
column数据库表中列名
propertyJava实体类中的属性名
jdbcType数据库字段的JDBC类型,这里是OTHER表示字段的类型不是JDBC标准类型
javaType映射到Java实体类属性类型
typeHandler自定义类型处理器,主要负责Java类型和JDBC类型之间进行转换

java返回结果展示

"code": 200,
    "msg": "操作成功",
    "data": [
        {
            "id": 1,
            "bookId": 11,
            "inventory": 10,
            "oldPrice": "100.00",
            "picture": "http://xx.xx.xxx.xx:xx/ttbook/2024/02/28/bc4d02cc21974b85aceb9c4aa55b8b66.jpg",
            "price": "49.00",
            "skuCode": "TT001",
            "skuProperties": {
                "1": "1",
                "2": "3"
            },
            "specs1": "1",
            "specsValue1": "1",
            "specs2": "2",
            "specsValue2": "3",
            "skuPropertiesName": null,
            "specs": [
                {
                    "valueName": "十宗罪1",
                    "name": "系列"
                },
                {
                    "valueName": "不恐怖",
                    "name": "版本"
                }
            ]
        }

首先,要知道一个概念,就是mybatis-plus执行SQL查询的过程

  1. 构建SQL语句:编写SQL语句,在xml中或使用注解定义SQL。参数占位符:使用#{}或 ${}来插入动态参数
  2. 参数绑定:在执行SQL查询之前,使用TypeHandler将Java类型转换成JDBC类型。例如String -> varchar, Date -> TIMESTAMP
  3. 预编译SQL:使用PreparedStatement预编译SQL语句,将参数替换成占位符。
  4. 执行SQL:执行预编译后的SQL语句,从 数据库中获取结果集
  5. 结构映射:
    1. mybatis:通过ResultMap配置,将数据库结果集中的列值映射到Java对象的属性上
    2. 结果映射中同样会使用TypeHandler来处理从数据库类型到Java类型的转换
    3. 如果结果 集中的列是一个JSON字符串,而你想映射到一个com.alibaba.fastjson.JSONObject对象,这时可以使用自定义的TypeHandler(FastjsonTypeHandler 针对JSON字段使用)来进行转换
  6. 构建对象:根据映射配置,mybatis会遍历结果集,并为每一行数据创建一个Java对象实例,将结果集中对应的列填充到对象的属性中。

知道这个概念之后,只要利用typeHandler来指定javaType类型为JSONObject或JSONArray就可以实现映射了!!

附加功能: Mybatis 一对多映射

SQL结果集

3	系列	十宗罪1	6	第一部	  1	测试地址
3	系列	十宗罪2	7	第二部	  1 测试地址
4	版本	恐怖	     8	 真恐怖   1 测试地址
4	版本	不恐怖	    9	真不恐怖  1	测试地址

最终结果:

 "data": [
        {
            "id": "3",
            "name": "系列",
            "values": [
                {
                    "id": "6",
                    "name": "十宗罪1",
                    "picture": "测试地址",
                    "available": "1",
                    "desc": "第一部"
                },
                {
                    "id": "7",
                    "name": "十宗罪2",
                    "picture": "测试地址",
                    "available": "1",
                    "desc": "第二部"
                }
            ]
        },
        {
            "id": "4",
            "name": "版本",
            "values": [
                {
                    "id": "8",
                    "name": "恐怖",
                    "picture": "测试地址",
                    "available": "1",
                    "desc": "真恐怖"
                },
                {
                    "id": "9",
                    "name": "不恐怖",
                    "picture": "测试地址",
                    "available": "1",
                    "desc": "真不恐怖"
                }
            ]
        }
    ]

resultMap实现一对多

<!--    查询规格 属性值 -->
    <select id="getSpecsList" resultMap="specsList">
        SELECT
            t4.id  as id,
            t4.`name` as name,
            t3.`name` as nameValue,
            t3.id as idValue,
            t3.`desc` as `desc`,
            t3.available as available,
            t3.picture as picture
        FROM
            book_specs_value t2
                JOIN t_specs_value t3 ON t2.specs_value_id = t3.id
                JOIN t_specs t4 ON t2.specs_id = t4.id
        WHERE
            t2.book_id = #{bookId}
    </select>

    <!-- 一对多 -->
    <resultMap id="specsList" type="org.dromara.app.appojo.aojo.details.Specs">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <collection property="values" ofType="org.dromara.app.appojo.aojo.details.SpecsValue">
            <id column="idValue" property="id" ></id>
            <result column="nameValue" property="name"></result>
            <result column="desc" property="desc"></result>
            <result column="picture" property="picture"></result>
            <result column="available" property="available"></result>
        </collection>
    </resultMap>
  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值