版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
高頻jpa面試題及答案Q:JPA的核心設(shè)計目標(biāo)是什么?與Hibernate的關(guān)系如何?A:JPA(JavaPersistenceAPI)是JavaEE/JavaSE標(biāo)準(zhǔn)的ORM(對象關(guān)系映射)規(guī)范,核心目標(biāo)是通過統(tǒng)一的接口和注解簡化Java對象與數(shù)據(jù)庫的映射操作,消除不同ORM框架的使用差異。JPA本身是規(guī)范,Hibernate是其具體實現(xiàn)之一(還包括EclipseLink、OpenJPA等)。Hibernate在JPA規(guī)范基礎(chǔ)上擴(kuò)展了特有功能(如HQL、二級緩存策略),但企業(yè)開發(fā)中通常優(yōu)先使用JPA標(biāo)準(zhǔn)接口,以降低對具體實現(xiàn)的依賴,提升可移植性。例如,使用@Entity、@Id等JPA標(biāo)準(zhǔn)注解定義實體,而不是Hibernate特有的@Type注解,這樣切換ORM實現(xiàn)時只需調(diào)整配置,無需修改業(yè)務(wù)代碼。Q:@Entity、@Table、@Id、@GeneratedValue注解的作用分別是什么?A:@Entity標(biāo)記一個類為JPA實體,告知JPA該類需要與數(shù)據(jù)庫表映射(默認(rèn)表名與類名相同,大小寫敏感)。@Table用于顯式指定實體對應(yīng)的表名(name屬性)、模式(schema屬性)或索引(indexes屬性),例如@Table(name="user_info",schema="public")表示實體映射到public模式下的user_info表。@Id標(biāo)記實體的主鍵字段,JPA要求每個實體必須有一個主鍵。@GeneratedValue用于指定主鍵的提供策略,常見策略包括:IDENTITY:依賴數(shù)據(jù)庫自增(如MySQL的AUTO_INCREMENT),由數(shù)據(jù)庫自動提供主鍵值;SEQUENCE:使用數(shù)據(jù)庫序列(如Oracle的SEQUENCE),需配合@SequenceGenerator指定序列名稱和初始值;TABLE:通過一張專用表存儲主鍵提供值(兼容性強(qiáng)但性能較差);AUTO(默認(rèn)):由JPA實現(xiàn)自動選擇(如Hibernate會根據(jù)數(shù)據(jù)庫類型選擇IDENTITY或SEQUENCE)。實際開發(fā)中,互聯(lián)網(wǎng)項目常用IDENTITY(簡單高效),金融類項目可能用SEQUENCE(支持分布式主鍵)。Q:EntityManager的主要職責(zé)有哪些?persist()與merge()方法的區(qū)別是什么?A:EntityManager是JPA操作的核心接口,負(fù)責(zé)管理持久化上下文(PersistenceContext),主要職責(zé)包括:實體的增刪改查(CRUD);事務(wù)管理(需配合Transaction或Spring的@Transactional);同步持久化上下文與數(shù)據(jù)庫(flush操作);執(zhí)行JPQL/Criteria查詢。persist()與merge()的核心區(qū)別在于對實體狀態(tài)的影響:persist():將“新建狀態(tài)”(Transient)的實體轉(zhuǎn)換為“管理狀態(tài)”(Managed),直接向數(shù)據(jù)庫插入新記錄。若傳入“游離狀態(tài)”(Detached)的實體(已被持久化但會話關(guān)閉),會拋出IllegalArgumentException。merge():用于合并“游離狀態(tài)”的實體。它會先根據(jù)主鍵查詢數(shù)據(jù)庫中是否存在該實體:若存在,將游離實體的屬性復(fù)制到管理實體并返回;若不存在(類似persist),則創(chuàng)建新的管理實體并插入。因此,merge()的返回值是新的管理實體,原游離實體仍保持游離狀態(tài)。例如,會話1加載實體A(管理狀態(tài)),會話關(guān)閉后A變?yōu)橛坞x狀態(tài)。在會話2中調(diào)用persist(A)會報錯,而調(diào)用merge(A)會查詢數(shù)據(jù)庫是否存在A的主鍵,若存在則更新,不存在則插入,最終返回新的管理實體。Q:持久化上下文的四種狀態(tài)是什么?狀態(tài)轉(zhuǎn)換的觸發(fā)條件是什么?A:持久化上下文(PersistenceContext)是JPA的核心緩存層,負(fù)責(zé)跟蹤實體狀態(tài)變化。實體有四種狀態(tài):1.新建狀態(tài)(Transient):未被持久化上下文管理,且數(shù)據(jù)庫中無對應(yīng)記錄(如newUser()創(chuàng)建的對象)。2.管理狀態(tài)(Managed):被持久化上下文管理,數(shù)據(jù)庫中有對應(yīng)記錄(通過EntityManager.find()加載或persist()后的實體)。3.游離狀態(tài)(Detached):曾被管理,但因持久化上下文關(guān)閉(如EntityManager.close())或調(diào)用clear()/detach()方法,不再被管理,但數(shù)據(jù)庫中仍有記錄。4.刪除狀態(tài)(Removed):被標(biāo)記為刪除(調(diào)用remove()方法),事務(wù)提交時會執(zhí)行DELETE語句。狀態(tài)轉(zhuǎn)換觸發(fā)條件:Transient→Managed:調(diào)用persist()或merge()(僅當(dāng)數(shù)據(jù)庫無對應(yīng)記錄時)。Managed→Detached:調(diào)用clear()/detach()或關(guān)閉EntityManager。Managed→Removed:調(diào)用remove()。Detached→Managed:調(diào)用merge()(返回新的管理實體)。Removed→數(shù)據(jù)庫刪除:事務(wù)提交時。理解狀態(tài)轉(zhuǎn)換是避免“臟檢查”(DirtyChecking)失效的關(guān)鍵。例如,管理狀態(tài)的實體修改屬性后,事務(wù)提交時JPA會自動提供UPDATE語句(基于臟檢查),但游離狀態(tài)的實體修改屬性不會觸發(fā)自動更新,必須通過merge()合并后才會同步。Q:JPQL與SQL的區(qū)別是什么?如何防止JPQL注入?A:JPQL(JavaPersistenceQueryLanguage)是JPA定義的面向?qū)ο蟛樵冋Z言,與SQL的核心區(qū)別:操作對象不同:JPQL操作實體類和屬性(如SELECTuFROMUseruWHERE=?),SQL操作數(shù)據(jù)庫表和字段(如SELECTFROMuserWHEREname=?)。支持繼承映射:JPQL可直接查詢繼承體系中的實體(如SELECTpFROMPersonpWHERETYPE(p)=Employee),SQL需通過UNION或JOIN處理。函數(shù)與關(guān)鍵字:JPQL支持部分SQL函數(shù)(如LENGTH、SUBSTRING),但擴(kuò)展了JPQL特有關(guān)鍵字(如TYPE、MEMBEROF)。防止JPQL注入的方法與SQL類似,優(yōu)先使用參數(shù)化查詢(NamedParameter),避免拼接字符串。例如:錯誤寫法:Stringjpql="SELECTuFROMUseruWHERE='"+userName+"'";正確寫法:Queryquery=em.createQuery("SELECTuFROMUseruWHERE=:name");query.setParameter("name",userName);JPA會對參數(shù)進(jìn)行類型安全檢查,避免惡意字符直接拼入SQL。若必須動態(tài)拼接(如動態(tài)條件),需使用CriteriaAPI構(gòu)建類型安全的查詢,或?qū)斎雲(yún)?shù)進(jìn)行嚴(yán)格校驗(如正則匹配)。Q:@ManyToOne、@OneToMany、@ManyToMany注解的級聯(lián)操作(CascadeType)如何選擇?需要注意什么?A:級聯(lián)操作(CascadeType)用于定義對主實體的操作是否自動應(yīng)用到關(guān)聯(lián)實體。常見CascadeType選項:ALL:包含PERSIST、MERGE、REMOVE、REFRESH、DETACH的所有操作。PERSIST:保存主實體時自動保存關(guān)聯(lián)實體(避免手動調(diào)用persist()關(guān)聯(lián)實體)。MERGE:合并主實體時自動合并關(guān)聯(lián)實體(適用于游離狀態(tài)的關(guān)聯(lián)實體)。REMOVE:刪除主實體時自動刪除關(guān)聯(lián)實體(需謹(jǐn)慎,可能導(dǎo)致級聯(lián)刪除鏈過長)。REFRESH:刷新主實體時自動刷新關(guān)聯(lián)實體(從數(shù)據(jù)庫重新加載最新數(shù)據(jù))。DETACH:分離主實體時自動分離關(guān)聯(lián)實體(較少使用)。選擇建議:父子關(guān)系(如訂單-訂單項):通常用CascadeType.ALL,因為訂單項無法獨立于訂單存在。多對多關(guān)系(如用戶-角色):避免使用REMOVE,否則刪除用戶會刪除角色(角色可能被其他用戶引用),一般用PERSIST/MERGE。單向關(guān)聯(lián)與雙向關(guān)聯(lián):雙向關(guān)聯(lián)需在一端用mappedBy指定關(guān)系的擁有方(如@OneToMany(mappedBy="user")),級聯(lián)操作應(yīng)加在關(guān)系擁有方(@ManyToOne側(cè)),否則可能導(dǎo)致關(guān)聯(lián)數(shù)據(jù)不同步。注意事項:級聯(lián)操作可能引發(fā)性能問題(如級聯(lián)保存大量關(guān)聯(lián)實體導(dǎo)致單次事務(wù)數(shù)據(jù)量過大),或意外數(shù)據(jù)丟失(如級聯(lián)刪除時未正確評估依賴關(guān)系)。生產(chǎn)環(huán)境中建議顯式指定需要的CascadeType,而非直接使用ALL。Q:如何解決JPA查詢中的N+1問題?A:N+1問題通常發(fā)生在關(guān)聯(lián)對象的懶加載(FetchType.LAZY)場景:查詢主實體列表(1次查詢),遍歷列表時逐個加載關(guān)聯(lián)對象(N次查詢),總查詢次數(shù)為N+1。例如:List<Order>orders=em.createQuery("SELECToFROMOrdero",Order.class).getResultList();for(Orderorder:orders){order.getItems().size();//觸發(fā)訂單項懶加載,每次查詢1次}解決方法:1.使用JOINFETCH:在JPQL中通過LEFTJOINFETCH或INNERJOINFETCH將關(guān)聯(lián)對象一次性加載。例如:SELECToFROMOrderoLEFTJOINFETCHo.itemsWHEREo.userId=:userId這樣只需1次查詢,將訂單和訂單項通過JOIN一次性加載。2.調(diào)整FetchType為EAGER:將關(guān)聯(lián)字段的FetchType設(shè)為EAGER(立即加載),但可能導(dǎo)致冗余數(shù)據(jù)(如查詢訂單時總是加載訂單項,即使不需要),需權(quán)衡使用場景。3.批量抓?。˙atchFetching):通過@BatchSize注解設(shè)置批量加載數(shù)量。例如在@OneToMany注解中添加@BatchSize(size=10),則加載10個訂單時,會一次性加載這10個訂單的訂單項(僅需2次查詢:1次訂單,1次批量訂單項)。Hibernate默認(rèn)支持此優(yōu)化,配置方式為在實體類或關(guān)聯(lián)字段添加@BatchSize。4.啟用二級緩存:對頻繁查詢且不常修改的關(guān)聯(lián)對象,啟用二級緩存(如Hibernate的Ehcache),減少數(shù)據(jù)庫查詢次數(shù)。實際開發(fā)中,JOINFETCH和批量抓取是最常用的解決方案,需根據(jù)具體業(yè)務(wù)場景選擇(如數(shù)據(jù)量大小、查詢頻率)。Q:@Version注解的作用是什么?如何實現(xiàn)樂觀鎖?A:@Version注解用于標(biāo)記一個字段作為版本號,實現(xiàn)樂觀鎖機(jī)制。樂觀鎖假設(shè)并發(fā)沖突概率低,通過版本號檢測數(shù)據(jù)是否被其他事務(wù)修改。具體流程:1.加載實體時,JPA會將版本號(如version字段)從數(shù)據(jù)庫讀取到實體中。2.修改實體屬性后,事務(wù)提交時,JPA會執(zhí)行UPDATE語句,并在WHERE子句中檢查版本號是否與加載時一致。3.若一致(說明未被其他事務(wù)修改),更新實體并遞增版本號;若不一致(版本號已變化),拋出OptimisticLockException異常。示例:@EntitypublicclassProduct{@Id@GeneratedValueprivateLongid;privateStringname;@VersionprivateIntegerversion;//getters/setters}當(dāng)兩個事務(wù)同時修改同一Product時:事務(wù)1加載Product(version=1),修改name為"A",提交時執(zhí)行UPDATEproductSETname='A',version=2WHEREid=1ANDversion=1(成功,version變?yōu)?)。事務(wù)2加載Product(version=1),修改name為"B",提交時執(zhí)行UPDATEproductSETname='B',version=2WHEREid=1ANDversion=1(此時數(shù)據(jù)庫version已為2,條件不滿足,更新行數(shù)為0,JPA檢測到后拋出異常)。樂觀鎖適用于讀多寫少的場景(如商品庫存查詢),相比悲觀鎖(SELECTFORUPDATE),能減少數(shù)據(jù)庫鎖競爭,提升并發(fā)性能。Q:JPA的一級緩存和二級緩存有什么區(qū)別?如何配置二級緩存?A:一級緩存(PersistenceContextCache)是JPA內(nèi)置的、與EntityManager綁定的緩存,生命周期與EntityManager一致。它存儲管理狀態(tài)的實體,確保同一EntityManager中多次查詢同一實體時僅執(zhí)行一次數(shù)據(jù)庫查詢(通過主鍵查詢時直接從緩存返回)。一級緩存無法手動關(guān)閉,是JPA的核心特性,用于提升單會話內(nèi)的查詢性能。二級緩存(SecondLevelCache)是進(jìn)程級或集群級的緩存,與EntityManagerFactory綁定,多個EntityManager可共享緩存數(shù)據(jù)。它存儲實體或?qū)嶓w集合,需顯式配置啟用。二級緩存適用于頻繁查詢、不常修改的數(shù)據(jù)(如字典表、地區(qū)數(shù)據(jù))。Hibernate作為JPA實現(xiàn)時,配置二級緩存的步驟:1.在persistence.xml中啟用二級緩存:<propertyname="hibernate.cache.use_second_level_cache"value="true"/><propertyname="hibernate.cache.region.factory_class"value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>2.添加緩存依賴(如Ehcache的JAR包)。3.在實體類上添加@Cache注解指定緩存策略:@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)publicclassDict{...}常用緩存并發(fā)策略:READ_ONLY:適用于從不修改的數(shù)據(jù)(如靜態(tài)字典);READ_WRITE:支持讀寫,通過版本號或時間戳保證一致性(最常用);NONSTRICT_READ_WRITE:寬松的讀寫,不保證強(qiáng)一致性(適用于允許短暫臟讀的場景);TRANSACTIONAL:事務(wù)級緩存(僅支持JTA事務(wù))。注意:二級緩存可能引入數(shù)據(jù)一致性問題,需結(jié)合業(yè)務(wù)場景評估是否啟用,避免緩存臟數(shù)據(jù)。Q:@MappedSuperclass與@Embeddable的區(qū)別是什么?A:@MappedSuperclass和@Embeddable都用于復(fù)用實體的公共屬性,但使用場景不同:@MappedSuperclass:標(biāo)記一個非實體的父類,子類實體繼承其屬性并映射到各自的數(shù)據(jù)庫表中。父類本身不是實體(無@Entity注解),不會提供對應(yīng)的數(shù)據(jù)庫表。例如:@MappedSuperclasspublicclassBaseEntity{@Id@GeneratedValueprivateLongid;privateLocalDateTimecreateTime;}@EntitypublicclassUserextendsBaseEntity{privateStringusername;}此時User表會包含id、createTime、username字段,BaseEntity無對應(yīng)表。@Embeddable:標(biāo)記一個可嵌入的類,其屬性會被嵌入到其他實體的表中,共享同一表結(jié)構(gòu)。嵌入類需用@Embedded注解在目標(biāo)實體中聲明。例如:@EmbeddablepublicclassAddress{privateStringprovince;privateStringcity;}@EntitypublicclassUser{@IdprivateLongid;@EmbeddedprivateAddressaddress;}此時User表會包含id、province、city字段(Address的屬性被嵌入)。總結(jié):@MappedSuperclass用于垂直繼承(父子類共享屬性,各子類有獨立表),@Embeddable用于水平組合(多個屬性封裝為一個類,嵌入到主實體表中)。Q:JPA如何處理枚舉類型?@Enumerated注解的使用方式有哪些?A:JPA通過@Enumerated注解指定枚舉類型的存儲方式,支持兩種策略:EnumType.ORDINAL(默認(rèn)):存儲枚舉的索引(從0開始)。例如枚舉Color{RED,GREEN,BLUE}會存儲為0、1、2。EnumType.STRING:存儲枚舉的名稱(如"RED"、"GREEN"、"BLUE")。示例:publicenumGender{MALE,FEMALE}@EntitypublicclassUser{@IdprivateLongid;@Enumerated(EnumType.STRING)//存儲枚舉名稱privateGendergender;}選擇建議:ORDINAL:存儲空間小(整數(shù)),但枚舉順序變更會導(dǎo)致歷史數(shù)據(jù)錯誤(如新增枚舉值在中間位置,索引改變)。STRING:存儲空間較大(字符串),但枚舉名稱變更需同步修改數(shù)據(jù)庫數(shù)據(jù)(否則查詢會失?。?,但比ORDINAL更安全(順序變更不影響歷史數(shù)據(jù))。生產(chǎn)環(huán)境中推薦使用STRING策略,避免枚舉順序變更導(dǎo)致的兼容性問題。若需更靈活的映射(如自定義枚舉值與數(shù)據(jù)庫值的對應(yīng)關(guān)系),可結(jié)合@Converter注解自定義枚舉轉(zhuǎn)換器。Q:EntityManager的flush()和clear()方法有什么作用?觸發(fā)flush的時機(jī)有哪些?A:flush()方法用于強(qiáng)制將持久化上下文中的修改同步到數(shù)據(jù)庫(執(zhí)行INSERT/UPDATE/DELETE語句),但不會提交事務(wù)。它的主要用途是在事務(wù)提交前手動同步數(shù)據(jù)(如需要立即獲取數(shù)據(jù)庫提供的主鍵,或在批量操作中分批提交以減少內(nèi)存占用)。clear()方法用于清空持久化上下文,將所有管理狀態(tài)的實體轉(zhuǎn)為游離狀態(tài)。調(diào)用clear()后,EntityManager不再跟蹤任何實體的變化,后續(xù)對這些實體的修改不會觸發(fā)臟檢查和自動更新。觸發(fā)flush的時機(jī)(即使未顯式調(diào)用flush()):1.事務(wù)提交(commit())時,JPA會自動flush以保證數(shù)據(jù)一致性。2.執(zhí)行JPQL/Criteria查詢時(除了SELECTCOUNT()等不返回實體的查詢),為避免查詢到舊數(shù)據(jù),JPA會先flush持久化上下文中的修改。3.顯式調(diào)用flush()方法。例如,在一個事務(wù)中先執(zhí)行em.persist(user),再執(zhí)行em.createQuery("SELECTuFROMUseru").getResultList(),此時JPA會先flush插入操作,確保查詢能返回剛插入的user。Q:JPA的悲觀鎖如何實現(xiàn)?與樂觀鎖的適用場景有何不同?A:悲觀鎖通過數(shù)據(jù)庫的鎖機(jī)制實現(xiàn),假設(shè)并發(fā)沖突概率高,在查詢時直接鎖定數(shù)據(jù),防止其他事務(wù)修改。JPA中通過LockModeType指定悲觀鎖類型,常用模式:LockModeType.PESSIMISTIC_READ:讀鎖(共享鎖),允許其他事務(wù)讀取但禁止修改。LockModeType.PESSIMISTIC_WRITE:寫鎖(排他鎖),禁止其他事務(wù)讀取和修改(具體行為依賴數(shù)據(jù)庫實現(xiàn))。實現(xiàn)方式:在查詢時指定鎖模式,例如:Useruser=em.find(User.class,1L,LockModeType.PESSIMISTIC_WRITE);或通過JPQL查詢:Queryquery=em.createQuery("SELECTuFROMUseruWHEREu.id=:id");query.setParameter("id",1L);query.setLockMode(LockModeType.PESSIMISTIC_WRITE);Useruser=(User)query.getSingleResult();悲觀鎖與樂觀鎖的適用場景:悲觀鎖:適用于寫多讀少、對數(shù)據(jù)一致性要求極高的場景(如銀行轉(zhuǎn)賬),通過數(shù)據(jù)庫鎖直接阻塞沖突事務(wù),保證強(qiáng)一致性,但可能降低并發(fā)性能。樂觀鎖:適用于讀多寫少、允許一定沖突的場景(如商品詳情頁),通過版本號檢測沖突,減少鎖競爭,提升并發(fā)能力,但需要處理異常(如重試機(jī)制)。注意:悲觀鎖的效果依賴數(shù)據(jù)庫實現(xiàn)(如MySQL的InnoDB支持行鎖,MyISAM僅支持表鎖),使用時需結(jié)合具體數(shù)據(jù)庫特性。Q:@Transient注解的作用是什么?與Hibernate的@Formula有何區(qū)別?A:@Transient是JPA標(biāo)準(zhǔn)注解,標(biāo)記一個字段不需要映射到數(shù)據(jù)庫表(即不參與持久化)。該字段的值不會被JPA存儲或加載,通常用于臨時計算屬性(如根據(jù)其他字段動態(tài)計算的總金額)。例如:@EntitypublicclassOrder{privateBigDecimalamount;@TransientprivateBigDecimaltax;//不存儲到數(shù)據(jù)庫,僅用于業(yè)務(wù)計算publicBigDecimalgetTax(){returnamount.multiply(newBigDecimal("0.05"));//5%稅率}}@Formula是Hibernate的擴(kuò)展注解(非JPA標(biāo)準(zhǔn)),用于定義一個計算列,其值由數(shù)據(jù)庫表達(dá)式動態(tài)提供。例如:@Entity@org.hibernate.annotations.Formula("(amount0.05)")privateBigDecimaltax;區(qū)別:@Transient:值在Java內(nèi)存中計算,不與數(shù)據(jù)庫交互,查詢時不會包含該字段(需手動計算)。@Formula:值由數(shù)據(jù)庫在查詢時計算(通過SQL表達(dá)式),查詢結(jié)果中會包含該字段(如SELECT,(amount0.05)AStaxFROMorder),但無法修改(僅可讀)。選擇建議:若計算邏輯簡單且需在內(nèi)存中處理,用@Transient;若計算邏輯復(fù)雜(需利用數(shù)據(jù)庫函數(shù))或希望查詢時直接獲取結(jié)果,用@Formula(需注意對具體ORM實現(xiàn)的依賴)。Q:如何自定義JPA的字段映射(如將Java的LocalDateTime映射到數(shù)據(jù)庫的TIMESTAMP類型)?A:JPA2.2及以上版本支持Java8的時間類型(如LocalDateTime、LocalDate),Hibernate5.2+默認(rèn)提供了這些類型的映射器。若需自定義映射(如特殊格式的日期字符串),可通過@Converter注解實現(xiàn)自定義轉(zhuǎn)換器。步驟:1.實現(xiàn)AttributeConverter接口,定義轉(zhuǎn)換邏輯。例如,將LocalDateTime轉(zhuǎn)換為字符串(格式y(tǒng)yyy-MM-ddHH:mm:ss):@Converter(autoApply=true)//autoApply=true表示自動應(yīng)用到所有該類型字段publicclassLocalDateTimeConverterimplementsAttributeConverter<LocalDateTime,String>{privatestaticfinalDateTimeFormatterFORMATTER=DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss");@OverridepublicStringconvertToDatabaseColumn(LocalDateTimeattribute){returnattribute==null?null:FORMATTER.format(attribute);}@OverridepublicLocalDateTimeconvertToEntityAttribute(StringdbData){returndbData==null?null:LocalDateTime.parse(dbData,FORMATTER);}}2.在實體字段上添加@Convert注解(若autoApply=false):@Column(name="create_time")@Convert(converter=LocalDateTimeConverter.class)privateLocalDateTimecreateTime;autoApply=true時,轉(zhuǎn)換器會自動應(yīng)用到所有LocalDateTime類型的字段;否則需顯式用@Convert指定。自定義轉(zhuǎn)換器可用于處理枚舉、JSON對象(如將Java對象轉(zhuǎn)換為JSON字符串存儲)等場景。Q:JPA的事務(wù)管理有哪幾種方式?與Spring集成時如何選擇?A:JPA支持兩種事務(wù)管理方式:1.資源本地事務(wù)(Resource-LocalTransactions):由EntityManager的Transaction接口管理(em.getTransaction()),適用于獨立應(yīng)用(如JavaSE)或未使用全局事務(wù)管理器的場景。事務(wù)范圍僅限于單個數(shù)據(jù)庫連接,不支持分布式事務(wù)。2.JTA事務(wù)(JavaTransactionAPI):由應(yīng)用服務(wù)器(如WildFly)或Spring的JtaTransactionManager管理,支持分布式事務(wù)(跨多個數(shù)據(jù)源或資源)。JTA事務(wù)通過@Transactional注解聲明,事務(wù)管理器負(fù)責(zé)協(xié)調(diào)多個資源的提交或回滾。與Spring集成時,通常使用Spring的聲明式事務(wù)管理(@Transactional注解),底層根據(jù)配置選擇資源本地或JTA事務(wù):單數(shù)據(jù)源場景:使用DataSourceTransactionManager(資源本地事務(wù)),通過em.unwrap(Session.class)獲取HibernateSession并管理事務(wù)。多數(shù)據(jù)源或分布式事務(wù)場景:使用JtaTransactionManager(如結(jié)合Atomikos實現(xiàn)分布式事務(wù)),通過@Transactional注解聲明事務(wù)邊界。注意:Spring的@Transactional默認(rèn)回滾運(yùn)行時異常(RuntimeException)和錯誤(Error),可通過rollbackFor屬性指定需要回滾的異常類型(如checked異常)。Q:如何優(yōu)化JPA的批量插入性能?A:JPA默認(rèn)逐條插入數(shù)據(jù)(INSERT語句),批量插入時性能較低。優(yōu)化方法:1.啟用JDBC批量插入:在persistence.xml中配置Hibernate的批量插入?yún)?shù):<propertyname="hibernate.jdbc.batch_size"value="100"/><!-每次批量插入100條--><propertyname="hibernate.order_inserts"value="true"/><!-按主鍵順序排序插入,提升數(shù)據(jù)庫性能-->2.使用EntityManag
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年元宵節(jié)的歷史價值
- 2026年創(chuàng)業(yè)項目路演技巧培訓(xùn)
- 2026年建筑施工過程中突發(fā)事件處理的案例
- 2025年藝術(shù)系列高級職稱筆試及答案
- 2025年浙江mba 不用筆試及答案
- 2025年紹興市事業(yè)單位招聘考試及答案
- 2026年高效團(tuán)隊的扁平化工作模式總結(jié)
- 2025年市場局事業(yè)單位考試題及答案
- 2026年生態(tài)系統(tǒng)服務(wù)與工程地質(zhì)環(huán)境評價
- 2026年扁平化管理在商戰(zhàn)中的指南
- 資產(chǎn)接收協(xié)議書模板
- 華潤燃?xì)?026屆校園招聘“菁英計劃·管培生”全面開啟備考考試題庫及答案解析
- 數(shù)據(jù)中心合作運(yùn)營方案
- 印鐵涂料基礎(chǔ)知識
- 工資欠款還款協(xié)議書
- 石籠網(wǎng)廠施工技術(shù)交底
- 新建粉煤灰填埋場施工方案
- 2025至2030全球及中國經(jīng)顱刺激器行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢及投資規(guī)劃深度研究報告
- 中遠(yuǎn)海運(yùn)集團(tuán)筆試題庫2025
- 電力三種人安全培訓(xùn)課件
- 船舶生產(chǎn)許可管理辦法
評論
0/150
提交評論