Spring Data JPA與PostgreSQL的jsonb類型集成與支持
在我們項目中經常會遇到數據結構不定的情況,這時普通的關係型資料庫不能滿足我們的要求。Postgres為我們提供了jsonb
數據類型,我們可在此類型的欄位存儲json
數據,並可對此數據進行查詢。本例將結合hibernate
,Spring Data JPA
,Spring Boot
來實現。
public class JsonbPostgresDialect extends PostgreSQL94Dialect {
public JsonbPostgresDialect {
this.registerColumnType(Types.JAVA_OBJECT,"jsonb");
}
}
指定方言
spring.jpa.database-platform: com.example.jpajsonb.support.JsonbPostgresDialect
2. 自定義jsonb數據類型
這裡主要實現了Map
映射PGObject
(postgres對象類型),通過ObjectMapper
來實現兩個數據類型的轉換。
public class JsonbType implements UserType{
private final ObjectMapper mapper = new ObjectMapper;;
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor 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, SessionImplementor session, Object owner) throws HibernateException, SQLException {
PGobject o = (PGobject) rs.getObject(names[0]);
if (o.getValue != null) {
try {
return mapper.readValue(o.getValue,Map.class);
}catch (IOException e){
e.printStackTrace;
}
}
return new HashMap
}
@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 Map.class;
}
@Override
public int sqlTypes {
return new int{Types.JAVA_OBJECT};
}
}
3. 聲明使用
先定義數據類型,再在欄位上使用
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@TypeDef(name = "JsonbType", typeClass = JsonbType.class)
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(columnDefinition = "jsonb")
@Type(type = "JsonbType")
private Map
}
4.Repository
通過postgres
原生sql語句查詢,本例含義為json
數據info
的一個key
為name
的值等於。具體的JSON的sql查詢方式請參考:
public interface PersonRepository extends JpaRepository
@Query(value = "select * from person where info ->> "name" = :name" , nativeQuery = true)
List
}
5. 保存和讀取測試
@Bean
CommandLineRunner saveAndReadJsonb(PersonRepository personRepository){
return e -> {
Person p = new Person;
Map m = new HashMap;
m.put("name","汪雲飛");
m.put("age",11);
p.setInfo(m);
Person returnPerson = personRepository.save(p);
Map returnMap = returnPerson.getInfo;
for(Object entry :returnMap.entrySet){
log.info(entry.toString);
}
};
}
6. 查詢測試
@Bean
CommandLineRunner queryJsonb(PersonRepository personRepository){
return e -> {
List
for (Person person : people){
Map info = person.getInfo;
log.info(person.getId + "/" + info.get("name") + "/" +info.get("age"));
}
};
}
7. 源碼地址
※細說Nullable
※Javascript 「繼承」
※使用CoApp創建NuGet C++靜態庫包
※大話Python正則表達式
※Linux 最新SO_REUSEPORT特性
TAG:達人科技 |
※TypeScript基礎之高級類型的可辨識聯合(Discriminated Unions)
※python中list,array,mat,tuple大小及類型
※Chrome 66 新特性:CSS 類型對象模型,非同步剪貼板 API,AudioWorklet,等
※Hibernate 映射枚舉Enum 類型的屬性
※SM、jyp、yg、cube、ymc等公司類型——其中big hit最霸氣
※Google出品的Python代碼靜態類型分析器:Pytype
※「Good idea/solution」 類型作文審題
※python基礎之變數類型number(math模塊)
※由光環新網運營的 AWS 中國區域現已推出 Amazon RDS for Oracle 支持 X1 實例類型
※類型轉換運算符 運算符重載 operator new operator delete
※「Python」Chapter1 變數和簡單數據類型
※澳大利亞 Bunjil Place,高難度木曲線營造類型場所/fjmt
※opencv Mat類型和BYTE*指針類型互轉
※Pyright:微軟提供的Python靜態類型檢查器
※鄭爽VS Angel baby 鹿晗VS易烊千璽,同類型綜藝
※solidity之地址類型
※Redis 數據類型
※steam免費領取 HITMAN? 2 序章(FOD 類型)
※Mariadb學習總結(三):數據類型
※Summary 數據類型詳解