工作中用到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字段】的方式二部分。