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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

spring(11)使用对象-关系映射持久化数据

發(fā)布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring(11)使用对象-关系映射持久化数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README 1)本文部分文字描述轉自:“Spring In Action(中/英文版)”,旨在review ?“spring(11)使用對象-關系映射持久化數據”?的相關知識;
【2】spring 與 java 持久化API 1)intro:JPA全稱Java Persistence API.JPA通過JDK 5.0注解或XML描述對象-關系表的映射關系,并將運行期的實體對象持久化到數據庫中。 2)在spring中使用 JPA 第一步是要在 spring應用上下文中將 實體管理器工廠 按照bean 的形式來進行配置;(干貨——引入了實體管理器工廠)
【2.1】配置實體管理器工廠 ? ? ? ? 1)intro:基于JPA的應用程序需要使用 EntityManagerFactory的實現類來獲取 EntityManager實例。JPA 定義了 兩種類型的實體管理器: type1)應用程序管理類型:當應用程序向實體管理器工廠直接請求實體管理器時,工廠會創(chuàng)建一個實體管理器。在這種模式下,程序要負責打開或關閉實體管理器并在事務中對其進行控制。這種方式的實體管理器適合于不運行在 java ee 容器中的獨立應用程序; type2)容器管理類型:實體管理器由java ee 創(chuàng)建和管理。應用程序根本不與實體管理器工程打交道。相反,實體管理器直接通過注入或JNDI 來獲取。容器負責配置實體管理器工廠。這種類型的實體管理器最適用于 java ee 容器,在這種case下 會希望在 ?persistence.xml 指定的 JPA 配置之外保持一些自己對 JPA的控制;(干貨——容器管理類型的實體管理器最適用于 java ee 容器) 2)以上兩種實體管理器實現了同一個接口 EntityManager。關鍵的區(qū)別在于 ?EntityManager 的創(chuàng)建和管理方式。?應用程序管理類型的 EntityManager由 EntityManagerFactory 創(chuàng)建的,EntityManagerFactory?是由 PersistenceProvider.createEntityManagerFactory() 方法得到的;而 容器管理類型的 EntityManagerFactorys 是通過 PersistenceProvider.createContainerEntityManagerFactory()方法得到的;(干貨——應用程序管理類型和容器管理類型的實體管理器的關鍵區(qū)別在于 ?EntityManager 的創(chuàng)建和管理方式)
3)這兩種實體管理器工廠分別由對應的 spring 工廠 bean 創(chuàng)建: type1)LocalEntityManagerFactoryBean: 生成應用程序管理類型的 EntityManagerFactory; type2)LocalContainerEntityManagerFactoryBean: 生成容器管理類型的 EntityManagerFactory;
Attention)應用程序管理類型和容器管理類型的實體管理器工廠間唯一值得關注的區(qū)別是:在 spring 應用上下文中如何進行配置;
【2.1.1】配置應用程序管理類型的JPA 1)intro:對于應用程序管理類型的實體管理器工廠來說,它絕大部分配置信息來源于一個 名為 persistence.xml 的配置文件,這個文件必須位于 類路徑下的 META-INF 目錄下; 2)下面是一個典型的 persistence.xml 文件: <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence"version="1.0"><persistence-unit name="spitterPU"><class>com.habuma.spittr.domain.Spitter</class><class>com.habuma.spittr.domain.Spittle</class><properties><property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver" /><property name="toplink.jdbc.url"value="jdbc:hsqldb:hsql://localhost/spitter/spitter" /><property name="toplink.jdbc.user" value="sa" /><property name="toplink.jdbc.password" value="" /></properties></persistence-unit> </persistence> 3)可以通過如下的 @Bean注解方法在spring中聲明 LocalEntityManagerFactoryBean:

