最近有用到postgresql,里面的一个特色数据类型便是jsonb,和json差不多,但是查询比较快,关于概念,这里就提一句,不赘述。
我们先来看下用mybatisplus,首先是查询数据。
依赖:
- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-boot-starterartifactId>
- <version>3.5.1version>
- dependency>
-
- <dependency>
- <groupId>org.mybatis.spring.bootgroupId>
- <artifactId>mybatis-spring-boot-starterartifactId>
- <version>2.2.2version>
- 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
extends Object> extends BaseTypeHandler { -
- 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
extends BaseTypeHandler { -
- 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
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 ? "成功" : "失败");
- }
成功存到数据库中
![]()
-----------------------------------------------------补充完毕--------------------------------------------------------------
测试用例自己写一下,写的比较潦草,因为是临时记录,又是在公司。
如果有任何问题,请在下方留言,或者直接私信我,我看到都会回复!