Mybatis&MybatisPlus 操作 jsonb 格式数据

2023-09-18 18:03:07

最近有用到postgresql,里面的一个特色数据类型便是jsonb,和json差不多,但是查询比较快,关于概念,这里就提一句,不赘述。

我们先来看下用mybatisplus,首先是查询数据。

依赖:

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

然后数据库:

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name TEXT,
    age INTEGER,
    address JSONB
);

INSERT INTO employees (name, age, address) VALUES
  ('Alice', 25, '{"city": "New York", "street": "123 Main St"}'),
  ('Bob', 30, '{"city": "San Francisco", "street": "456 Elm St"}'),
  ('Charlie', 35, '{"city": "Seattle", "street": "789 Oak St"}'),
  ('David', 28, '{"city": "Chicago", "street": "678 Walnut St"}'),
  ('Eve', 27, '{"city": "Los Angeles", "street": "234 Pine St"}'),
  ('Frank', 32, '{"city": "Boston", "street": "345 Maple St"}'),
  ('Grace', 29, '{"city": "Austin", "street": "567 Birch St"}');

前面的都无所谓,主要来看实体类,实体类中有两个地方注意:

因为是用的MP,所以在这里直接就注解上配置了  (这里是为了扩展性,所以才自定义的,其实在MP中,是自带了TypeHandler 的,有Gson,FastJson等等

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;

/**
 * @Description:
 * @Author Jack_Lee
 * @Date 2023/9/18 11:30
 */
@MappedTypes(Object.class)
public class JsonTypeHandlerObject<T extends Object> extends BaseTypeHandler<T> {

    private static final PGobject jsonObject = new PGobject();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        jsonObject.setType("jsonb");
        jsonObject.setValue(JSON.toJSONString(parameter));
        ps.setObject(i, jsonObject);
    }

    @Override
    public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
        return (T) resultSet.getString(columnName);

    }

    @Override
    public T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        return (T) resultSet.getString(columnIndex);

    }

    @Override
    public T getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        return (T) callableStatement.getString(columnIndex);
    }
}

添加TypeHandler,用于类型处理,这个应该不陌生,如有不知道这个的小伙伴,可以去温习一下mybatis相关知识。

定义mapper,这个不用说,最基本的

再来看下Mybatis的,mybatis不像plus,很多都要手动进行配置

先定义一个resultMap,然后在字段上指定TypeHandler即可

<mapper namespace="com.jack.mapper.EmployeesMapper">

    <resultMap id="EmployeesMap" type="com.jack.entity.Employees">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <result column="address" property="address" typeHandler="com.jack.handler.JsonTypeHandlerObject"/>
    </resultMap>
    
    <select id="findList"  resultMap="EmployeesMap">
        select * from employees;
    </select>

</mapper>

然后再写个测试类自己测一下,这里不多说

重点说一下插入数据

以mybatis为例,先在mapperx.xml中定义好
 

