Mybatis 原生JSON类型字段处理

1. mysql 字段类型为json数据处理

1.1 配置文件配置json数据类型处理类,并自定义json处理类

package com.dahua.evo.attendance.handler;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
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;

/**
 * @author fuwu314
 * @describe:mysqlJson类型处理类
 * @date 2024/9/18
 */
public class MySqlJsonHandler <T extends Object> extends BaseTypeHandler<T> {

    private static final ObjectMapper mapper = new ObjectMapper();
    private Class<T> clazz;
    public MySqlJsonHandler(Class<T> clazz) {
        if (clazz == null) throw new IllegalArgumentException("Type argument cannot be null");
        this.clazz = clazz;
    }

    static {
//        mapper.configure(JsonParser.Feature.WRITE_NULL_MAP_VALUES, false);
        mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, this.toJson(parameter));
    }
    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return this.toObject(rs.getString(columnName), clazz);
    }
    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.toObject(rs.getString(columnIndex), clazz);
    }
    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.toObject(cs.getString(columnIndex), clazz);
    }

    /**
     * 将字符串内容转换为指定类型的对象
     *
     * @param content 字符串内容
     * @param clazz   目标类型
     * @return 目标类型的对象
     */
    private T toObject(String content, Class<?> clazz) {
        if (content != null && !content.isEmpty()) {
            try {
                return (T) mapper.readValue(content, clazz);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }

    /**
     * 将对象转换为JSON字符串
     *
     * @param object 要转换的对象
     * @return JSON字符串
     * @throws RuntimeException 如果转换过程中发生异常
     */
    private String toJson(T object) {
        try {
            return mapper.writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}
配置文件:
mybatis.type-handlers-package=com.dahua.evo.attendance.handler

1.2实体类正常注解,mapper.xml  文件注明字段处理类

实体类:
@Data
@TableName(value = "inspect_classes")
public class InspectClasses implements Serializable {

	private static final long serialVersionUID = 6888405245126579026L;

	/**
	 * 主键 -2休班
	 */
	@TableId(value="ID", type= IdType.AUTO)
	private Long id;

	/**
	 * 班次名称
	 */
	@TableField("CLASSES_NAME")
	private String classesName;

	/**
	 * 绑定颜色
	 */
	@TableField("COLOUR")
	private String colour;

	/**
	 * 班次类型, 1-固定班 2-弹性班 3-签到班 4-休班
	 */
	@TableField("TYPE")
	private Integer type;

	/**
	 * 备注
	 */
	@TableField("MEMO")
	private String memo;

	/**
	 * 系统默认 1-是 0-否 系统默认不允许删除 默认为否
	 */
	@TableField("SYS_DEFAULT")
	private Integer sysDefault;

	/**
	 * 是否删除, 逻辑删除 1-是 0-否
	 */
	@TableField("IS_DELETE")
	private Integer isDelete;

	/**
	 * 创建时间
	 */
	@TableField("CREATE_TIME")
	private Date createTime;

	/**
	 * 更新时间
	 */
	@TableField("UPDATE_TIME")
	private Date updateTime;

	/**
	 * 记录所属用户组织编码
	 */
	@TableField("ORG_CODE")
	private String orgCode;
	/**
	 * 餐补规则(json类型)
	 */
	@TableField(value="MEAL_ALLOWANCE")
	private List<ClasseMealAllowance> classeMealAllowanceList;



	public InspectClasses() {

	}

	public InspectClasses(Long id, String classesName) {
		this.id = id;
		this.classesName = classesName;
	}
}

xml文件:
<?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.dahua.evo.attendance.business.mapper.classes.ClassesMapper">

	<!-- 通用查询映射结果 -->
	<resultMap id="BaseResultMap" type="com.dahua.evo.attendance.business.domain.classes.InspectClasses">
		<id column="ID" property="id" />
		<result column="CLASSES_NAME" property="classesName" />
		<result column="COLOUR" property="colour" />
		<result column="TYPE" property="type" />
		<result column="MEMO" property="memo" />
		<result column="SYS_DEFAULT" property="sysDefault" />
		<result column="IS_DELETE" property="isDelete" />
		<result column="CREATE_TIME" property="createTime" />
		<result column="UPDATE_TIME" property="updateTime" />
		<result column="ORG_CODE" property="orgCode" />
		<result column="MEAL_ALLOWANCE" property="classeMealAllowanceList" typeHandler="com.dahua.evo.attendance.handler.MySqlJsonHandler" />
	</resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        ID AS id, CLASSES_NAME AS classesName, COLOUR AS colour, TYPE AS type, MEMO AS memo, SYS_DEFAULT AS sysDefault,
        IS_DELETE AS isDelete, CREATE_TIME AS createTime, UPDATE_TIME AS updateTime, ORG_CODE AS orgCode,
		MEAL_ALLOWANCE AS mealAllowanceList
    </sql>



	<select id="selectListByCondition" resultType="com.dahua.evo.attendance.business.vo.classes.ClassesVo">
		SELECT
		<include refid="Base_Column_List" />
		FROM inspect_classes
		<where>
			AND IS_DELETE = 0
			<if test="searchKey != null and searchKey != ''">
				AND instr(CLASSES_NAME,#{searchKey}) > 0
			</if>
			<if test="queryDefault != null">
				AND SYS_DEFAULT = #{queryDefault}
			</if>
			<if test="ownerCode != null and ownerCode != ''">
				AND ORG_CODE LIKE CONCAT(#{ownerCode}, '%')
			</if>
		</where>
		ORDER BY UPDATE_TIME DESC
	</select>
<!--	查询sql -->
	<select id="getClassById" resultMap="BaseResultMap">
		SELECT * FROM inspect_classes where ID =#{classesId}
	</select>
	<!--新增sql -->
	<insert id="insertClass"
			useGeneratedKeys="true" keyProperty="id"
			parameterType="com.dahua.evo.attendance.business.domain.classes.InspectClasses">
		insert into inspect_classes (CLASSES_NAME, COLOUR,TYPE,MEMO,CREATE_TIME,UPDATE_TIME,ORG_CODE,MEAL_ALLOWANCE)
		values (#{classesName,jdbcType=VARCHAR}, #{colour,jdbcType=VARCHAR},#{type,jdbcType=INTEGER},#{memo,jdbcType=VARCHAR},
		#{createTime,jdbcType=VARCHAR},#{updateTime,jdbcType=TIMESTAMP},#{orgCode,jdbcType=VARCHAR},
		#{classeMealAllowanceList,jdbcType=OTHER,typeHandler=com.dahua.evo.attendance.handler.MySqlJsonHandler})
	</insert>
	<!-- 更新sql -->
	<update id="updateClassById" parameterType="com.dahua.evo.attendance.business.domain.classes.InspectClasses">
		UPDATE `evo_attendance`.`inspect_classes`
		SET `CLASSES_NAME` = #{classesName,jdbcType=VARCHAR}, `COLOUR` = #{colour,jdbcType=VARCHAR}, `TYPE` = #{type,jdbcType=INTEGER},
		 `MEMO` = #{memo,jdbcType=VARCHAR}, `SYS_DEFAULT` = #{sysDefault,jdbcType=VARCHAR},
		 `UPDATE_TIME` = #{updateTime,jdbcType=VARCHAR}, `ORG_CODE` = #{orgCode,jdbcType=VARCHAR},
		 `MEAL_ALLOWANCE` = #{classeMealAllowanceList,jdbcType=OTHER,typeHandler=com.dahua.evo.attendance.handler.MySqlJsonHandler}
		WHERE `ID` = #{id,jdbcType=INTEGER};
	</update>
    <insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `evo_custom`.`smart_brain_project`(`TYPE`, `TYPE_NAME`, `DETAIL_INFO`, `CREATE_DATETIME`,
        `CREATE_USER_ID`, `UPDATE_TIME`, `UPDATE_USER_ID`)
        VALUES
        <foreach item="item" collection="projects" separator="," open="" close="" index="">
            ( #{item.type,jdbcType=VARCHAR }, #{item.typeName,jdbcType=VARCHAR },
            #{item.detailInfo, jdbcType=OTHER,typeHandler=com.dahua.evo.custom.handler.MySqlJsonHandler}, now (), now
            (), #{item.createUserId }, #{item.updateUserId })
        </foreach>
    </insert>
</mapper>

2.  mysql  json数据查询:

参考链接:https://blog.youkuaiyun.com/hollycloud/article/details/142375951

1    test01    {"obj": {"title": "工程师"}, "name": "研发部", "colors": ["red", "blue"]}
2    test02    {"jobs": [{"name": "经理"}, {"name": "工程师"}], "name": "研发部"}
3    test03    {"name": "行政部"}
4    test04    [{"name": "研发部"}, {"name": "工程部"}]

2.1 查询extend里面name等于研发部的数据
查询语句跟普通的sql语句差不多,也就是字段名要用到path表达式

查询sql: select * from test_my_json where extend  ->'$.name' = '研发部'

模糊查:select * from test_my_json where extend  ->'$.name' like '%研发部%'

sql结果:

2.2  查询extend里面obj.title等于工程师的数据
select * from test_my_json where extend  ->'$.obj.title' like '%工程师%'

2.3查询colors包含red的数据
需要用到json_contains函数,第一个参数是表的字段名,第二个参数是要查询的值,如果是字符串需要用双引号,第三个参数是path路径
select * from test_my_json where   JSON_CONTAINS(extend,'"red"', '$.colors') 

2.4查询jobs里面的name包含经理的数据
select * from test_my_json  where extend->'$.jobs[*].name' like '%经理%'

2.4.1 精确匹配
select * from test_my_json where JSON_CONTAINS(extend->'$.jobs[*].name','"经理"')

3.

Mybatis中javaType和jdbcType对应关系
JDBC TypeJava Type
BITboolean / Boolean
TINYINTbyte / Byte
SMALLINTshort / Short
INTEGERint / Integer
BIGINTlong / Long
REALfloat / Float
FLOATdouble / Double
DOUBLEdouble / Double
NUMERICjava.math.BigDecimal
DECIMALjava.math.BigDecimal
CHARString
VARCHAR / VARCHAR 2String
LONGVARCHARString
DATEjava.sql.Date
TIMEjava.sql.Time
TIMESTAMPjava.sql.Timestamp (在较新版本中推荐使用java.time.LocalDateTime)
BINARYbyte[]
VARBINARYbyte[]
LONGVARBINARYbyte[]
CLOBjava.sql.Clob
NCLOBjava.sql.NClob
BLOBjava.sql.Blob
BOOLEANboolean / Boolean
OTHER依赖于数据库特定类型(如:java.sql.Struct, java.sql.Array等)
NULL不适用于基本映射,但在某些特殊情况下可能有用
VARCHAR_IGNORECASE同 VARCHAR,但某些数据库驱动可能支持大小写不敏感比较
UNICODE_STREAM字符流,用于处理Unicode字符数据
BINARY_STREAM二进制流,用于处理二进制数据

注意:并非所有的JDBC类型在所有数据库系统中都有完全一致的实现,因此具体映射可能会因数据库驱动而异。参考链接:深入理解MyBatis中的javaType与jdbcType及其应用场景_mybatis javatype-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值