MyBatis里json型字段到Java类的映射

1.需求描述:
对象中有个属性是非基本数据类型,在DB存储时我们想存的是json格式的字符串,从DB拿出来时想直接映射成目标类型,也即json格式的字符串字段与Java类的相互类型转换。

package com.cmict.oneconstruction.microservice.data.mybatis;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * mapper里json型字段到类的映射。
 * 用法一:
 * 入库:#{jsonDataField, typeHandler=com.adu.spring_test.mybatis.typehandler.JsonTypeHandler}
 * 出库:
 * <resultMap>
 * <result property="jsonDataField" column="json_data_field" javaType="com.xxx.MyClass" typeHandler="com.adu.spring_test.mybatis.typehandler.JsonTypeHandler"/>
 * </resultMap>
 * 集合对象设置
 * <resultMap>
 *  * <result property="jsonDataField" column="json_data_field" javaType="java.util.ArrayList" typeHandler="com.adu.spring_test.mybatis.typehandler.JsonTypeHandler"/>
 *  * </resultMap>
 *
 * 用法二:
 * 1)在mybatis-config.xml中指定handler:
 *      <typeHandlers>
 *              <typeHandler handler="com.adu.spring_test.mybatis.typehandler.JsonTypeHandler" javaType="com.xxx.MyClass"/>
 *      </typeHandlers>
 * 2)在MyClassMapper.xml里直接select/update/insert。
 *
 *
 * @author cao
 * @date 2021/6/24 17:33
 */
public class JsonTypeHandler<T extends Object> 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;
    }
    @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);
    }
    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 {
                return (T) mapper.readValue(content, clazz);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }
    static {
        mapper.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);
        mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    }
}

org.codehaus.jackson 的依赖

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JSON字段存储动态数据时,操作该字段的 SQL 语句需要使用 MySQL 中提供的 JSON 函数。在 MyBatis 中,可以使用 XML 映射文件或注解来编写 SQL 语句,具体操作步骤如下: 1. 创建实体类 首先,需要创建一个实体类来表示包含 JSON字段的表。例如,创建一个名为 `MyEntity` 的实体类: ```java public class MyEntity { private Integer id; private String dynamicData; // getter and setter } ``` 其中,`id` 表示主键字段,`dynamicData` 表示存储动态数据的 JSON字段。 2. 创建 XML 映射文件或注解 使用 XML 映射文件或注解来编写 SQL 语句,操作 `dynamic_data` 字段中的数据。例如,以下是一个使用 XML 映射文件的示例: ```xml <!-- MyEntityMapper.xml --> <mapper namespace="com.example.MyEntityMapper"> <resultMap id="myEntityMap" type="com.example.MyEntity"> <id property="id" column="id"/> <result property="dynamicData" column="dynamic_data" jdbcType="JSON"/> </resultMap> <select id="findById" resultMap="myEntityMap"> SELECT * FROM my_table WHERE id = #{id} </select> <insert id="insert" parameterType="com.example.MyEntity"> INSERT INTO my_table (id, dynamic_data) VALUES (#{id}, #{dynamicData, jdbcType=JSON}) </insert> <update id="update" parameterType="com.example.MyEntity"> UPDATE my_table SET dynamic_data = #{dynamicData, jdbcType=JSON} WHERE id = #{id} </update> </mapper> ``` 以上示例中,定义了一个 `resultMap` 来映射查询结果到 `MyEntity` 实体类,使用 `jdbcType=JSON` 来指定 `dynamicData` 字段的数据类JSON。然后,定义了 `findById`、`insert` 和 `update` 三个 SQL 语句,分别用于查询、插入和更新数据。 如果使用注解来编写 SQL 语句,则可以在实体类中添加对应的注解,例如: ```java public interface MyEntityMapper { @Select("SELECT * FROM my_table WHERE id = #{id}") @Results({ @Result(property = "dynamicData", column = "dynamic_data", jdbcType = JdbcType.JSON) }) MyEntity findById(Integer id); @Insert("INSERT INTO my_table (id, dynamic_data) VALUES (#{id}, #{dynamicData, jdbcType=JSON})") int insert(MyEntity entity); @Update("UPDATE my_table SET dynamic_data = #{dynamicData, jdbcType=JSON} WHERE id = #{id}") int update(MyEntity entity); } ``` 3. 使用 MyBatis 操作数据 最后,在代码中使用 MyBatis 操作数据。例如,以下是一个查询 `MyEntity` 实体类的示例: ```java public class MyService { private final SqlSessionFactory sqlSessionFactory; public MyService(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } public MyEntity findById(Integer id) { try (SqlSession session = sqlSessionFactory.openSession()) { MyEntityMapper mapper = session.getMapper(MyEntityMapper.class); return mapper.findById(id); } } } ``` 在以上示例中,首先创建了一个 `SqlSessionFactory` 对象,用于创建 `SqlSession` 对象和 `MyEntityMapper` 接口的实例。然后,使用 `session.getMapper(MyEntityMapper.class)` 方法获取 `MyEntityMapper` 的实例,并使用 `mapper.findById(id)` 方法执行查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值