【spring data jpa】实现postgresql的jsonb属性映射

1,558 阅读1分钟

一、新建断言类

public class JsonbPostgresDialect extends PostgreSQL95Dialect {
    public JsonbPostgresDialect() {
        this.registerColumnType(Types.JAVA_OBJECT, "jsonb");
    }
}
spring:
  jpa:
    show-sql: false
    hibernate:
      ddl-auto: none
    database-platform: POSTGRESQL
    properties:
      hibernate:
        dialect: com.gass.nuctech.hibernate.JsonbPostgresDialect  ## 自定义断言
        enable_lazy_load_no_trans: true

二、创建类型

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.SerializationException;
import org.hibernate.usertype.UserType;
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;

public class JsonbType implements UserType {

   @Override
    public Object deepCopy(Object originalValue) throws HibernateException {
        if (originalValue == null) {
            return null;
        }
        return originalValue;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
        final String json = rs.getString(names[0]);
        if (json == null) {
            return null;
        }
        return JSONObject.parseObject(json);

    }

    @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 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, value.toString(), Types.OTHER);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        return ObjectUtils.nullSafeEquals(x, y);
    }

    @Override
    public Class<?> returnedClass() {
        return JSONObject.class;
    }

    @Override
    public int[] sqlTypes() {
        return new int[]{Types.JAVA_OBJECT};
    }
}

实体类

@Data
@Entity
@Table(schema = "business", name = "three_d_door")
@TypeDef(name = "JsonbType", typeClass = JsonbType.class)
public class ThreeDDoor {
    @Column(columnDefinition = "jsonb")
    @Type(type = "JsonbType")
    private JSONObject similarityPerson;
}