<insert id="insertEmp" parameterType="com.jack.entity.Employees">
        insert into employees values (#{id}, {name}, {age}, {address,jdbcType=OTHER,typeHandler=com.jack.handler.JsonTypeHandlerObject})
    </insert>
@Mapper
public interface EmployeesMapper {

    int insertEmp();
}

--------------------------------------------------------------------------------------------------------------------------------

补充:如果要存的话,建议还是用Map进行存取,因为刚好也是键值对,比较方便,下面是我自定义的TypeHandler

@MappedTypes(Map.class)
public class JsonTypeHandlerMap<T> extends BaseTypeHandler<T> {

    private static final PGobject pgObject = new PGobject();

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, T parameter, JdbcType jdbcType) throws SQLException {
        pgObject.setType("jsonb");
        pgObject.setValue(JSON.toJSONString(parameter));
        preparedStatement.setObject(i, pgObject);
    }

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

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

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

 同样在实体类中指定或者在mapper.xml 中进行指定即可。

然后去测试:

@Test
    public void TestUsersInsert(){
        Users users = new Users();
        users.setId(13);
        users.setName("zhangsan");
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","测试1111");
        map.put("age","测2222");
        System.out.println("---------------------------->>>>     "+ map);
        users.setAddress(map);
        int insert = usersMapper.insert(users);
        System.out.println(insert > 0 ? "成功" : "失败");
    }

 成功存到数据库中

-----------------------------------------------------补充完毕--------------------------------------------------------------

测试用例自己写一下,写的比较潦草,因为是临时记录,又是在公司。

如果有任何问题,请在下方留言,或者直接私信我,我看到都会回复!

更多推荐

怎么将视频压缩变小?

&nbsp;&nbsp;怎么将视频压缩变小?随着互联网行业的额不断进步和短视频平台的日益流行,视频文件已经成为我们生活不可或缺的一部分。然而,在使用视频文件的过程中,我们可能会遇到一个棘手的问题:视频文件过大,无法轻松地进行传输或存储。文件过大是视频使用过程中不可避免的事情,尤其是现在拍摄设备的愈发先进,让拍摄的视频越

Java + Selenium + Appium自动化测试

一、启动测试机或者Android模拟器(Genymotion俗称世界上最快的模拟器,可自行百度安装)二、启动Appium(Appium环境安装可自行百度)三、安装应用到Genymotion上,如下图我安装一个计算机的小应用,包名为CalcTest.apk安装步骤:(基于AndroidSDK已经配置好了环境变量,可自行百

Linux Ubuntu命令行快速配置C++开发环境

本文介绍在Linux操作系统的Ubuntu版本中,基于命令行,快速配置C++编辑、编译、运行的代码开发环境的简便方法。在之前的文章Linux操作系统Ubuntu22.04配置VisualStudioCode与C++代码开发环境的方法(https://blog.csdn.net/zhebushibiaoshifu/art

7.4.4 【MySQL】索引字符串值的前缀

我们知道一个字符串其实是由若干个字符组成,如果我们在MySQL中使用utf8字符集去存储字符串的话,编码一个字符需要占用1~3个字节。假设我们的字符串很长,那存储一个字符串就需要占用很大的存储空间。在我们需要为这个字符串列建立索引时,那就意味着在对应的B+树中有这么两个问题:B+树索引中的记录需要把该列的完整字符串存储

DP4306F—Sub-1G无线收发通信芯片

DP4306F是一款高性能低功耗的单片集成收发机,工作频率可覆盖200MHz~1000MHz,集成M0核MCU,支持230/408/433/470/868/915频段。该芯片集成了射频接收器、射频发射器、频率综合器、GFSK调制器、GFSK解调器等功能模块。通过SPI接口可以对输出功率、频道选择以及数据包格式进行灵活配

从Langchain到ReAct,在大模型时代下全新的应用开发核心

简介:什么是ReAct框架关于什么是langchain,可以参考:https://ata.alibaba-inc.com/articles/266839?spm=ata.23639420.0.0.1dea7536uD7yhh在使用langchain的过程中,大模型给人留下最深刻的印象无疑是Agent功能。大模型会自己分

hive操作

Hive启动类功能说明命令启动hiveserver2服务bin/hiveserver2启动beelinebin/beeline连接hiveserver2beeline>!connectjdbc:hive2://hadoop102:10000metastroe服务bin/hive--servicemetastorehiv

【EI会议】第二届声学,流体力学与工程国际学术会议(AFME 2023)

第二届声学,流体力学与工程国际学术会议20232ndInternationalConferenceonAcoustics,FluidMechanicsandEngineering(AFME2023)声学、流体力学两个古老的学科发展至今,无时无刻都在影响着我们的生活。小到日常使用的耳机、风扇,大到制造的轮船、飞机。时代发

学习记忆——宫殿篇——记忆宫殿——记忆桩——单间+客厅+厨房+厕所+书房+院子

文章目录单间客厅厨房厕所书房院子单间水壶水龙头香皂果汁机电视门空间花红酒葡萄不锈钢白毛沙发彩色垫子吉他皮椅挂画风扇糖抱枕盒子花土水晶腿衣柜笔三环相框水壶壁挂台灯被网球拍足球抽屉闹钟蝴蝶心斑马三轮车音响椅子碗玩偶烟灰缸电视窗帘玻璃上铺镜子壁灯枕头电话纸盘鱼长方形镜子垃圾桶电视柜地板砖折叠凳窗帘挂坠毯子竹节式台灯台灯床头床

如何利用好Twitter的功能进行营销

虽然Twitter不是最复杂的社交网络,但您需要了解其中的一些特性和功能。这些是我们进行基本操作的地方。您进行探索并想出更多有创意的方式来使用这些功能。推文。推文是您可以分享的帖子和更新,限制在140个字符内。每一条推文都有存档,您可以查看自己和其他用户的推文。通过浏览其他用户的近期推文,您可以更好地了解他们关注的话题

SpringCLoud——docker中的数据卷

数据卷容器与数据耦合的问题不便于修改当我们要改Nginx的HTML内容时,需要进入容器内部修改,很不方便。数据不可复用在容器内的修改对外是不可见的。所有修改对新的容器是不可复用的。升级维护困难数据在容器内,如果要升级容器必然删除旧容器,所有数据都跟着删除了。数据卷(Volume)是一个虚拟目录,指向宿主机文件系统中的某

热文推荐