PostgreSQL springboot spring data jpa 集成
Posted 朝花不夕拾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL springboot spring data jpa 集成相关的知识,希望对你有一定的参考价值。
项目地址:https://gitee.com/zhxs_code/PostgreSQL_springboot_jpa_demo.git
增删查改都已经实现。
重点部分:
1.定义自己的方言。
1 package com.zxl.postgrespringdemo.config.dialect; 2 3 import org.hibernate.dialect.PostgreSQL94Dialect; 4 import org.hibernate.type.StringType; 5 6 import java.sql.Types; 7 8 public class JsonbPostgresDialect extends PostgreSQL94Dialect { 9 public JsonbPostgresDialect() { 10 super(); 11 registerColumnType(Types.JAVA_OBJECT, "jsonb"); 12 registerHibernateType(Types.ARRAY, StringType.class.getName()); 13 } 14 15 16 }
2. 配置文件中声明使用自己定义的方言 (yml格式)
database-platform: com.zxl.postgrespringdemo.config.dialect.JsonbPostgresDialect
3.编写自己的json转换类型,用来实现json类型与Postgre类型的转换
package com.zxl.postgrespringdemo.config; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import org.hibernate.HibernateException; import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.SerializationException; import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.UserType; import org.postgresql.util.PGobject; import org.springframework.util.ObjectUtils; import java.io.IOException; import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.Properties; public class JsonbType implements UserType, ParameterizedType { private final ObjectMapper mapper = new ObjectMapper(); private static final ClassLoaderService classLoaderService = new ClassLoaderServiceImpl(); public static final String CLASS = "CLASS"; private Class<?> jsonClassType; @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { if (value == null) { st.setNull(index, Types.OTHER); } else { try { st.setObject(index, mapper.writeValueAsString(value), Types.OTHER); } catch (IOException e) { e.printStackTrace(); } } } @Override public Object deepCopy(Object originalValue) throws HibernateException { if (originalValue != null) { try { return mapper.readValue(mapper.writeValueAsString(originalValue), returnedClass()); } catch (IOException e) { throw new HibernateException("Failed to deep copy object", e); } } return null; } @Override public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { PGobject o = (PGobject) rs.getObject(names[0]); if (o.getValue() != null) { return JSON.parseObject(o.getValue(), jsonClassType); } return null; } @Override public Serializable disassemble(Object value) throws HibernateException { Object copy = deepCopy(value); if (copy instanceof Serializable) { return (Serializable) copy; } throw new SerializationException(String.format("Cannot serialize ‘%s‘, %s is not Serializable.", value, value.getClass()), null); } @Override public Object assemble(Serializable cached, Object owner) throws HibernateException { return deepCopy(cached); } @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return deepCopy(original); } @Override public boolean isMutable() { return true; } @Override public int hashCode(Object x) throws HibernateException { if (x == null) { return 0; } return x.hashCode(); } @Override public boolean equals(Object x, Object y) throws HibernateException { return ObjectUtils.nullSafeEquals(x, y); } @Override public Class<?> returnedClass() { return jsonClassType; } @Override public int[] sqlTypes() { return new int[]{Types.JAVA_OBJECT}; } @Override public void setParameterValues(Properties properties) { final String clazz = (String) properties.get(CLASS); if (clazz != null) { jsonClassType = classLoaderService.classForName(clazz); } } }
4.demo实体类
1 /** 2 * 用户demo类 3 */ 4 @Data 5 @AllArgsConstructor 6 @NoArgsConstructor 7 @Entity 8 @Table(name = "user_demo") 9 @TypeDefs({ 10 @TypeDef(name = "infoType", typeClass = JsonbType.class, parameters = { 11 @Parameter(name = JsonbType.CLASS, value = "com.zxl.postgrespringdemo.pojo.UserBaseInfo") 12 }), 13 @TypeDef(name = "addressType", typeClass = JsonbType.class, parameters = { 14 @Parameter(name = JsonbType.CLASS, value = "com.zxl.postgrespringdemo.pojo.Address") 15 }) 16 }) 17 public class UserDemo { 18 19 @Id 20 @GeneratedValue 21 private Long id; 22 23 @Column(columnDefinition = "jsonb") 24 @Type(type = "addressType") 25 private Address address; 26 27 28 @Column(columnDefinition = "jsonb") 29 @Type(type = "infoType") 30 private UserBaseInfo info; 31 }
5. 执行原生的SQL语句
@Repository public interface UserRepository extends JpaRepository<UserDemo, Long> { // postgre 原生sql语句查询。 @Query(value = "select * from user_demo as a where (a.address ->> ‘province‘) = ?1", nativeQuery = true) List<UserDemo> findByAddress_Province(String value); @Query(value = "select * from user_demo as a where (a.info ->> ‘name‘) = ?1", nativeQuery = true) List<UserDemo> findByInfo_Name(String name); }
参考过的相关文档与博客:
https://blog.csdn.net/carry1beyond/article/details/79568934
以上是关于PostgreSQL springboot spring data jpa 集成的主要内容,如果未能解决你的问题,请参考以下文章
使用 Liquibase 的 Spring Boot 未在 Docker 中执行
Docker:Springboot 容器无法连接到 PostgreSql 容器
使用 testcontainers postgresql 进行 Spring 启动测试
Docker/Hibernate/PostgreSQL - 将运行 Hibernate/SpringBoot 应用程序的容器与 postgreSQL 容器不工作连接