文章目录
- 一、在 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
的数据。