SpringBoot + Mybatis + PostgreSQL JSON数据处理

上篇博客的遗留问题:

  • MySQL数据库,存储类型是VARCHAR(255),很容易超出上限。而且在实际项目中使用的是PostgreSQL数据库,有JSON格式的数据类型。

为什么要处理JSON格式的数据类型?

  • 在项目中持久层框架使用的Mybatis,Mybatis并未提供直接处理JSON的相关类,所以需要我们手动创建处理JSON的类,继承BaseTypeHandler。

具体实现:

import com.gotrade.esop.common.JacksonSerializer;
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;

/**
 * @author jason.tang
 * @create 2019-01-29 11:27
 * @description 自定义JsonTypeHandler处理PostgreSQL的JSON数据类型
 */
@MappedTypes({Object.class})
public class JsonTypeHandler extends BaseTypeHandler<Object> {
    //引入PGSQL提供的工具类PGobject
    private static final PGobject jsonObject = new PGobject();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        jsonObject.setType("json");
        jsonObject.setValue(parameter.toString());
        ps.setObject(i, jsonObject);
    }

    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return JacksonSerializer.parseObject(rs.getString(columnName), Object.class);
    }

    @Override
    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return JacksonSerializer.parseObject(rs.getString(columnIndex), Object.class);
    }

    @Override
    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return JacksonSerializer.parseObject(cs.getString(columnIndex), Object.class);
    }
}

注意事项:

  • 一开始使用如果报错找不到PGobject类,请检查pom文件,将runtime注释掉:
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <!-- <scope>runtime</scope> -->
</dependency>
  • 在上篇文章中,我是先将需要监控的对象转成JSON字符串,所以这里的 setNonNullParameter方法直接setValue即可,如果是先直接传入对象,在自定义处理JSON数据类型的类中处理如下:
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
    jsonObject.setType("json");
    jsonObject.setValue(JacksonSerializer.toJSONString(parameter));
    ps.setObject(i, jsonObject);
}
  • 这里用到了JSON字符串与对象的相互转换工具类,请看这里

在Mybatis的xml中使用

<insert id="addAuditLog" parameterType="com.gotrade.autitlog.model.AuditLog">
    <selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="logNum">
        SELECT nextval('seq_audit_log'::regclass) AS logNum
    </selectKey>
    INSERT INTO audit_log (
        log_num, log_table_name, log_type, log_data, src_num, create_dt
    ) VALUES (
        #{logNum}, #{logTableName}, #{logType}, 
        #{logData, typeHandler=com.gotrade.autitlog.common.JsonTypeHandler},
        #{srcNum}, #{createDateTime}
    )
</insert>
  • 这里的log_data在PostgreSQL数据库的类型为JSON类型
  • 在对于的值后面加上typeHandler=com.gotrade.autitlog.common.JsonTypeHandler即可,这就是刚刚自定义处理JSON数据类的全限定名。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 11,079评论 0 4
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    草里有只羊阅读 18,428评论 0 85
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,793评论 1 32
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 9,864评论 1 14
  • 其实 这些话想说很久了 只是找不到合适的时间 合适的理由 更是不知道如何去表达 毕竟我是一个表达能力差的人 其实我...
    林椿贱阅读 1,326评论 0 0