【2.1.2】使用容器管理類型的JPA 1)intro:容器管理的JPA 采取了一個不同的方式。當運行在容器中時,可以使用容器提供的信息來生成 EntityManagerFactory; 2)你可以將 數據源信息配置在 spring應用上下文中,而不是在 persistence.xml 中了。如下的@Bean 注解方法聲明了在 spring中如何使用 LocalContainerEntityManagerFactoryBean 來配置容器管理類型的 JPA:
對以上代碼的分析(Analysis):? A1)這里,我們使用了 spring配置的數據源來設置 datasource屬性。任何 javax.sql.DataSource 的實現都是可以的; A2)jpaVendorApapter屬性:用于指明所使用的是哪一個廠商的JPA 實現,spring提供了多個 JPA 廠商適配器: adapter1)EclipseLinkJpaVendorAdapter adapter2)HibernateJpaVendorAdapter adapter3)OpenJpaVendorAdapter adapter4)TopLinkJpaVendorAdapter (deprecated in Spring 3.1)
【2.1.3】從JNDI 獲取實體管理器工廠 1)intro:如果將spring應用程序部署在應用server中, 則 EntityManagerFactory 可能已經被創(chuàng)建好了,并且位于 JNDI 中等待查詢使用; 2)在這種case下,可以使用 spring jee 命名空間下的 <jee: jndi-lookup>元素來獲取對 EntityManagerFactory 的引用: <jee:jndi-lookup id="emf" jndi-name="persistence/spitterPU" /> 3)可以使用 java Config 來獲取?EntityManagerFactory?: @Bean public JndiObjectFactoryBean entityManagerFactory() {}JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();jndiObjectFB.setJndiName("jdbc/SpittrDS");return jndiObjectFB; } 對以上代碼的分析(Analysis): 因為上述方法返回的?JndiObjectFactoryBean?是 FactoryBean 接口的實現,它能夠創(chuàng)建 EntityManagerFactory; Attention)自此,我們就得到了?EntityManagerFactory 對象了;
【2.2】編寫基于 JPA 的 Repository 1)intro:spring 對 JPA 集成也提供了JpaTemplate 模板以及對應的支持類 JpaDaoSupport; 2)鑒于純粹的JPA 方式遠遠勝于基于模板的 JPA,所以在本節(jié)中我們將會重點關注如何構建不依賴spring 的 JPA Repository。如下程序中的 JpaSpitterRepository 展現了 如何開發(fā)不使用 spring JpaTemplate 的 JPA Repository; @Repository @Transactional public class JpaSpitterRepository implements SpitterRepository {@PersistenceUnitprivate EntityManagerFactory emf;public void addSpitter(Spitter spitter) {emf.createEntityManager().persist(spitter);}public Spitter getSpitterById(long id) {return emf.createEntityManager().find(Spitter.class, id);}public void saveSpitter(Spitter spitter) {emf.createEntityManager().merge(spitter);}... } 對以上代碼的分析(Analysis):
A1)@PersistenceUnit注解:spring會將 EntityManagerFactory 注入到 Repository中;(干貨——注解@PersistenceUnit的作用 A2)有了 EntityManagerFactory之后,JpaSpitterRepository 的方法就能夠使用它來創(chuàng)建 EntityManager了,然后 EntityManager 可以針對數據庫執(zhí)行操作; A3)JpaSpitterRepository?唯一的問題:在于每個方法都會調用createEntityManager()方法;
3)下面的程序展現了 如何借助 @PersistenceContext注解為 JpaSpitterRepository 設置 EntityManager; @Repository @Transactional public class JpaSpitterRepository implements SpitterRepository {@PersistenceContextprivate EntityManager em;public void addSpitter(Spitter spitter) {em.persist(spitter);}public Spitter getSpitterById(long id) {return em.find(Spitter.class, id);}public void saveSpitter(Spitter spitter) {em.merge(spitter);}... } 對以上代碼的分析(Analysis): A0)@Transactional注解的作用: 表明這個 Repository中的持久化方法是在事務上下文中執(zhí)行的;(干貨——@Transactional注解的作用 A1)由于沒有使用模板類來處理異常,所以我們需要為 Repository添加 @Repository 注解,這樣PersistenceAnnotationBeanPostProcessor 就會知道要將這個bean 產生 的異常轉換為 spring 的統(tǒng)一數據訪問異常; A2)在上面的JpaSpitterRepository?中,直接為其設置了?EntityManager?;這樣的話,每個方法中就沒有必須再通過 EntityManagerFactory 創(chuàng)建 EntityManager了;(盡管這種方式非常便利,但你可能會擔心注入的EntityManager?會有?線程安全問題) A3)這里的真相是:@PersistenceContext 并不會真正注入?EntityManager;它沒有將真正的?EntityManager 設置給 Repository,而是給了它一個?EntityManager 的代理;真正的EntityManager 是與當前事務相關聯(lián)的那一個,如果不存在這樣的?EntityManager 的話,就會創(chuàng)建一個新的。這樣的話,我們就能始終以 線程安全的方式提供實體管理器了;
4)需要了解 @PersistenceUnit and @PersistenceContext 并不是spring 的注解,而是 JPA規(guī)范提供的。 4.1)為了讓spring理解 這些注解,并注入 EntityManagerFactory or EntityManager,我們必須要配置 spring 的 PersistenceAnnotationBeanPostProcessor ; 4.2)如果你已經使用了 <context:annotation-config> or <context:component-scan>,那么你不必擔心了,因為這些配置元素會自動注冊 PersistenceAnnotationBeanPostProcessor bean;否則的話,我們就要顯示地注入這個 bean; @Bean public PersistenceAnnotationBeanPostProcessor paPostProcessor() {return new PersistenceAnnotationBeanPostProcessor(); }

總結

以上是生活随笔為你收集整理的spring(11)使用对象-关系映射持久化数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。