【SpringBoot】Jpa 关于postgresql中Jsonb字段的存取操作

150 阅读2分钟

工作中用到jpa与pgsql中jsonb字段的存取操作,一般使用方言进行操作,这种方式是全局的方便操作。 方言的配置一般是搭配自定义map进行数据映射操作,且应该放置到公共模块中。

但是如果全局已经定义了一个方言,且已经定义了对应的自定义类型,那么插件模块的jsonb字段要怎么处理呢?

方言

统一的方言设置仍然是正确的解决方式。

具体可参考:【JPA实体类映射PostgreSQL中的jsonb字段

  • 自定义数据类型 xxxMap.java

    public class xxxMap implements Serializable, JsonSerializable {
    
    }
    
  • 自定义类型 xxxJsonType.java

    public class xxxJsonType extends AbstractSingleColumnStandardBasicType<xxxMap>
        implements DiscriminatorType<xxxMap> {
        ···
        ···
        }
    
  • 自定义方言 xxxDialect.java

    public class xxxSqlDialect extends PostgreSQL95Dialect {
    public xxxSqlDialect() {
            super();
            this.registerColumnType(Types.JAVA_OBJECT, "xxxjsonType的路径");
        }
    }
    
  • 实体类用法 entity.java

    @Data
    @Entity
    @Table(name = "test_jsonb_entity")
    @TypeDef(name = "Jsonb", typeClass = xxxType.class) // 自定义类型
    public class TestJsonbEntity {
    
            // 主键...
        private Integer id;
    
        /**
         * jsonb类型的字段
         */
        @Column(columnDefinition = "jsonb")
        @Type(type = "jsonb") // @TypeDef中的name
        private xxxMap xxxJsonb;
    
    }
    
  • application.yml

    spring.jpa:
       database-platform: xxxDialect方言路径  
    

Jpa 自定义SQL的方式

目前遇到的情况是,有一个系统已经有自己的方言,但是并没有单独设置一个共通模块,因此为了不污染环境,使用原生sql进行存取。这种方式非常麻烦,且存取的方式需要进行json的转换操作,推荐使用方言。

  • entity
    // 不需要使用json相关类型
    private String jsonbText;
    
  • 查询操作
    查询使用jpa直接查询即可,查询到的对象字段可以进行string To json的转换。
    jpaRepository.findById(xxx);
    
  • 插入操作
    插入时使用原生sql的方式,先将传入的json对象转为string,再通过sql中的cast函数进行string到jsonb的转换。
    @Modifying
    @Query(nativeQuery=true,
                   value="insert into table "+
                             " (object_content) "+ 
                             " values ( CAST(:#{#object.content} AS jsonb)) ")
    void addObject(@Param("object") Object object);
    

引入hibernate-types依赖

还没有进行尝试,类似将方言抽出一个公共的依赖使用。

详见:【JPA实体类映射PostgreSQL中的jsonb字段】的方式二部分。