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

  

 

以上是关于PostgreSQL springboot spring data jpa 集成的主要内容,如果未能解决你的问题,请参考以下文章

使用 Liquibase 的 Spring Boot 未在 Docker 中执行

Docker:Springboot 容器无法连接到 PostgreSql 容器

使用 testcontainers postgresql 进行 Spring 启动测试

Docker/Hibernate/PostgreSQL - 将运行 Hibernate/SpringBoot 应用程序的容器与 postgreSQL 容器不工作连接

vue3+SpringBoot+postgresql 项目前后端传参

将非容器本地 PostgreSQL 连接到本地 SpringBoot docker 容器