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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JPA实体图

發(fā)布時(shí)間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JPA实体图 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JPA 2.1的最新功能之一是能夠使用實(shí)體圖指定獲取計(jì)劃。 這很有用,因?yàn)樗试S您自定義使用查詢或查找操作檢索的數(shù)據(jù)。 當(dāng)使用中型到大型應(yīng)用程序時(shí),通常以不同的方式顯示來(lái)自同一實(shí)體的數(shù)據(jù)。 在其他情況下,您只想選擇最小的信息集即可優(yōu)化應(yīng)用程序的性能。

您沒(méi)有很多機(jī)制可以控制JPA實(shí)體中加載或不加載的內(nèi)容。 您可以使用EAGER / LAZY提取,但是這些定義幾乎是靜態(tài)的。 您在檢索數(shù)據(jù)時(shí)無(wú)法更改其行為,這意味著您受制于實(shí)體中定義的內(nèi)容。 在開(kāi)發(fā)中更改這些內(nèi)容是一場(chǎng)噩夢(mèng),因?yàn)檫@可能導(dǎo)致查詢行為異常。 控制加載的另一種方法是編寫(xiě)特定的JPQL查詢。 通常,您最終會(huì)得到非常相似的查詢和以下方法: findEntityWithX , findEntityWithY , findEntityWithXandY等。

在JPA 2.1之前,實(shí)現(xiàn)已經(jīng)支持類似于實(shí)體圖的非標(biāo)準(zhǔn)方式來(lái)加載數(shù)據(jù)。 您具有Hibernate Fetch Profiles , OpenJPA Fetch Groups和EclipseLink Fetch Groups 。 在規(guī)范中具有這種行為是合乎邏輯的。 它允許您對(duì)使用標(biāo)準(zhǔn)API加載的內(nèi)容進(jìn)行更精細(xì),更詳細(xì)的控制。

考慮以下實(shí)體圖:

(關(guān)系應(yīng)該是N到N,但讓它保持簡(jiǎn)單)。

電影實(shí)體具有以下定義:

電影.java

@Entity @Table(name = "MOVIE_ENTITY_GRAPH") @NamedQueries({@NamedQuery(name = "Movie.findAll", query = "SELECT m FROM Movie m") }) @NamedEntityGraphs({@NamedEntityGraph(name = "movieWithActors",attributeNodes = {@NamedAttributeNode("movieActors")}),@NamedEntityGraph(name = "movieWithActorsAndAwards",attributeNodes = {@NamedAttributeNode(value = "movieActors", subgraph = "movieActorsGraph")},subgraphs = {@NamedSubgraph(name = "movieActorsGraph",attributeNodes = {@NamedAttributeNode("movieActorAwards")})}) }) public class Movie implements Serializable {@Idprivate Integer id;@NotNull@Size(max = 50)private String name;@OneToMany@JoinColumn(name = "ID")private Set<MovieActor> movieActors;@OneToMany(fetch = FetchType.EAGER)@JoinColumn(name = "ID")private Set<MovieDirector> movieDirectors;@OneToMany@JoinColumn(name = "ID")private Set<MovieAward> movieAwards; }

靠近實(shí)體,我們可以看到我們有3個(gè)1到N的關(guān)系,并且將movieDirectors設(shè)置為渴望加載。 其他關(guān)系設(shè)置為默認(rèn)的延遲加載策略。 如果要更改此行為,可以使用批注@NamedEntityGraph定義不同的加載模型。 只需設(shè)置一個(gè)名稱即可識(shí)別它,然后使用@NamedAttributeNode指定要加載的根實(shí)體的哪些屬性。 對(duì)于關(guān)系,您需要為子圖設(shè)置一個(gè)名稱,然后使用@NamedSubgraph 。 詳細(xì):

注解

實(shí)體圖movieWithActors

@NamedEntityGraph(name = "movieWithActors",attributeNodes = {@NamedAttributeNode("movieActors")}) )

這將定義一個(gè)名稱為movieWithActors的實(shí)體圖,并指定應(yīng)加載關(guān)系movieActors 。

實(shí)體圖movieWithActorsAndAwards

@NamedEntityGraph(name = "movieWithActorsAndAwards",attributeNodes = {@NamedAttributeNode(value = "movieActors", subgraph = "movieActorsGraph")},subgraphs = {@NamedSubgraph(name = "movieActorsGraph",attributeNodes = {@NamedAttributeNode("movieActorAwards")})})

這將定義一個(gè)名稱為movieWithActorsAndAwards的實(shí)體圖,并指定應(yīng)加載關(guān)系movieActors 。 此外,它還指定關(guān)系movieActors應(yīng)該加載movieActorAwards 。

