文章目录
- 一、在 handle 包下新建Jsonb处理类
- 1. 方式一
- 2. 方式二
- 二、PostgreSQL jsonb类型保存
- 1. 新建数据库表含有jsonb类型
- 2. 创建实体类
- 3. Control创建保存数据库方法
- 4. 发起请求
- 三、PostgreSQL jsonb类型查询
- 1. Control创建查询数据库方法
- 2. 发起请求
一、在 handle 包下新建Jsonb处理类
1. 方式一
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; 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 CSDN @一碗情深 * @description PostgreSql jsonb 数据处理器 **/ @MappedTypes({Object.class}) @MappedJdbcTypes({JdbcType.VARCHAR}) public class JsonbTypeHandler extends AbstractJsonTypeHandler<Object> { private static final PGobject jsonObject = new PGobject(); private final Class<?> type; public JsonbTypeHandler(Class<?> type) { this.type = type; } /** * 重写设置参数 * @param ps * @param i * @param parameter * @param jdbcType * @throws SQLException */ @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { if (ps != null) { jsonObject.setType("jsonb"); jsonObject.setValue(JSON.toJSONString(parameter)); ps.setObject(i, jsonObject); } } /** * 根据列名,获取可以为空的结果 * @param rs * @param columnName * @return * @throws SQLException */ @Override public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { Object v = rs.getObject(columnName); return toFill(v); } /** * 根据列索引,获取可以为空的结果 * @param rs * @param columnIndex * @return * @throws SQLException */ @Override public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException { Object v = rs.getObject(columnIndex); return toFill(v); } @Override public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { Object v = cs.getObject(columnIndex); return toFill(v); } @Override protected Object parse(String json) { return JSON.parseObject(json, this.type); } /** * 必须将 v 转成 PGObject 处理 * @param v * @return */ private Object toFill(Object v) { if (v != null && v instanceof PGobject) { PGobject p = (PGobject) v; String pv = p.getValue(); if (StringUtils.isNotEmpty(pv) && ("jsonb".equals(p.getType()) || "json".equals(p.getType()))) { return parse(p.getValue()); } } return v; } @Override protected String toJson(Object obj) { return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty); } }
复制
2. 方式二
package com.hlta.map.utils; import com.alibaba.fastjson.JSON; 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 CSDN @一碗情深 * @description PostgreSql jsonb 数据处理器 **/ @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)); } }
复制
二、PostgreSQL jsonb类型保存
1. 新建数据库表含有jsonb类型
2. 创建实体类
- 在实体类上加上
@TableName(value = "表名", autoResultMap = true)
- 在jsonb属性上加上
@TableField(value = "字段", typeHandler = JsonbTypeHandler.class)
import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import com.chh.handle.JsonbTypeHandler; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; /** * @author CSDN @一碗情深 */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName(value = "app_control_manage", autoResultMap = true) public class AppControlManage implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 名称 */ @TableField("name") private String name; /** * 关联渠道 */ @TableField("channel") private String channel; /** * 控制项 */ @TableField(value = "content", typeHandler = JsonbTypeHandler.class) private Object content; /** * 说明 */ @TableField("description") private String description; /** * 创建日期 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField(fill = FieldFill.INSERT) private Date createTime; }
复制
3. Control创建保存数据库方法
以下方法用于接收post请求,将数据保存到数据库
@PostMapping("/test") public Object test(@RequestBody JSONObject object, final HttpServletResponse response, final HttpServletRequest request) { AppControlManage appControlManage = object.toJavaObject(AppControlManage.class); boolean save = appControlManageService.save(appControlManage); if (save) { System.out.println("保存成功"); } else { System.out.println("保存失败"); } return appControlManage; }
复制
4. 发起请求
可以看到,json数据被保存进数据库
三、PostgreSQL jsonb类型查询
1. Control创建查询数据库方法
以下方法用于接收get请求,查询数据content字段,其中 #>>
为以文本形式获取在指定路径的 JSON 对象,'{test,0,name}'
可以得到 “test” JSON对象下的下标为0的数组,其中key为 name
所对应的value的文本。以下包含了排序和分页可供参考。
不懂如何操作json/jsonb,可参考博主的另一篇博文:
PostgreSQL 操作json/jsonb
@GetMapping("/select") public Object select(@RequestParam("mpage") Integer mpage, @RequestParam("msize") Integer msize, @RequestParam("msort") String msort, @RequestParam("name") String name) { IPage<AppControlManage> iPage = new LambdaQueryChainWrapper<>(appControlManageMapper) .apply(StringUtil.isNotEmpty(name), "content #>> '{test,0,name}' = {0}", name) .last(StringUtil.isNotEmpty(msort), "order by " + msort) .page(new Page<>(mpage + 1, msize)); return new InfoResult(iPage.getTotal(), iPage.getRecords()); }
复制
2. 发起请求
可以看到,查询到了content字段下的 test
JSON对象下的第一个数组,key为 name
,value为 apple
的数据。