在 Spring Data JPA 基本篇 談到 JPA 的基本作業,現在加入 Spring 的注入(Dependency Injection)來看,Spring 簡化程式碼有多少.
Step 01: DAO Interface: PersonSpringDataDao.java
package com.mis.demos.dao; import com.mis.demos.model.Person; public interface PersonSpringDataDao { public Person Save(Person person); } |
Step 02: DAO Implement: PersonSpringDataDaoImpl.java
package com.mis.demos.dao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.mis.demos.model.Person; @Repository("PersonSpringDataDao") public class PersonSpringDataDaoImpl implements PersonSpringDataDao { @PersistenceContext private EntityManager em; @Transactional public Person Save(Person person) { if (person.getId()==null) em.persist(person); else em.merge(person); return person; } } |
Step 03: Service Interface: PersonSpringDataService.java
package com.mis.demos.services; import com.mis.demos.model.Person; public interface PersonSpringDataService { public Person saveAccount(Person person); } |
Step 04: Service implement: PersonSpringDataServiceImpl.java , Spring 完成依賴注入,因此不再需要使用 new 操作符創建 PersonSpringDataDaoImpl 物件了
package com.mis.demos.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.mis.demos.dao.PersonSpringDataDao; import com.mis.demos.dao.PersonSpringDataDaoImpl; import com.mis.demos.model.Person; @Service("PersonSpringDataService") public class PersonSpringDataServiceImpl implements PersonSpringDataService { //private PersonSpringDataDao personSpringDataDao = new PersonSpringDataDaoImpl(); @Autowired private PersonSpringDataDao personSpringDataDao; @Transactional public Person saveAccount(Person person) { return personSpringDataDao.Save(person); } } |
Step 05: 建立 Spring 設定檔: spring-demo-cfg.xml ,它會去參考 META-INF\persistence.xml 裡的 persistence-unit ,只有一個 PU 時, 則為預設的 data source
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 聲明Spring要管理的範圍 --> <context:component-scan base-package="com.mis" /> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> </bean> </beans> |
Step 06: 測試
package com.mis.demos; import javax.annotation.Resource; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mis.demos.dao.PersonDao; import com.mis.demos.dao.PersonSpringDataDao; import com.mis.demos.model.Person; import com.mis.demos.services.PersonPU; import com.mis.demos.services.PersonService; import com.mis.demos.services.PersonSpringDataService; import com.mis.demos.services.PersonSpringDataServiceImpl; public class SimpleSpringJpaDemo { public static void main(String[] args) { doSpringDataJPASave(); } public static void doSpringDataJPASave(){ Person person = new Person(); person.setId(1); person.setFirstName("polin-9-12"); person.setLastName("wei-9-12"); ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-demo-cfg.xml"); //PersonSpringDataDao personSpringDataDao = ctx.getBean("PersonSpringDataDao",PersonSpringDataDao.class); //personSpringDataDao.Save(person); // 注意這裡是取得 Service Interface : PersonSpringDataService.java , 不是實作 PersonSpringDataServiceImpl.java PersonSpringDataService personSpringDataService = ctx.getBean("PersonSpringDataService",PersonSpringDataService.class); personSpringDataService.saveAccount(person); ctx.close(); } } |
由此可知,通過與 Spring Data JPA 基本篇 程式碼的對比,程式重構前後的代碼,可以發現 Spring 對 JPA 的簡化已經非常出色了,可以大致總結一下 Spring 框架對 JPA 提供的支援主要體現在如下幾個方面:
• 首先,它使得 JPA 配置變得更加靈活。JPA 規範要求,設定檔必須命名為 persistence.xml,並存在於類路徑下的 META-INF 目錄中。該檔通常包含了初始化 JPA 引擎所需的全部資訊。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常靈活的配置,persistence.xml 中的資訊都可以在此以屬性注入的方式提供。
• 其次,Spring 實現了部分在 EJB 容器環境下才具有的功能,比如對 @PersistenceContext、@PersistenceUnit 的容器注入支援。
• 第三,也是最具意義的,Spring 將 EntityManager 的創建與銷毀、事務管理等代碼抽取出來,並由其統一管理,開發者不需要關心這些,如前面的代碼所示,業務方法中只剩下操作領域物件的代碼,事務管理和 EntityManager 創建、銷毀的代碼都不再需要開發者關心了。
留言列表