Spring Data JDBC下如何将实体以JSONB类型存入PostgreSQL数据库
解决Spring Data JDBC中String转PostgreSQL jsonb的问题
方案一:自定义类型转换器(推荐)
Spring Data JDBC支持通过Converter接口实现类型映射,我们可以编写两个转换器分别处理Java String转PostgreSQL jsonb和jsonb转String的逻辑:
- 实现转换器类
import org.postgresql.util.PGobject; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; // 写入数据库时:String转jsonb @WritingConverter public class StringToJsonbConverter implements Converter<String, PGobject> { @Override public PGobject convert(String source) { PGobject pgObject = new PGobject(); pgObject.setType("jsonb"); try { pgObject.setValue(source); } catch (Exception e) { throw new IllegalArgumentException("字符串转JSONB失败", e); } return pgObject; } } // 读取数据库时:jsonb转String @ReadingConverter public class JsonbToStringConverter implements Converter<PGobject, String> { @Override public String convert(PGobject source) { return source.getValue(); } }
- 注册转换器到Spring配置
创建JDBC配置类,继承AbstractJdbcConfiguration并注册自定义转换器:
import org.springframework.context.annotation.Configuration; import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration; import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; import org.springframework.data.convert.JdbcCustomConversions; import java.util.List; @Configuration @EnableJdbcRepositories public class JdbcConfig extends AbstractJdbcConfiguration { @Override protected JdbcCustomConversions jdbcCustomConversions() { return new JdbcCustomConversions(List.of( new StringToJsonbConverter(), new JsonbToStringConverter() )); } }
完成后Spring Data JDBC会自动处理String与jsonb的转换,原实体类无需修改。
方案二:直接使用PGobject作为实体属性
将实体类中的content字段类型改为PostgreSQL的PGobject,手动指定类型为jsonb:
修改实体类:
import lombok.AllArgsConstructor; import lombok.Data; import org.postgresql.util.PGobject; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Table; @Data @AllArgsConstructor @Table(name = "my_files") public class MyFile { // 修正Java类名规范 @Id private Long id; private PGobject content; }
使用示例:
PGobject jsonbContent = new PGobject(); jsonbContent.setType("jsonb"); jsonbContent.setValue("{\"key\": \"demo-value\"}"); // 传入合法JSON字符串 MyFile file = new MyFile(1L, jsonbContent); fileRepository.save(file);
这种方式无需编写转换器,但实体类直接依赖PostgreSQL API,耦合度较高。
方案三:手动编写带CAST的SQL(临时应急)
在Repository接口中通过@Query手动编写SQL,显式将字符串转为jsonb:
import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; public interface MyFileRepository extends CrudRepository<MyFile, Long> { @Modifying @Query("INSERT INTO my_files (id, content) VALUES (:id, CAST(:content AS jsonb))") void saveFile(Long id, String content); }
该方式无需修改实体类,但每个涉及jsonb的操作都要手动写SQL,灵活性较差,适合临时解决单一场景问题。
内容的提问来源于stack exchange,提问作者Dmitrii Nuvakhov
相关产品推荐
相关产品推荐

