Mybatis和Mybatis-Plus对MySQL中json类型处理
1 MySQL中json类型处理
1.1 引言
mysql5.7
开始支持json
类型字段
点击了解MySQL中JSON类型数据操作
1.2 准备建表
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`content` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
1.3 Mybatis
由于 Mybatis
不支持对MySQL
的JSON
类型处理需要另外处理
1.3.1 实体类
package com.test.entity;
import com.alibaba.fastjson.JSONObject;
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private JSONObject content;
}
1.3.2 BaseTypeHandler
此处可以选择实现TypeHandler
接口或者继承BaseTypeHandler
其中的注解:@MappedTypes
和@MappedJdbcTypes
是MyBatis
框架中的注解,用于指定Java类型
和JDBC类型
之间的映射关系:
@MappedTypes
:用于指定Java类型
与数据库中的数据类型之间的映射关系。@MappedJdbcTypes
:用于指定JDBC类型
与Java类型之间的映射关系
package com.test.handler;
import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedTypes(JSONObject.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MySqlJsonHandler extends BaseTypeHandler<JSONObject>{
/**
* 设置非空参数
* @param ps
* @param i
* @param parameter
* @param jdbcType
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i,String.valueOf(parameter.toJSONString()));
}
/**
* 根据列名,获取可以为空的结果
* @param rs
* @param columnName
* @return
* @throws SQLException
*/
@Override
public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
String sqlJson = rs.getString(columnName);
if (null != sqlJson) {
return JSONObject.parseObject(sqlJson);
}
return null;
}
/**
* 根据列索引,获取可以为内控的接口
* @param rs
* @param columnIndex
* @return
* @throws SQLException
*/
@Override
public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String sqlJson = rs.getString(columnIndex);
if (null != sqlJson) {
return JSONObject.parseObject(sqlJson);
}
return null;
}
/**
*
* @param cs
* @param columnIndex
* @return
* @throws SQLException
*/
@Override
public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String sqlJson = cs.getNString(columnIndex);
if (null != sqlJson) {
return JSONObject.parseObject(sqlJson);
}
return null;
}
}
1.3.3 application.yml
在 application.yml
中增加对应配置,把定义的类型转换器注册到mybatis容器中
点击此处了解Mybatis之原理详解
mybatis:
type-handlers-package: com.test.handler #增加此项配置
mybatis.type-handlers-package
是MyBatis
配置文件中的一个属性,用于指定自定义类型处理器的包名。
通过配置mybatis.type-handlers-package
属性,可以让MyBatis
自动扫描指定包下的所有类型处理器,并将其注册到MyBatis
中。这样,在进行数据库操作时,MyBatis
就可以自动使用这些类型处理器进行类型转换,从而简化了开发人员的工作
1.3.4 修改SQL文件
<resultMap id="BaseResultMap" type="com.test.entity.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<!--将json类型的rules字段修改为如下形式-->
<result column="content" property="content" typeHandler="com.test.handler.MySqlJsonHandler" />
</resultMap>
在xml中写sql语句时,需要将使用到 JSON
字段的地方配置,以下以插入为例
<insert id="insertTest" parameterType="com.test.entity.User" >
insert into user (id, name, content)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{content,jdbcType=OTHER,typeHandler=com.test.handler.MySqlJsonHandler})
</insert>
1.4 MybatisPlus
在实体类加上@TableName(autoResultMap = true)
在JSON
字段映射的属性加上@TableField(typeHandler = JacksonTypeHandler.class)
;
1.4.1 实体类
package com.test.entity;
import com.alibaba.fastjson.JSONObject;
@Data
@TableName(value = "user",autoResultMap = true)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
@TableField(value="content",typeHandler = JacksonTypeHandler.class)
private JSONObject content;
}
另外,此处的JacksonTypeHandler
也可以替换成像上面自定义的MySqlJsonHandler
1.4.2 application.yml
如果在实体类中 typeHandler
使用的是 Mybatis-Plus
提供的则不需要在注册到 mybatis-plus
容器中,如果像上面使用类似1.3.2自定义的typeHandler
,则要在配置文件中添加属性:mybatis-plus.type-handlers-package
来指定自定义的 typeHandler
包的位置
点击此处了解Mybatis之原理详解
在 application.yml
中增加对应配置
mybatis-plus:
type-handlers-package: com.test.handler #增加此项配置
1.4.3 SQL文件
如果启动报错:No typehandler found for content....
那么在对应的mapper文件里面对应的JSON字段 添加typeHandler
<resultMap id="BaseResultMap" type="com.test.entity.User">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="content" property="content" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
</resultMap>
在xml
中写sql
语句时,需要将使用到 JSON
字段的地方配置,也要像Mybatis
那样处理
<insert id="insertUser" parameterType="com.test.entity.User">
insert into
user
values(#{id},#{name},#{content,jdbcType=OTHER,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler})
</insert>