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_skuwhere 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 | 数据库表中列名 |
property | Java实体类中的属性名 |
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查询的过程
- 构建SQL语句:编写SQL语句,在xml中或使用注解定义SQL。参数占位符:使用#{}或 ${}来插入动态参数
- 参数绑定:在执行SQL查询之前,使用TypeHandler将Java类型转换成JDBC类型。例如String -> varchar, Date -> TIMESTAMP
- 预编译SQL:使用PreparedStatement预编译SQL语句,将参数替换成占位符。
- 执行SQL:执行预编译后的SQL语句,从 数据库中获取结果集
- 结构映射:
- mybatis:通过ResultMap配置,将数据库结果集中的列值映射到Java对象的属性上
- 结果映射中同样会使用TypeHandler来处理从数据库类型到Java类型的转换
- 如果结果 集中的列是一个JSON字符串,而你想映射到一个com.alibaba.fastjson.JSONObject对象,这时可以使用自定义的TypeHandler(FastjsonTypeHandler 针对JSON字段使用)来进行转换
- 构建对象:根据映射配置,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">SELECTt4.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 pictureFROMbook_specs_value t2JOIN t_specs_value t3 ON t2.specs_value_id = t3.idJOIN t_specs t4 ON t2.specs_id = t4.idWHEREt2.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>