1. 程式人生 > >PostgreSQL 、springboot 、spring data jpa 整合

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 }
View Code

    2. 配置檔案中宣告使用自己定義的方言 (yml格式)

  

database-platform: com.zxl.postgrespringdemo.config.dialect.JsonbPostgresDialect
View Code

    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); } } }
View Code

    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 }
View Code

    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);
}
View Code

  

  參考過的相關文件與部落格:

  https://blog.csdn.net/carry1beyond/article/details/79568934