日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate中的JPA 2.1条件删除/更新和临时表

發(fā)布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate中的JPA 2.1条件删除/更新和临时表 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

從JPA 2.0版開始, EntityManager提供了方法getCriteriaBuilder()來動態(tài)構(gòu)建選擇查詢,而無需使用Java持久性查詢語言(JPQL)進行字符串連接。 在2.1版中,此CriteriaBuilder提供了兩個新方法createCriteriaDelete()和createCriteriaUpdate() ,使我們可以使用條件API制定刪除和更新查詢的方法。

出于說明目的,讓我們對兩個實體Person和Geek使用簡單的繼承用例:

@Entity @Table(name = "T_PERSON") @Inheritance(strategy = InheritanceType.JOINED) public class Person {@Id@GeneratedValueprivate Long id;@Column(name = "FIRST_NAME")private String firstName;@Column(name = "LAST_NAME")private String lastName;... }@Entity @Table(name = "T_GEEK") @Access(AccessType.PROPERTY) public class Geek extends Person {private String favouriteProgrammingLanguage;... }

要從我們的數(shù)據(jù)庫中刪除所有喜歡Java作為其編程語言的怪胎,我們可以使用EntityManager的新createCriteriaDelete()方法利用以下代碼:

EntityTransaction transaction = null; try {transaction = entityManager.getTransaction();transaction.begin();CriteriaBuilder builder = entityManager.getCriteriaBuilder();CriteriaDelete<Geek> delete = builder.createCriteriaDelete(Geek.class);Root<Geek> geekRoot = delete.from(Geek.class);delete.where(builder.equal(geekRoot.get("favouriteProgrammingLanguage"), "Java"));int numberOfRowsUpdated = entityManager.createQuery(delete).executeUpdate();LOGGER.info("Deleted " + numberOfRowsUpdated + " rows.");transaction.commit(); } catch (Exception e) {if (transaction != null && transaction.isActive()) {transaction.rollback();} }

與純SQL一樣,我們可以使用from()方法指定要針對其發(fā)出刪除查詢的表,并使用where()聲明謂詞。 通過這種方式,標準API允許以動態(tài)方式定義批量刪除操作,而無需使用過多的字符串連接。

但是,SQL是如何創(chuàng)建的呢? 首先,ORM提供程序必須注意,我們正在使用策略JOINED從繼承層次結(jié)構(gòu)中刪除,這意味著我們有兩個表T_PERSON和T_GEEK ,其中第二個表存儲對父表的引用。 Hibernate版本4.3.8.Final創(chuàng)建以下SQL語句:

insert intoHT_T_GEEKselectgeek0_.id as id fromT_GEEK geek0_ inner joinT_PERSON geek0_1_ on geek0_.id=geek0_1_.id wheregeek0_.FAV_PROG_LANG=?;delete fromT_GEEK where(id) IN (selectid fromHT_T_GEEK);delete fromT_PERSON where(id) IN (selectid fromHT_T_GEEK)delete fromHT_T_GEEK;

如我們所見,Hibernate使用與我們的搜索條件匹配的極客/人員的ID填充了一個臨時表。 然后,它將刪除極客表中的所有行,然后刪除人員表中的所有行。 最后,臨時表被清除。

刪除語句的順序很明確,因為表T_GEEK在T_PERSON表的id列上具有外鍵約束。 因此,子表中的行必須在父表中的行之前刪除。 本文介紹了Hibernate創(chuàng)建臨時表的原因。 概括起來,潛在的問題是查詢限制了僅在子表中存在的列上要刪除的行。 但是子表中的行必須在父表中的相應行之前刪除。 刪除子表中的行(即,所有具有FAV_PROG_LANG='Java'的怪胎)后,由于已經(jīng)刪除了怪胎行,因此無法隨后刪除所有對應的人員。 解決該問題的方法是臨時表,該臨時表首先收集應刪除的所有行ID。 知道所有ID后,可以使用此信息先從怪胎表中刪除行,然后從人員表中刪除行。

上面生成的SQL語句當然獨立于標準API的用法。 使用JPQL方法會導致生成相同的SQL:

EntityTransaction transaction = null; try {transaction = entityManager.getTransaction();transaction.begin();int update = entityManager.createQuery("delete from Geek g where g.favouriteProgrammingLanguage = :lang").setParameter("lang", "Java").executeUpdate();LOGGER.info("Deleted " + update + " rows.");transaction.commit(); } catch (Exception e) {if (transaction != null && transaction.isActive()) {transaction.rollback();} }

當我們將繼承策略從JOINED更改為SINGLE_TABLE ,生成的SQL語句也更改為單個(此處的鑒別DTYPE列為DTYPE ):

delete fromT_PERSON whereDTYPE='Geek' and FAV_PROG_LANG=?

結(jié)論

用于刪除和更新的標準API的新增功能使您可以構(gòu)造SQL語句,而無需任何字符串連接。 但是請注意,從繼承層次結(jié)構(gòu)中進行批量刪除可能會迫使基礎(chǔ)ORM使用臨時表,以便組裝必須事先刪除的行列表。

翻譯自: https://www.javacodegeeks.com/2015/02/jpa-2-1-criteria-deleteupdate-temporary-tables-hibernate.html

總結(jié)

以上是生活随笔為你收集整理的Hibernate中的JPA 2.1条件删除/更新和临时表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。