赞
踩
在 Springboot 项目开发中,一般使用关系型数据库作为主库存储数据,有时候业务场景需要在既有的表结构上,扩展自定义业务信息。这种场景下一般使用json类型存储。本文总结 Springboot 项目中,借助 Mybatis-plus 操作json实践方案。
Spring boot + Mybatis-plus + PostgreSQL,在 PostgreSQL 数据库中某一个字段为 json 类型。
在 MyBatis 中,类型处理器(TypeHandler)扮演着 JavaType 与 JdbcType 之间转换的桥梁角色。它们用于在执行 SQL 语句时,将 Java 对象的值设置到 PreparedStatement 中,或者从 ResultSet 或 CallableStatement 中取出值。
MyBatis-Plus 给大家提供了提供了一些内置的类型处理器,可以通过 TableField
注解快速注入到 MyBatis 容器中,从而简化开发过程。MyBatis-Plus 字段类型处理器官方参考文档:字段类型处理器 | MyBatis-Plus (baomidou.com)
JSON 字段类型处理器
MyBatis-Plus 内置了多种 JSON 类型处理器,包括 AbstractJsonTypeHandler
及其子类 Fastjson2TypeHandler
、FastjsonTypeHandler
、GsonTypeHandler
、JacksonTypeHandler
等。这些处理器可以将 JSON 字符串与 Java 对象相互转换。
PostgreSQL 数据库字段如上图所示:param_config 是一个 json 类型的字段。
步骤一:DO实体写法
字段数据类型为 com.alibaba.fastjson2.JSONObject 。
@Data @Accessors(chain = true) @TableName(autoResultMap = true) public class User { private Long id; ... /** * 关键代码!!! * 必须开启映射注解 * * @TableName(autoResultMap = true) * * 选择对应的 JSON 处理器,并确保存在对应的 JSON 解析依赖包 */ @TableField(value = "param_config", typeHandler = JacksonTypeHandler.class) // 或者使用 FastjsonTypeHandler // @TableField(typeHandler = FastjsonTypeHandler.class) private JSONObject paramConfig; }
步骤二:XML 配置对应写法
<!-- 关键代码!!!!!!! -->
<!-- 单个字段的类型处理器配置 -->
<result column="param_config" jdbcType="VARCHAR" property="paramConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
<!-- 多个字段中某个字段的类型处理器配置 -->
<resultMap id="departmentResultMap" type="com.baomidou...DepartmentVO">
<result property="director" column="director" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
</resultMap>
<select id="selectPageVO" resultMap="departmentResultMap">
select id,name,director from department ...
</select>
查看保存在数据库中的结果,如下图所示:
先在 PostgreSQL 的数据库 URL 后面加上 &stringtype=unspecified,注意,如果此配置前面直接是数据库名字,则需要将 & 换成 ? 。
步骤一:DO实体类写法
@TableField(value = "param_config", typeHandler = JacksonTypeHandler.class)
private String paramConfig;
步骤二:XML 配置对应写法
<!-- 单个字段的类型处理器配置 -->
<result column="param_config" jdbcType="VARCHAR" property="paramConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
查看保存在数据库中的结果,如下图所示:
在 MyBatis-Plus 中,除了使用内置的类型处理器外,开发者还可以根据需要自定义类型处理器。
例如,当使用 PostgreSQL 数据库时,可能会遇到 JSON 类型的字段,这时可以创建一个自定义的类型处理器来处理 JSON 数据。
以下是一个自定义的 JSON 类型处理器的示例:
package com.ruoyi.common.utils.pg; import com.ruoyi.common.utils.StringUtils; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes; import org.postgresql.util.PGobject; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @ClassName: JsonTypeHandlerPg * @Description: json对象处理 * @Author: hjm * @Date: 2024-07-11 10:34 */ @MappedTypes(String.class) public class JsonTypeHandlerPg extends BaseTypeHandler<String> { /** * 引入PGSQL提供的工具类PGobject */ private static final PGobject JSON_OBJECT = new PGobject(); public static final String JSON_TYPE = "json"; /** * 关键位置!!! */ @Override public void setNonNullParameter(PreparedStatement ps, int i, String param, JdbcType jdbcType) throws SQLException { JSON_OBJECT.setType(JSON_TYPE); JSON_OBJECT.setValue(param); ps.setObject(i, JSON_OBJECT); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String sqlJson = rs.getString(columnName); if (StringUtils.isNotBlank(sqlJson)) { return sqlJson; } return null; } // 根据列索引,获取可以为空的结果 @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String sqlJson = rs.getString(columnIndex); if (StringUtils.isNotBlank(sqlJson)) { return sqlJson; } return null; } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String sqlJson = cs.getString(columnIndex); if (StringUtils.isNotBlank(sqlJson)) { return sqlJson; } return null; } }
在实体类中,通过 TableField
注解指定自定义的类型处理器:
/** * 测试对象 * * @author hjm * @date 2024-07-11 */ @Data @EqualsAndHashCode(callSuper = true) @TableName("data_test") public class DataTest extends BaseEntity { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id") private Long id; /** * 关键位置!!! */ @TableField(typeHandler = JsonTypeHandlerPg.class) private String jsonData; }
修改mapper文件
<?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.ruoyi.dt.mapper.DataTestMapper"> <resultMap type="com.ruoyi.dt.domain.DataTest" id="DataTestResult"> <result property="id" column="id"/> <!-- 关键位置!!! --> <result property="jsonData" column="json_data" typeHandler="com.ruoyi.common.utils.pg.JsonTypeHandlerPg"/> <result property="createBy" column="create_by"/> <result property="createTime" column="create_time"/> <result property="updateBy" column="update_by"/> <result property="updateTime" column="update_time"/> </resultMap> </mapper>
业务代码
/** * 新增数据 */ @Override public Boolean insertByAo(DataTestAo ao) { DataTest add = BeanUtil.toBean(ao, DataTest.class); // 关键位置!!! add.setJsonData(JSONUtil.toJsonStr(ao)); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { ao.setId(add.getId()); } return flag; }
本文完结!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。