hibernate脏数据_Hibernate性能提示:脏收集效果
hibernate臟數(shù)據(jù)
在使用Hibernate作為ORM開發(fā)服務(wù)器和嵌入式應(yīng)用程序8年后,我全力以赴地尋求提高Hibernate性能的解決方案,閱讀博客和參加會(huì)議,我決定與您分享在這些年中獲得的知識(shí)。這是更多新帖子中的第一篇:
去年,我以Devoxx的身份參加了演講,但是我也參加了關(guān)于Hibernate反模式的 Patrycja Wegrzynowicz會(huì)議。 在該演示中, Patrycja向我們展示了一種反模式,它使我震驚,因?yàn)槭聦?shí)證明它預(yù)料到了意外情況。
我們將看到當(dāng)Hibernate檢測(cè)到一個(gè)骯臟的集合并應(yīng)該重新創(chuàng)建它時(shí)所產(chǎn)生的效果。
讓我們從將要使用的模型開始,只有兩個(gè)與一對(duì)多關(guān)聯(lián)相關(guān)的類:
@Entity public class Starship {private Long id;@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) public Long getId() {return id;}public void setId(Long id) {this.id = id;}private Date launched;@Temporal(TemporalType.DATE) public Date getLaunched() {return launched;}public void setLaunched(Date launched) {this.launched = launched;}private String registry;@Column(unique=true, nullable=false) public String getRegistry() {return registry;}public void setRegistry(String registry) {this.registry = registry;}private StarshipClassEnum starshipClassEnum;@Enumerated public StarshipClassEnum getStarshipClassEnum() {return starshipClassEnum;}public void setStarshipClassEnum(StarshipClassEnum starshipClassEnum) {this.starshipClassEnum = starshipClassEnum;}private AffiliationEnum affiliationEnum;@Enumerated public AffiliationEnum getAffiliationEnum() {return affiliationEnum;}public void setAffiliationEnum(AffiliationEnum affiliationEnum) {this.affiliationEnum = affiliationEnum;}private Physics physics;@Embedded public Physics getPhysics() {return physics;}public void setPhysics(Physics physics) {this.physics = physics;}private List<Officer> officers = new ArrayList<Officer>();@OneToMany(cascade={CascadeType.ALL}) public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}public Starship() {super();}public Starship(String registry) {setRegistry(registry);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result+ ((registry == null) ? 0 : registry.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Starship other = (Starship) obj;if (registry == null) {if (other.registry != null)return false;} else if (!registry.equals(other.registry))return false;return true;} }@Entity public class Officer {private Long id;@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)public Long getId() {return id;}protected void setId(Long id) {this.id = id;}private String name;@Column(unique=true, nullable=false) public String getName() {return this.name;}public void setName(String name) {this.name = name;}private SpeciesEnum speciesEnum;@Enumerated public SpeciesEnum getSpeciesEnum() {return speciesEnum;}public void setSpeciesEnum(SpeciesEnum speciesEnum) {this.speciesEnum = speciesEnum;}private PlanetEnum homePlanet;@Enumerated public PlanetEnum getHomePlanet() {return homePlanet;}public void setHomePlanet(PlanetEnum homePlanet) {this.homePlanet = homePlanet;}private AffiliationEnum affiliationEnum;@Enumerated public AffiliationEnum getAffiliationEnum() {return affiliationEnum;}public void setAffiliationEnum(AffiliationEnum affiliationEnum) {this.affiliationEnum = affiliationEnum;}private RankEnum rank;@Enumerated @NotNull public RankEnum getRank() {return rank;}public void setRank(RankEnum rank) {this.rank = rank;}private Starship starship; @ManyToOne public Starship getStarship() {return starship;}protected void setStarship(Starship starship) {this.starship = starship;}public Officer() {super();}public Officer(String name, RankEnum rank) {setName(name);setRank(rank);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Officer other = (Officer) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}在上一堂課中,我們應(yīng)注意三個(gè)重點(diǎn):
- 我們?cè)趯傩约?jí)別而不是字段級(jí)別進(jìn)行注釋。
 - @ OneToMany和@ ManyToOne使用默認(rèn)選項(xiàng)( 級(jí)聯(lián)定義除外)
 - 星際飛船班的軍官getter返回一個(gè)不變的列表。
 
