终极JPA查询和技巧列表–第3部分
JPA:通過查詢創(chuàng)建對象
JPA允許我們在查詢內(nèi)創(chuàng)建對象,并帶有所需的值:
注意,在查詢中我們創(chuàng)建了一個新對象。 好消息是您可以創(chuàng)建任何對象,而不必是一個實(shí)體。 您只需要傳遞類的完整路徑,JPA將處理新的類實(shí)例化。
對于需要特定字段但實(shí)體中不存在這些字段的報表,這是非常有用的功能。
JPQL:批量更新和刪除
有時我們需要執(zhí)行一個操作來更新表數(shù)據(jù)庫中的幾行。 例如,更新所有年齡大于70歲的人,并將其定義為老年人。
您可以像這樣運(yùn)行批量更新/刪除:
package com.main;import javax.persistence.EntityManager; import javax.persistence.Query;import com.model.Person;public class Page14 {public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em = CodeGenerator.getEntityManager();em.clear();Query query = em.createQuery('update Person p set p.name = 'Fluffy, the destroyer of worlds!'');query.executeUpdate();query = em.createQuery('select p from Person p where p.id = 4');Person person = (Person) query.getSingleResult();System.out.println('My new name is: ' + person.getName());query = em.createQuery('delete from Person p where p.dogs is empty');query.executeUpdate();query = em.createQuery('select p from Person p');System.out.println('We had 6, but was found ' + query.getResultList().size() + ' persons in the database');CodeGenerator.closeConnection();} }在這種情況下,級聯(lián)選項(xiàng)不會被觸發(fā)。 您將無法刪除對象,并希望JPA刪除關(guān)系中的級聯(lián)對象。 一旦討論批量操作,數(shù)據(jù)庫數(shù)據(jù)的完整性就屬于開發(fā)人員。 如果要從數(shù)據(jù)庫及其關(guān)系中刪除對象,則需要在執(zhí)行刪除操作之前將對象的關(guān)系更新為null。
我們可以將這種操作定義為非常危險的操作。 如果我們在第17行添加注釋(“ em.clear(); “),我們將看到該人的姓名在更新后仍然保持不變。
“ 問題 ”是持久性上下文將所有數(shù)據(jù)“ 附加 ”在內(nèi)存中,但是這些批量操作不會更新持久性上下文。 我們將在數(shù)據(jù)庫中完成一個操作,但尚未在持久性上下文中反映出來。 這種情況可能會給我們帶來同步問題。
描繪以下場景:
- 事務(wù)開始。
- 通過方法em.persist()將人員A保留在數(shù)據(jù)庫中。
- 人B的名稱通過em.merge()方法更新為“ Louanne”。
- 人員A將通過批量刪除操作被刪除。
- 人B的名稱已通過批量更新更新為“ Fernanda”。
- 交易完成。
在這種情況下會發(fā)生什么? 人員A已被批量操作刪除,但是持久性上下文將嘗試將其持久化到數(shù)據(jù)庫中。 人員B的名稱已更新為Fernanda,但“持久性上下文”將嘗試更新為Louanne。
對于某種情況,沒有默認(rèn)行為,但是可以使用一些解決方案來避免這些問題:
- 在批量操作之前啟動新事務(wù):對于剛開始于批量操作的新事務(wù),此操作完成后,更新/刪除將在數(shù)據(jù)庫中執(zhí)行。 您將沒有實(shí)體管理器嘗試使用尚未寫入數(shù)據(jù)庫的數(shù)據(jù)。
- 在批量操作之前調(diào)用“ entityManager.clear()”方法:如果調(diào)用此方法,則將強(qiáng)制“持久性上下文”釋放所有緩存的數(shù)據(jù)。 批量操作后,如果您使用find方法,則持久性上下文將從數(shù)據(jù)庫中獲取數(shù)據(jù),因?yàn)槟谂坎僮髦扒宄司彺娴臄?shù)據(jù)。
調(diào)用clear()方法不是靈丹妙藥,如果多次使用它會給您帶來性能問題。 如果您的Persistence Context有很多緩存的對象,并且您調(diào)用clear()方法,則Persistence Context將必須執(zhí)行很多“行程”才能再次獲取所需的數(shù)據(jù)。 持久性上下文具有出色的數(shù)據(jù)緩存控件,應(yīng)該利用它。
批量操作是一種可以在多種情況下為我們提供幫助的選項(xiàng), 但是您必須謹(jǐn)慎使用它。
JPA:條件
JPA是運(yùn)行查詢的一個很好的框架,但是Criteria并不是使用JPA進(jìn)行查詢的一個好方法。
JPA標(biāo)準(zhǔn)過于冗長,復(fù)雜,并且需要太多代碼才能進(jìn)行一些基本查詢。 不幸的是,作為休眠標(biāo)準(zhǔn)并不容易。
下面的代碼將顯示一個簡單的Criteria代碼,但我們不會再看到更多有關(guān)此主題的信息。 我已經(jīng)讀了三本關(guān)于EJB / JPA的書,而沒有一本書談?wù)撍?
下面的代碼有一個標(biāo)準(zhǔn)代碼:
package com.main;import java.util.List;import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaQuery;import com.model.Person;public class Page15 {@SuppressWarnings({ 'unchecked', 'rawtypes' })public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em = CodeGenerator.getEntityManager();CriteriaQuery criteriaQuery = em.getCriteriaBuilder().createQuery();criteriaQuery.select(criteriaQuery.from(Person.class));List<Person> result = em.createQuery(criteriaQuery).getResultList();System.out.println('Found ' + result.size() + ' persons.');CodeGenerator.closeConnection();} }我很遺憾在這里這樣說我對Criteria的看法,但是到目前為止,除非對于ListALL,否則在您的代碼中使用Criteria并不容易。
上面的代碼很容易應(yīng)用于通用DAO,因此通過它列出所有對象會更容易。
以下鏈接顯示了應(yīng)用程序中的通用DAO: 完整WebApplication JSF EJB JPA JAAS 。
結(jié)束!
希望這篇文章對您有所幫助。
單擊此處下載源代碼。
您無需編輯任何配置即可運(yùn)行本文的代碼,只需將其導(dǎo)入Eclipse。
如果您有任何疑問/意見,請在下面將其發(fā)布。
再見。
有用的鏈接:
- http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-log4j/
- http://stackoverflow.com/questions/1659030/how-to-get-the-database-time-with-jpql
- Pro EJB 3:Java持久性API,Mike Keith,Merrick Schincariol
- 企業(yè)JavaBeans 3.0 – Richard Monson-Haefel,Bill Burke
參考: uaiHebert博客上來自JCG合作伙伴 Hebert Coelho的JPA查詢和技巧 。
翻譯自: https://www.javacodegeeks.com/2012/07/ultimate-jpa-queries-and-tips-list-part_7092.html
總結(jié)
以上是生活随笔為你收集整理的终极JPA查询和技巧列表–第3部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 月薪3000如何理财买车?
- 下一篇: 支付宝黄金为什么卖掉还在亏钱?