首页 前端知识 MyBatis-Plus 实现PostgreSQL数据库jsonb类型的保存与查询

MyBatis-Plus 实现PostgreSQL数据库jsonb类型的保存与查询

2024-09-21 21:09:52 前端知识 前端哥 259 179 我要收藏

文章目录

  • 一、在 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类型

新建数据库表含有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. 发起请求

post请求

可以看到,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. 发起请求

get请求

可以看到,查询到了content字段下的 test JSON对象下的第一个数组,key为 name ,value为 apple 的数据。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18458.html
评论
发布的文章

javascript jQuery

2024-09-21 22:09:33

【若依】表格固定列宽

2024-09-21 22:09:30

Knockout-jQueryUI 使用指南

2024-09-21 22:09:29

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!