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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

jpa和hibernate_使用JPA和Hibernate有效删除数据

發(fā)布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jpa和hibernate_使用JPA和Hibernate有效删除数据 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

jpa和hibernate

您可能會遇到必須對關(guān)系數(shù)據(jù)庫中存儲的大量數(shù)據(jù)集執(zhí)行批量刪除的情況。 如果您將JPA與Hibernate一起用作基礎(chǔ)OR映射器,則可以嘗試通過以下方式調(diào)用EntityManager的remove()方法:

public void removeById(long id) {RootEntity rootEntity = entityManager.getReference(RootEntity.class, id);entityManager.remove(rootEntity); }

首先,我們加載要刪除的實體的引用表示形式,然后將此引用傳遞給EntityManager。 假設(shè)上面的RootEntity與名為ChildEntity的類有子關(guān)系:

@OneToMany(mappedBy = "rootEntity", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private Set childEntities = new HashSet(0);

如果現(xiàn)在打開hibernate的屬性show_sql,我們將想知道發(fā)出什么SQL語句:

selectrootentity0_.id as id5_1_,rootentity0_.field1 as field2_5_1_,rootentity0_.field2 as field3_5_1_,childentit1_.PARENT as PARENT5_3_,childentit1_.id as id3_,childentit1_.id as id4_0_,childentit1_.field1 as field2_4_0_,childentit1_.field2 as field3_4_0_,childentit1_.PARENT as PARENT4_0_fromROOT_ENTITY rootentity0_left outer joinCHILD_ENTITY childentit1_on rootentity0_.id=childentit1_.PARENTwhererootentity0_.id=?deletefromCHILD_ENTITYwhereid=?deletefromROOT_ENTITYwhereid=?

為什么Hibernate首先將所有數(shù)據(jù)加載到內(nèi)存中以便隨后立即刪除該數(shù)據(jù)? 原因是JPA的生命周期要求對象處于“托管”狀態(tài),然后才能刪除它。 僅在這種狀態(tài)下,所有生命周期功能(如攔截器)才可用(請參閱此處 )。 因此,Hibernate在刪除之前發(fā)出SELECT查詢,以便將RootEntity和ChildEntity都轉(zhuǎn)移到“托管”狀態(tài)。 但是,如果我們只想刪除RootEntity和ChildEntity,并且知道RootEntity的ID,該怎么辦? 答案是使用類似于以下內(nèi)容的簡單DELETE查詢。 但是由于子表的完整性約束,我們首先必須刪除所有依賴的子實體。 以下代碼演示了如何:

List childIds = entityManager.createQuery("select c.id from ChildEntity c where c.rootEntity.id = :pid").setParameter("pid", id).getResultList(); for(Long childId : childIds) {entityManager.createQuery("delete from ChildEntity c where c.id = :id").setParameter("id", childId).executeUpdate(); } entityManager.createQuery("delete from RootEntity r where r.id = :id").setParameter("id", id).executeUpdate();

上面的代碼通過調(diào)用remove()產(chǎn)生了我們期望的三個SQL語句。 現(xiàn)在您可能會說,這種刪除方式比僅調(diào)用EntityManager的remove()方法更為復雜。 它還會忽略我們在兩個實體類中放置的注釋,例如@OneToMany和@ManyToOne。 那么,為什么不編寫一些代碼來使用關(guān)于兩個類文件中已經(jīng)存在的兩個實體的知識呢? 首先,我們在RootEntity類中使用反射查找@OneToMany批注,提取子實體的類型,然后查找其后向字段,并用@ManyToOne批注。 完成此操作后,我們可以以更通用的方式輕松編寫三個SQL語句:

public void delete(EntityManager entityManager, Class parentClass, Object parentId) {Field idField = getIdField(parentClass);if (idField != null) {List oneToManyFields = getOneToManyFields(parentClass);for (Field field : oneToManyFields) {Class childClass = getFirstActualTypeArgument(field);if (childClass != null) {Field manyToOneField = getManyToOneField(childClass, parentClass);Field childClassIdField = getIdField(childClass);if (manyToOneField != null && childClassIdField != null) {List childIds = entityManager.createQuery(String.format("select c.%s from %s c where c.%s.%s = :pid", childClassIdField.getName(), childClass.getSimpleName(), manyToOneField.getName(), idField.getName())).setParameter("pid", parentId).getResultList();for (Long childId : childIds) {entityManager.createQuery(String.format("delete from %s c where c.%s = :id", childClass.getSimpleName(), childClassIdField.getName())).setParameter("id", childId).executeUpdate();}}}}entityManager.createQuery(String.format("delete from %s e where e.%s = :id", parentClass.getSimpleName(), idField.getName())).setParameter("id", parentId).executeUpdate();} }

上面的代碼中的方法getFirstActualTypeArgument(),getManyToOneField(),getIdField()和getOneToManyFields()并未在此處顯示,但是聽起來像它們的名字。 實施后,我們可以輕松刪除所有以樹的根開頭的實體。

  • 可以在github上找到一個可用于檢查上述行為和解決方案的簡單示例應用程序。

參考:在Martin's Developer World博客上, 使用JPA和Hibernate從我們的JCG合作伙伴 Martin Mois 有效地刪除了數(shù)據(jù) 。

翻譯自: https://www.javacodegeeks.com/2013/11/efficiently-delete-data-with-jpa-and-hibernate.html

jpa和hibernate

總結(jié)

以上是生活随笔為你收集整理的jpa和hibernate_使用JPA和Hibernate有效删除数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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