為了測(cè)試模型配置,我們將創(chuàng)建一個(gè)測(cè)試,該測(cè)試將創(chuàng)建并保留一個(gè)Starship和七個(gè)高級(jí)管理人員 ,并在不同的Transaction和EntityManager中找到創(chuàng)建的Starship 。
@ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class StarshipPersistenceTests {@Injectprivate EntityManagerFactory entityManagerFactory;@Testpublic void testSaveOrderWithItems() throws Exception {Starship starship = createData();findStarship(starship);}private Starship createData() {EntityManager entityManager = entityManagerFactory.createEntityManager();EntityTransaction transaction = entityManager.getTransaction();transaction.begin();Physics physics = physics().height(137.5D).length(642.5D).power("Wrap reactor").width(467.0D).build();Calendar launched = Calendar.getInstance();launched.set(2363, 9, 4);Starship starship = starship().registry("NCC-1701-D").physics(physics).launched(launched.getTime()).starshipClass(StarshipClassEnum.GALAXY).affiliation(AffiliationEnum.STARFLEET).build();Officer jeanLucPicard = officer().name("Jean-Luc Picard").rank(RankEnum.CAPTAIN).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.EARTH).speciment(SpeciesEnum.HUMAN).build();starship.addOfficer(jeanLucPicard);Officer williamRiker = officer().name("William Riker").rank(RankEnum.COMMANDER).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.EARTH).speciment(SpeciesEnum.HUMAN).build();starship.addOfficer(williamRiker);Officer data = officer().name("Data").rank(RankEnum.LIEUTENANT_COMMANDER).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.OMICRON_THETA).speciment(SpeciesEnum.ANDROID).build();starship.addOfficer(data);Officer geordiLaForge = officer().name("Geordi La Forge").rank(RankEnum.LIEUTENANT).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.EARTH).speciment(SpeciesEnum.HUMAN).build();starship.addOfficer(geordiLaForge);Officer worf = officer().name("Worf").rank(RankEnum.LIEUTENANT).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.QONOS).speciment(SpeciesEnum.KLINGON).build();starship.addOfficer(worf);Officer beverlyCrusher = officer().name("Beverly Crusher").rank(RankEnum.COMMANDER).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.EARTH).speciment(SpeciesEnum.HUMAN).build();starship.addOfficer(beverlyCrusher);Officer deannaTroi = officer().name("Deanna Troi").rank(RankEnum.COMMANDER).affiliation(AffiliationEnum.STARFLEET).homePlanet(PlanetEnum.BETAZED).speciment(SpeciesEnum.BETAZOID).build();starship.addOfficer(deannaTroi);entityManager.persist(starship);transaction.commit();entityManager.close();return starship;}private void findStarship(Starship starship) {EntityManager entityManager = this.entityManagerFactory.createEntityManager();EntityTransaction transaction = entityManager.getTransaction();transaction.begin();System.out.println("Before Find");Starship newStarship = entityManager.find(Starship.class, starship.getId());System.out.println("After Find Before Commit");transaction.commit();System.out.println("After commit");entityManager.close();} }現(xiàn)在我們已經(jīng)創(chuàng)建了這個(gè)測(cè)試,我們可以運(yùn)行它并且觀察Hibernate控制臺(tái)的輸出。
Hibernate: insert into Starship (affiliationEnum, launched, height, length, power, width, registry, starshipClassEnum, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?)Before Find Starship By IdHibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ from Starship starship0_ where starship0_.id=?After Find Starship By Id and Before CommitHibernate: select officers0_.Starship_id as Starship1_1_2_, officers0_.officers_id as officers2_2_, officer1_.id as id0_0_, officer1_.affiliationEnum as affiliat2_0_0_, officer1_.homePlanet as homePlanet0_0_, officer1_.name as name0_0_, officer1_.rank as rank0_0_, officer1_.speciesEnum as speciesE6_0_0_, officer1_.starship_id as starship7_0_0_, starship2_.id as id1_1_, starship2_.affiliationEnum as affiliat2_1_1_, starship2_.launched as launched1_1_, starship2_.height as height1_1_, starship2_.length as length1_1_, starship2_.power as power1_1_, starship2_.width as width1_1_, starship2_.registry as registry1_1_, starship2_.starshipClassEnum as starship9_1_1_ from Starship_Officer officers0_ inner join Officer officer1_ on officers0_.officers_id=officer1_.id left outer join Starship starship2_ on officer1_.starship_id=starship2_.id where officers0_.Starship_id=? Hibernate: delete from Starship_Officer where Starship_id=? Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?) Hibernate: insert into Starship_Officer (Starship_id, officers_id) values (?, ?)After commit查看在第一次提交(持久對(duì)象)和第二次事務(wù)提交(查找Starship )期間執(zhí)行的查詢數(shù)。 在忽略序列生成器的總數(shù)中,我們可以計(jì)數(shù)22個(gè)inserts ,2個(gè)selects和1個(gè)delete ,當(dāng)我們僅創(chuàng)建8個(gè)對(duì)象和1個(gè)通過(guò)主鍵查找時(shí)就可以了。
此時(shí),讓我們檢查為什么執(zhí)行這些SQL查詢:
前8個(gè)插入是不可避免的。 通過(guò)將數(shù)據(jù)插入數(shù)據(jù)庫(kù)需要它們。
接下來(lái)的七都需要插入,因?yàn)槲覀円呀?jīng)注釋getOfficers財(cái)產(chǎn)沒有的mappedBy屬性。 如果我們仔細(xì)查看Hibernate文檔,它會(huì)指出“在不描述任何物理映射的情況下,將使用具有連接表的單向一對(duì)多 ”。
下一組查詢甚至更陌生,第一個(gè)選擇語(yǔ)句是通過(guò)id查找Starship,但是我們已經(jīng)創(chuàng)建的這些數(shù)據(jù)刪除和插入是什么?
在提交期間, Hibernate通過(guò)比較對(duì)象引用來(lái)驗(yàn)證集合屬性是否臟。 當(dāng)一個(gè)集合被標(biāo)記為臟集合時(shí), Hibernate需要重新創(chuàng)建整個(gè)集合,甚至包含相同的對(duì)象。 在本例中,當(dāng)我們要招募軍官時(shí),我們將返回一個(gè)不同的集合實(shí)例,具體來(lái)說(shuō)是一個(gè)不可修改的列表,因此Hibernate認(rèn)為軍官的集合是骯臟的。
由于使用了聯(lián)接表,因此應(yīng)重新創(chuàng)建Starship_Officer表,刪除先前插入的元組并插入新的元組(盡管它們具有相同的值)。
讓我們嘗試解決此問題。 我們首先映射一個(gè)雙向的一對(duì)多關(guān)聯(lián),并以多對(duì)一的一方為擁有方。
private List<Officer> officers = new ArrayList<Officer>(); @OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);} protected void setOfficers(List<Officer> officers) {this.officers = officers;} public void addOfficer(Officer officer) {this.officers.add(officer);}現(xiàn)在,我們?cè)俅沃匦逻\(yùn)行相同的測(cè)試,并再次檢查輸出。
Hibernate: insert into Starship (affiliationEnum, launched, height, length, power, width, registry, starshipClassEnum, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?)Before Find Starship By IdHibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ from Starship starship0_ where starship0_.id=?After Find Starship By Id and Before CommitHibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_ from Officer officers0_ where officers0_.starship_id=?After commit盡管我們已將SQL語(yǔ)句的數(shù)量從25個(gè)減少到10個(gè),但仍然有不必要的查詢,這些查詢僅位于第二個(gè)事務(wù)的commit部分中。 為什么如果默認(rèn)情況下軍官是懶惰的( JPA規(guī)范),而我們又沒有讓軍官參與交易,那么Hibernate會(huì)在“軍官”表上執(zhí)行選擇嗎? 出于與先前配置相同的原因,返回的集合具有不同的Java標(biāo)識(shí)符,因此Hibernate將其標(biāo)記為新實(shí)例化的集合,但是現(xiàn)在顯然不再需要連接表操作。 我們減少了查詢數(shù)量,但是仍然存在性能問題。 可能我們需要其他解決方案,而該解決方案不是最明顯的解決方案,我們不會(huì)返回Hibernate返回的集合對(duì)象,我們稍后可能會(huì)對(duì)此進(jìn)行擴(kuò)展,但是我們將更改批注的位置。
我們要做的是將映射位置從屬性方法更改為使用字段映射。 簡(jiǎn)單來(lái)說(shuō),我們將所有注釋移至類屬性,而不是getter上 。
@Entity public class Starship {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@Temporal(TemporalType.DATE) private Date launched;public Date getLaunched() {return launched;}public void setLaunched(Date launched) {this.launched = launched;}...@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) private List<Officer> officers = new ArrayList<Officer>();public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}public Starship() {super();}public Starship(String registry) {setRegistry(registry);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result+ ((registry == null) ? 0 : registry.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Starship other = (Starship) obj;if (registry == null) {if (other.registry != null)return false;} else if (!registry.equals(other.registry))return false;return true;} }@Entity public class Officer {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@Column(unique=true, nullable=false) private String name;public String getName() {return this.name;}public void setName(String name) {this.name = name;}@Enumerated private SpeciesEnum speciesEnum;public SpeciesEnum getSpeciesEnum() {return speciesEnum;}public void setSpeciesEnum(SpeciesEnum speciesEnum) {this.speciesEnum = speciesEnum;}...@ManyToOne private Starship starship; public Starship getStarship() {return starship;}protected void setStarship(Starship starship) {this.starship = starship;}public Officer() {super();}public Officer(String name, RankEnum rank) {setName(name);setRank(rank);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Officer other = (Officer) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;} }最后,我們將再次運(yùn)行測(cè)試,看看會(huì)發(fā)生什么:
Hibernate: insert into Starship (affiliationEnum, launched, height, length, power, width, registry, starshipClassEnum, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?) Hibernate: insert into Officer (affiliationEnum, homePlanet, name, rank, speciesEnum, starship_id, id) values (?, ?, ?, ?, ?, ?, ?)Before Find Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_ from Starship starship0_ where starship0_.id=?After Find Before Commit After commit為什么使用屬性映射Hibernate在提交期間運(yùn)行查詢,而未執(zhí)行使用字段映射? 提交事務(wù)后,Hibernate執(zhí)行刷新操作,以使基礎(chǔ)持久性存儲(chǔ)與內(nèi)存中保持的可持久狀態(tài)同步。 當(dāng)使用屬性映射時(shí),Hibernate調(diào)用getter / setter方法來(lái)同步數(shù)據(jù),對(duì)于getOfficers方法,它將返回一個(gè)臟集合(由于進(jìn)行了unmodifiableList調(diào)用)。 另一方面,當(dāng)我們使用字段映射時(shí), Hibernate直接獲取字段,因此收集不被認(rèn)為是骯臟的,不需要重新創(chuàng)建。
但是我們還沒有完成,我想您想知道為什么我們還沒有從getter中刪除Collections.unmodifiableList,而是返回Hibernate集合? 是的,我同意您的意見,我們很快完成了工作,更改看起來(lái)像@ OneToMany(cascade = {CascadeType.ALL} )public List <Officer> getOfficers(){ 但返回原始集合最終會(huì)導(dǎo)致封裝問題,實(shí)際上我們的封裝已損壞! 我們可以將任何我們喜歡的東西添加到可變列表中; 我們可以將不受控制的更改應(yīng)用于對(duì)象的內(nèi)部狀態(tài)。
使用unmodifiableList是避免破壞封裝的一種方法,但是我們當(dāng)然可以對(duì)公共訪問和Hibernate訪問使用不同的訪問器,而不用調(diào)用Collections.unmodifiableList方法。
考慮到我們今天所看到的,我建議您使用始終字段注釋而不是屬性映射,我們將避免很多意外。
希望您發(fā)現(xiàn)這篇文章有用。
此示例的屏幕截圖:
下載代碼
參考: Hibernate性能提示: JCG合作伙伴的 臟回收效應(yīng) ? 在一個(gè)罐子統(tǒng)治他們所有博客的亞歷克斯·索托。
翻譯自: https://www.javacodegeeks.com/2012/03/hibernate-performance-tips-dirty.html
hibernate臟數(shù)據(jù)
總結(jié)
以上是生活随笔為你收集整理的hibernate脏数据_Hibernate性能提示:脏收集效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 汽车抵押车管所备案流程(汽车抵押车管所备
 - 下一篇: 预防服务器ddos攻击(预防服务器ddo