Mybatis读取和存储json类型的数据

news/2024/11/29 22:40:33/

目录

    • 一、测试使用JSONObject来获取json
    • 二、设置@TableName的autoResultMap为true,@TableField的typeHandler为JacksonTypeHandler.class
    • 三、设置xml当中的resultMap
    • 四、JacksonTypeHandler讲解
    • 五、新增假如是JSONObject异常问题
    • 六、遇到转义的问题

不管数据库当中是以json还是longtext数据类型来存json,都可以在mybatis当中使用string来接数据。这一点毋庸置疑!但是想要使用JSONObject类型的字段来取值是否可以呢?

一、测试使用JSONObject来获取json

接下来我们来测试一下,我用的是mybatis-plus框架,mybatis-plus和mybatis是一样的,无非就是mybatis-plus封装好了一些crud方法。但是对于手写xml来说两个框架是一样的。

实体类如下:这里的JSONObject我用的hutool工具包的,JSONObject一般引用的json框架都有

测试接口如下:这里一共写了两个接口,一个接口是手写的,一个是调用的mybatis-plus当中提供的BaseMapper的selectList方法

查询结果如下:假如想要使用JSONObject来映射数据库当中的json数据,不做任何配置是取不到的。

这个是访问mybatis-plus当中提供的查询方法

得出结论:在不做任何配置的情况下,不管是手写的xml接口还是用mybatis-plus自带的查询接口,都是无法将json数据映射到JSONObject类型的字段当中的。

二、设置@TableName的autoResultMap为true,@TableField的typeHandler为JacksonTypeHandler.class

两个接口测试如下:调整过后,mybatis-plus当中自带的接口是可以将json数据映射到JSONObject类型的字段当中的(不管是longtext类型存储的json还是json类型存储的json数据)

对于mybatis-plus框架我们将@TableName的autoResultMap为true,然后@TableField的typeHandler为JacksonTypeHandler.class之后,调用mybatis-plus自带的查询接口是可以将json数据映射到JSONObject类型的字段当中的。

注意:如果@TableName的autoResultMap不设置为true,那么设置typeHandler不会生效

三、设置xml当中的resultMap

使用mybatis,有两个属性标签<resultType><resultMap>可以提供结果映射。

虽然resultType 属性在大部分情况下都够用,但是在一些特殊情况下无能为力,比如属性名和列名不一致,为一些连接的复杂语句编写映射代码。遇到这些情况,我们要使用<resultMap>标签,一份 <resultMap> 能够代替实现同等功能的数千行代码。

resultMap 元素是 MyBatis 中最重要最强大的元素。resultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

注意:这里去掉了<reslutType>属性,用<resultMap>代替,二者只能选择其中的一个。

其实在上面设置@TableName的autoResultMap为true,@TableField的typeHandler为JacksonTypeHandler.class等同于在xml当中配置resultMap的某个属性使用JacksonTypeHandler。只不过mybatis-plus这块使用的是注解的形式,而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.gzl.cn.mysqljson.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.gzl.cn.mysqljson.model.User"><id column="id" jdbcType="BIGINT" property="id" /><result column="name" jdbcType="VARCHAR" property="name" /><result column="age" jdbcType="INTEGER" property="age" /><result column="email" jdbcType="VARCHAR" property="email" /><result column="result_json" jdbcType="OTHER" property="resultJson" javaType="cn.hutool.json.JSONObject" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/><result column="result_text" jdbcType="VARCHAR" property="resultText" javaType="cn.hutool.json.JSONObject" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/></resultMap><select id="getAllList" resultMap="BaseResultMap">select * from user</select></mapper>

查询结果如下:

四、JacksonTypeHandler讲解

JacksonTypeHandler是mybatis-plus提供的,不管是使用注解方式还是使用xml方式当中都使用到了JacksonTypeHandler类。那么这个类到低是干什么的?假如我使用的是mybatis而并不是mybatis-plus该怎么办?

