记录一次查询jsonb数据上遇到的坑

344 阅读1分钟

前文

在迭代中有一个需求,需要查询一个json数据{"zhansan"{"level":"1","high":"2"}}和一个json数组lisi["1","2","3"]

Postgresql中提供的json数据操作

json数据

操作符右操作数类型描述例子例子结果
->int获得 JSON 数组元素(索引从 0 开始,负整数结束)'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2{"c":"baz"}
->text通过键获得 JSON 对象域'{"a": {"b":"foo"}}'::json->'a'{"b":"foo"}
->>int文本形式获得 JSON 数组元素'[1,2,3]'::json->>23
->>text文本形式获得 JSON 对象域'{"a":1,"b":2}'::json->>'b'2

jsonb数据

操作符右操作数类型描述例子
@>jsonb左边的 JSON 值是否包含顶层右边JSON路径/值项?'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb
<@jsonb左边的JSON路径/值是否包含在顶层右边JSON值中?'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb
?text字符串是否作为顶层键值存在于JSON值中?'{"a":1, "b":2}'::jsonb ? 'b'
由于我选择存储的数据类型是jsonb的,所以我选择‘ @> ’操作符查询key-value形式的json数据,用‘ ? ’操作符查询json数组。

java中xml写相应的查询方法

springboot+mybatis+pg整合

引入依赖

<!--        pgsql依赖-->
      <dependency>
          <groupId>org.postgresql</groupId>
          <artifactId>postgresql</artifactId>
          <version>42.1.1</version>
      </dependency>
<!--       json依赖-->
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.68</version>
      </dependency>
<!--       mybatis依赖-->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.5</version>
      </dependency>

添加handle类

@MappedTypes({Object.class})
public class JsonbTypeHandler extends BaseTypeHandler<Object> {
    private static final PGobject jsonObject = new PGobject();

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
        if (preparedStatement != null) {
            jsonObject.setType("jsonb");
            jsonObject.setValue(JSON.toJSONString(o));
            preparedStatement.setObject(i, jsonObject);
        }
    }

    @Override
    public Object getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return JSON.parse(resultSet.getString(s));
    }

    @Override
    public Object getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return JSON.parse(resultSet.getString(i));
    }

    @Override
    public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return JSON.parse(callableStatement.getString(i));
    }
}

编写相应的sql

出现的问题

mybatis中的xml语句,zhan_san @> #{zhansan,typerHander = com...JsonbTypeHandler}和li_si ? #{lisi}
结果,对于第一种key-value形式的查不出值,第二种显示没有值

如何解决

1.将断点打在handle类中发现传入的数据已经是json所以不需要转换格式;
将JsonbTypeHandler中的jsonObject.setValue(JSON.toJSONString(o))改为jsonObject.setValue(o.tostring);
2.用‘ ?? ’替换‘ ? ’,操作符li_si ?? #{lisi}

参考:postgresql官方中文json操作文档