場景:動態查詢,分頁查詢,根據傳入不同的狀態,分別查詢不同資料表,並且在傳入page物件之前用map進行vo轉換。而pageable的使用地方不同影響到了分頁資料的正確性,以此進行**。
前提:page物件封於vo內,返回資料報括了分頁資料
@apimodelproperty("記錄")
private pageactivityrecordvolist;
@apimodelproperty("數量")
private integer num = 0;
@apimodelproperty("金額")
private bigdecimal totalmoney = bigdecimal.valueof(0);
錯誤運用:
listactivityrecordvolist = new arraylist<>();
if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.receive)
} else if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.send)
}
activityreceivesendrecordvo.setactivityrecordvolist(new pageimpl<>(activityrecordvolist,
pageable, activityrecordvolist.size()));
解析:傳入的pageable只在set進vo的時候,用new pageiml將list轉為page物件,前端報的問題雖然總頁數、總條數均為正確,但第一頁的條數是全部,資料異常!
採用specifications先根據查詢條件動態查詢並map出相應分頁物件(此塊**因需求而異),這時findall傳入的pageable是生效的,便會顯現正確的分頁資訊。
**塊參考:
***commonspecutil是自封的specification工具類,與原生spring data jpa原生查詢方法類似。
pagepage = new pageimpl<>(activityrecordvolist, pageable, activityrecordvolist.size());
if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.receive) else if (receivesendrecordrequestvo.getsendorreceivetype() == sendorreceivetype.send)
注:activityreceivesendrecordvo為封裝的vo,包含了返回的page物件
activityreceivesendrecordvo.setactivityrecordvolist(page);
場景:@transactional事務,更新使用者餘額(處理併發問題),更新完畢返回vo帶上使用者剩餘餘額,但卻非更新後的餘額。
更新邏輯**:
userwebservice.updatebalanceaftertransaction(userid, transactionrecordaddvo.getmoney(),user.getbalance());
@transactional
public void updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance)
}
@modifying
@query(value = "update user u set u.balance = u.balance - ?2 where u.id = ?1 and u.balance = ?3")
int updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance);
解析:
在jpa中使用@modifying,雖然事務已經能夠更新,但是在迴圈更新的時候,執行modify語句後的查詢的實體仍然是沒有更新的。
執行完modifying query, entitymanager可能會包含過時的資料,因為entitymanager不會自動清除實體。
只有新增clearautomatically屬性,entitymanager才會自動清除實體物件。
新增**:
@modifying(clearautomatically = true)
改正後的示例**:
@modifying(clearautomatically = true)
@query(value = "update user u set u.balance = u.balance - ?2 where u.id = ?1 and u.balance = ?3")
int updatebalanceaftertransaction(integer userid, bigdecimal money, bigdecimal userbalance);
使用了這麼長時間spring data jpa,覺得specifications巨好用,也不容易出錯,也是我喜歡的編碼風格,而new pageimpl<>()這種簡單粗暴的方法我一般都用在查詢資料關聯太多表的情況,在最後直接返回,更深層次的還需要再**! spring data jpa遇到的坑
1 column註解name最好全寫了,不然遇到像hibernate駝峰和下劃線風格配置變更時會出現找不到屬性,尤其開啟自動建表情況 2 唯讀操作情況,如果對讀取物件進行了屬性修改操作,那麼jpa會認為你要修改這個實體,使用hibernate的情況下回預設執行乙個update的sql,然後你懂得由於...
spring data jpa實體繼承
spring jpa中我們要將sql對映到物件,尤其是在spring boot這種高度自動化的環境下使用,大量的最優目錄結構與命名規則可以大大降低配置,約定大於配置貫穿其中。例如我們定義查詢dao,繼承jparepository即可。然後返回的物件,我們可以定義model entity table ...
SpringData JPA分頁查詢
首先我們需要知道springdata jpa 的幾個介面 其實看名字就大概懂了,也可以很方便的使用 首先我們的持久化層繼承jparepository,相當於繼承了增刪改查的持久化層以及分頁查詢的持久化層 所以如果我們要使用分頁查詢 我們只需要直接呼叫 由一開始的圖也可以看到pageable的其中乙個...