JacksonTypeHandler就是专门用来做数据映射转换的。是mybatis-plus的,但是实际上继承的是BaseTypeHandler,而BaseTypeHandler是mybatis的,那么我们也就可以基于BaseTypeHandler来自己写一个。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class JsonTypeHandler<T> extends BaseTypeHandler<T> {private static final ObjectMapper mapper = new ObjectMapper();private Class<T> clazz;public JsonTypeHandler(Class<T> clazz) {if (clazz == null) throw new IllegalArgumentException("Type argument cannot be null");this.clazz = clazz;}@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, this.toJson(parameter));}@Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {return this.toObject(rs.getString(columnName), clazz);}@Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return this.toObject(rs.getString(columnIndex), clazz);}@Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return this.toObject(cs.getString(columnIndex), clazz);}private String toJson(T object) {try {return mapper.writeValueAsString(object);} catch (Exception e) {throw new RuntimeException(e);}}private T toObject(String content, Class<?> clazz) {if (content != null && !content.isEmpty()) {try {// 核心转换,将数据库读取的字符串,转换为指定的class类型return (T) mapper.readValue(content, clazz);} catch (Exception e) {throw new RuntimeException(e);}} else {return null;}}
}

五、新增假如是JSONObject异常问题

而对于 typeHandler 属性,MyBatis 只支持写在 2 个地方:

  • 定义在 resultMap 里,作用于查询结果的封装
  • 定义在 insert 和 update 语句的 #{property} 中的 property后面
    (例:#{property,typehandler=xxx.xxx.xxx}),并且只作用于当前 设置值

假如不配置是会报错的!

在这里插入图片描述

六、遇到转义的问题

在使用JSONObject作为Java对象的类型存值和取值是可以原样返回的:

那假如是使用的String存值和取值会发生什么样的场景呢?

首先使用String来直接接json对象肯定是不可以的,直接会报400异常。

针对于这个问题有两种方案,一种是对json建立Java对象,还有一种是直接使用JSONObject

假如使用字符串来查询会出现转义的问题

遇到这个问题可以使用commons-lang3包下的StringEscapeUtils.unescapeJava进行转换一下

查询结果如下:


http://www.ppmy.cn/news/58433.html

相关文章

ospf扩展配置—认证、沉默接口、加快收敛、缺省路由

目录标题 认证接口认证区域认证虚链路认证 沉默接口加快收敛缺省路由3类缺省5类缺省7类缺省 总结 认证 在直连的邻居或邻接之间&#xff0c;配置身份核实秘钥来保障邻居、邻接间数据沟通的安全性 接口认证 在这连连接的接口上配置 [r6-GigabitEthernet0/0/1]ospf authentic…

生成C++工程的UML类图和类继承关系图

简介 在进行软件开发时&#xff0c;了解代码结构和关系、类之间的继承关系以及类内部的成员函数和变量定义是非常重要的。为此&#xff0c;我们可以使用Doxygen和Graphviz工具来生成UML类图和类集成关系图。 Doxygen是一个用于从注释的C源代码中生成文档的工具&#xff0c;支…

Ubuntu---mysql出现ERROR1698(28000):Access denied for user root@localhost错误解决方法

查看mysql版本&#xff1a; 安装完成后&#xff0c;登录mysql的时候就出现了如下错误&#xff1a; 因为安装的过程中没让设置密码&#xff0c;可能密码为空&#xff0c;但无论如何都进不去mysql。 下面是处理过程&#xff1a; Step1&#xff1a;修改mysqld.cnf配置文件 在ubun…

(九)Geoprocessing地理处理框架——ArcToolbox内容简介

&#xff08;九&#xff09;Geoprocessing地理处理框架——ArcToolbox内容简介 目录 &#xff08;九&#xff09;Geoprocessing地理处理框架——ArcToolbox内容简介 1.工具集简介1.1 3D Analyst工具箱&#xff1a;1.2分析工具箱:1.3制图工具箱:1.4转换工具箱:1.5Data Interoper…

PACS系统源码,大型医院PACS源码集成三维重建

PACS系统为医院提供包括放射、超声、核医学、病理、内窥镜、心电图室在内的所有影像检查数字化的一体化解决方案。 它涵盖了传统PACS和RIS系统的所有功能&#xff0c;以构建全数字化影像科为目标&#xff0c;致力于实现对医院所有影像数据的统一管理、影像检查工作流的自动化&a…

项目连载方式

协议介绍 芯片介绍 读写操作 小熊派驱动系列连载正点原子的代码重新用Cubemx实现协议分析项目制作单片机上云的代码移植可以使用Arduino接管或者使用以太网、或者ESP8266移植开源项目复刻 在小熊派的板子上进行简单的步骤实现&#xff0c;函数分析&#xff0c;在正点原子的…

RUST 每日一省:trait种类

trait的基本形式&#xff0c;很简单&#xff0c;但这只是trait的冰山一角。当你开始接触大型代码库中的trait时&#xff0c;将会遇到它的多种形式。种类繁多有助于我们完成复杂问题的建模。下面我们一次介绍其他形式的trait&#xff0c;以便了解何时需要使用它们。 标准trait …

常见元件、封装、尺寸、表面处理等

参考&#xff1a;https://www.bilibili.com/read/cv11024927?fromsearch&spm_id_from333.337.0.0 参考&#xff1a;https://www.bilibili.com/read/cv18413169?fromsearch&spm_id_from333.337.0.0 目录 通孔插件技术(THT)和表面贴装技术(SMT)封装类型SOP/SOIC封装DIP…