hibernate存取json數據的代碼分析
一、場景
public class OrderModel {
private List<String> favorableDescList;
}
訂單中會存儲一些優(yōu)惠信息,方便頁面展示時使用,如:
1、滿100減50
2、參與【老會員真情回饋——精品課程體驗活動】,僅需支付200.00學幣
3、【Oracle + PL/SQL 實戰(zhàn)】套裝課程的【搶購】活動,優(yōu)惠120.00學幣
……等等
如圖所示,我們在頁面給用戶展示他們參與的優(yōu)惠信息:

二、分析
如上優(yōu)惠信息有如下特點:
1、只用于展示,不會涉及修改;
2、一旦訂單支付成功,不會再改變;
3、數據量不會很大。
三、解決方案
1、最簡單的解決方案是關聯表:

但這種解決方案需要連表進行查詢,感覺是沒有必要的,畢竟只是展示數據,用關聯表有點殺雞用牛刀的感覺。
2、JSON解決方案:

通過如上思路我們可以解決許多類似的問題。
3、代碼示例:
1、模型類:
Java代碼
public class OrderModel {
@Type(type = "com.bjpowernode.framework.hibernate.type.JsonType") //①
private List<String> favorableDescList;
}
①處使用我們自定義的Hibernate類型來進行轉換,上邊代碼只有一部分
2、自定義JsonType
Java代碼
package com.bjpowernode.framework.hibernate.type;
//省略import
public class JsonType implements UserType, Serializable {
private String json;
@Override
public int[] sqlTypes() {
return new int[] {Hibernate.STRING.sqlType()};
}
@Override
public Class returnedClass() {
return JsonList.class;
}
@Override
public boolean equals(Object o, Object o1) throws HibernateException {
if (o == o1) {
return true;
}
if (o == null || o == null) {
return false;
}
return o.equals(o1);
}
@Override
public int hashCode(Object o) throws HibernateException {
return o.hashCode();
}
/**
* 從JDBC ResultSet讀取數據,將其轉換為自定義類型后返回
* (此方法要求對克能出現null值進行處理)
* names中包含了當前自定義類型的映射字段名稱
* @param resultSet
* @param names
* @param owner
* @return
* @throws HibernateException
* @throws SQLException
*/
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
String json = resultSet.getString(names[0]);
if(json == null || json.trim().length() == 0) {
return new JsonList();
}
return JSONArray.toList(JSONArray.fromObject(json), JsonList.class);
}
/**
* 本方法將在Hibernate進行數據保存時被調用
* 我們可以通過PreparedStateme將自定義數據寫入到對應的數據庫表字段
* @param preparedStatement
* @param value
* @param i
* @throws HibernateException
* @throws SQLException
*/
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int i) throws HibernateException, SQLException {
if(value == null) {
preparedStatement.setNull(i, Hibernate.STRING.sqlType());
} else {
preparedStatement.setString(i, JSONArray.fromObject(value).toString());
}
}
/**
* 提供自定義類型的完全復制方法
* 本方法將用構造返回對象
* 當nullSafeGet方法調用之后,我們獲得了自定義數據對象,在向用戶返回自定義數據之前,
* deepCopy方法將被調用,它將根據自定義數據對象構造一個完全拷貝,并將此拷貝返回給用戶
* 此時我們就得到了自定義數據對象的兩個版本,第一個是從數據庫讀出的原始版本,其二是我們通過
* deepCopy方法構造的復制版本,原始的版本將有Hibernate維護,復制版由用戶使用。原始版本用作
* 稍后的臟數據檢查依據;Hibernate將在臟數據檢查過程中將兩個版本的數據進行對比(通過調用
* equals方法),如果數據發(fā)生了變化(equals方法返回false),則執(zhí)行對應的持久化操作
*
* @param o
* @return
* @throws HibernateException
*/
@Override
public Object deepCopy(Object o) throws HibernateException {
if(o == null) return null;
JsonList jsonList = new JsonList();
jsonList.addAll((List)o);
return jsonList;
}
/**
* 本類型實例是否可變
* @return
*/
@Override
public boolean isMutable() {
return true;
}
/* 序列化 */
@Override
public Serializable disassemble(Object value) throws HibernateException {
return ((Serializable)value);
}
/* 反序列化 */
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
JSON框架使用的是json-lib 2.1。
3、自定義JsonList
Java代碼
package com.bjpowernode.framework.hibernate;
public class JsonList<T> extends ArrayList implements Cloneable {
}
就這么簡單,歡迎大家討論。
有人說有性能問題,我寫了個測試用例:
測試機器:CPU:p8700(雙核@2.53GHZ) 內存:2G
一、插入
1、JSON方式插入10w條
create 100000 elapsed time(millis):21031
2、關聯表插入10w條
create 100000 elapsed time(millis):79219
JSON性能遠遠好于關聯表,關聯表要插入兩個表。
二、查詢
1、JSON方式分頁(100條一頁)查詢10w條
select 100000 elapsed time(millis):146047
2、關聯表分頁(100條一頁)查詢10w條
select 100000 elapsed time(millis):275375
JSON性能遠遠好于關聯表,關聯表需要join連表查詢。
JSON方式的缺點:分析統(tǒng)計等查詢是雞肋、大數據量是雞肋(一列存儲數據量不可能太大)。
我的應用場景:優(yōu)惠信息、購物車持久化(每個用戶購物車最多50條)。
總結
以上所述是小編給大家介紹的hibernate存取json數據的代碼分析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
相關文章
java 出現問題javax.servlet.http.HttpServlet was not found解決方法
這篇文章主要介紹了java 出現問題javax.servlet.http.HttpServlet was not found解決方法的相關資料,需要的朋友可以參考下2016-11-11
徹底搞懂java并發(fā)ThreadPoolExecutor使用
這篇文章主要為大家介紹了徹底搞懂java并發(fā)ThreadPoolExecutor使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02
Spring實戰(zhàn)之使用Resource作為屬性操作示例
這篇文章主要介紹了Spring實戰(zhàn)之使用Resource作為屬性,結合實例形式分析了spring載人Resource作為屬性相關配置與使用技巧,需要的朋友可以參考下2020-01-01
解析Java線程編程中的線程安全與synchronized的使用
這篇文章主要介紹了Java線程編程中的線程安全與synchronized的使用,synchronized多線程使用時一定要注意線程之間的沖突問題,需要的朋友可以參考下2015-12-12

