项目地址: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;@Overridepublic 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();}}}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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);}@Overridepublic Object assemble(Serializable cached, Object owner) throws HibernateException {return deepCopy(cached);}@Overridepublic Object replace(Object original, Object target, Object owner) throws HibernateException {return deepCopy(original);}@Overridepublic boolean isMutable() {return true;}@Overridepublic int hashCode(Object x) throws HibernateException {if (x == null) {return 0;}return x.hashCode();}@Overridepublic boolean equals(Object x, Object y) throws HibernateException {return ObjectUtils.nullSafeEquals(x, y);}@Overridepublic Class<?> returnedClass() {return jsonClassType;}@Overridepublic int[] sqlTypes() {return new int[]{Types.JAVA_OBJECT};}@Overridepublic 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