pg数据库能够直接存储json算是一大特色

很多特定情境下使用直接存储json字段数据能够大量节省开发时间,提高后台效率。

具体配置如下所示
库表类型选择

pgsql的json字段java pg json类型_ide

实体类配置

实体类对应类型选择(包:org.json.simple.JSONObject)

JSONObject (存储数据格式json)

或 JSONArray (存储对象格式json)

因为我们知道json有两种类型,所以这里需要区分明确 否则参数接收或者copy赋值时就会类转换错误

pgsql的json字段java pg json类型_pgsql的json字段java_02

xml中映射关系表达

这里不能够想以往一样简单column、property、jdbcType就完事。如下:

pgsql的json字段java pg json类型_json_03


这里需要注意:

1.是JavaType(Java类型) 指向Object 而不是 jdbcType(数据库类型)

2.typeHandler 是我们自定义的转换类型(这里需要我们自己来定义而不能够使用mybatis提供好的类型转换)

如下我们定义的类型转换:

pgsql的json字段java pg json类型_json_04


图中类继承了mybatis的BaseTypeHandler类,表示使用我们规定的类来进行映射赋值。下面是代码

@MappedTypes(Object.class)
public class JSONTypeHandlerPg extends BaseTypeHandler<Object> {

    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 rs.getString(columnName);
    }

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

    @Override
    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex);
    }
}
插入数据语句

pgsql的json字段java pg json类型_ide_05

这里有新的问题,那就是查询时候怎样用?

当我们仍然按着之前定义的实体类来接收json字段,结果就是无法正确赋值(类型不匹配)

通过验证发现

pgsql的json字段java pg json类型_bc_06


将实体类对应json类型定义由JSONObject 改为 Object 即正常接收查询结果

但是这种方法如果再次使用插入我们发现,前台传递的json类型就会被做轻微改变。

最后总结就是我们可以仍然将实体字段类型定位 JSONObject 用来做插入操作

查询时我们可以定义其它类来接收,将json字段类型定义为Object就不会查询报错,

但是需要注意

这里我们使用Object接收数据库查询之后,得到的很可能会是默认字符串,此情况下我们直接响应给调用者就不是标准json了,解析就会很麻烦,所以我们需要区分业务,当前字段到底是JSONObject或是JSONArray,在后端进行转换后再组织响应给调用者。

pgsql的json字段java pg json类型_json_07

关于 String-JSONObject 与 String-JSONArray 的转换

推荐使用fastjson(依赖包较少 比较方便)
下面是依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>

然后我们可以使用包提供的方法进行自由合法转化json

pgsql的json字段java pg json类型_bc_08


当然这里如果不是json数组 我们可以调用JSONObject

pgsql的json字段java pg json类型_bc_09

这里顺便提一句

pg库里json格式有两种 json / jsonb
我们知道两种格式并无实质类型区别(对Java代码不会影响)
唯一区别就是jsonb会对存入进行预处理 致使写入时较慢,读取较快。
而 json 可以说是原木原样存储,所以写入速度较快,读取时可能会更慢。
个人更习惯使用 json。