請(qǐng)注意,我們沒(méi)有在實(shí)體圖中指定id屬性。 這是因?yàn)闊o(wú)論指定什么內(nèi)容,總是會(huì)獲取主鍵。 版本屬性也是如此。

提示

要使用查詢中定義的實(shí)體圖,您需要將它們?cè)O(shè)置為提示。 您可以使用兩個(gè)提示屬性,它們也會(huì)影響數(shù)據(jù)的加載方式。

您可以使用javax.persistence.fetchgraph ,此提示會(huì)將Entity Graph中所有指定的屬性視為FetchType.EAGER 。 未指定的屬性被視為FetchType.LAZY 。

另一個(gè)屬性提示是javax.persistence.loadgraph 。 這會(huì)將Entity Graph中所有指定的屬性視為FetchType.EAGER 。 未指定的屬性將被視為其指定的或默認(rèn)的FetchType 。

為了簡(jiǎn)化,并基于我們的示例,當(dāng)應(yīng)用實(shí)體圖movieWithActors :

默認(rèn)/指定 javax.persistence.fetchgraph javax.persistence.loadgraph
電影演員 急于 急于
電影導(dǎo)演 急于 急于
電影獎(jiǎng)

從理論上講,這應(yīng)該是獲取不同關(guān)系的方式。 實(shí)際上,它可能無(wú)法通過(guò)這種方式工作,因?yàn)镴PA 2.1規(guī)范還指出,JPA提供程序始終可以獲取除實(shí)體圖中指定的狀態(tài)之外的其他狀態(tài)。 這是因?yàn)樘峁┏绦蚩梢詢?yōu)化要獲取的數(shù)據(jù)并最終加載更多的數(shù)據(jù)。 您需要檢查提供商的行為。 例如,即使使用javax.persistence.fetchgraph提示,Hibernate始終會(huì)獲取指定為EAGER的所有內(nèi)容。 在此處檢查問(wèn)題。

詢問(wèn)

執(zhí)行查詢很容易。 您可以setHint進(jìn)行操作,但是只需對(duì)Query對(duì)象調(diào)用setHint :

提示實(shí)體圖

@PersistenceContextprivate EntityManager entityManager;public List<Movie> listMovies(String hint, String graphName) {return entityManager.createNamedQuery("Movie.findAll").setHint(hint, entityManager.getEntityGraph(graphName)).getResultList();}

要獲取要在查詢中使用的實(shí)體圖,您需要在EntityManager上調(diào)用getEntityGraph方法并傳遞名稱。 然后在提示中使用參考。 提示必須是javax.persistence.fetchgraph或javax.persistence.loadgraph 。

程式化

注釋可能變得冗長(zhǎng),尤其是當(dāng)您有大圖或許多實(shí)體圖時(shí)。 您可以以編程方式定義實(shí)體圖,而不必使用注釋。 讓我們看看如何:

首先添加一個(gè)靜態(tài)元模型實(shí)體類:

Movie_.java

@StaticMetamodel(Movie.class) public abstract class Movie_ {public static volatile SingularAttribute<Movie, Integer> id;public static volatile SetAttribute<Movie, MovieAward> movieAwards;public static volatile SingularAttribute<Movie, String> name;public static volatile SetAttribute<Movie, MovieActor> movieActors;public static volatile SetAttribute<Movie, MovieDirector> movieDirectors; }

確實(shí)不是必需的,您可以通過(guò)屬性的字符串名稱來(lái)引用屬性,但這將為您提供安全性。

程序?qū)嶓w圖

EntityGraph<Movie> fetchAll = entityManager.createEntityGraph(Movie.class);fetchAll.addSubgraph(Movie_.movieActors);fetchAll.addSubgraph(Movie_.movieDirectors);fetchAll.addSubgraph(Movie_.movieAwards);

該實(shí)體圖指定必須加載實(shí)體的所有關(guān)系。 現(xiàn)在,您可以調(diào)整自己的用例。

資源資源

您可以在Github的Java EE示例中找到此示例代碼。 在這里檢查。

特別說(shuō)明: EclipseLink / Glassfish當(dāng)前存在一個(gè)錯(cuò)誤,該錯(cuò)誤會(huì)阻止javax.persistence.loadgraph提示正常工作。 在此處檢查問(wèn)題。

結(jié)論

實(shí)體圖填補(bǔ)了JPA規(guī)范中缺少的空白。 它們是一種額外的機(jī)制,可以幫助您查詢真正需要的內(nèi)容。 它們還可以幫助您提高應(yīng)用程序的性能。 但是使用它們時(shí)要聰明。 可能有更好的方法。

翻譯自: https://www.javacodegeeks.com/2014/11/jpa-entity-graphs.html

總結(jié)

以上是生活随笔為你收集整理的JPA实体图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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