一步步學習 Spring Data 系列之JPA(一)

引入: 

Spring Data是SpringSource基金會下的一個用於簡化數據庫訪問,並支持雲服務的開源框架。其主要目標是使得數據庫的訪問變得方便快捷,並支持map-reduce框架和雲計算數據服務。對於擁有海量數據的項目,能夠用Spring Data來簡化項目的開發。 

然而針對不一樣的數據儲存訪問使用相對的類庫來操做訪問。Spring Data中已經爲咱們提供了不少業務中經常使用的一些接口和實現類來幫咱們快速構建項目,好比分頁、排序、DAO一些經常使用的操做。 

今天主要是對Spring Data下的JPA模塊進行講解。 

爲何說Spring Data能幫助咱們快速構建項目呢,由於Spring Data已經在數據庫訪問層上幫咱們實現了公用功能了,而咱們只需寫一個接口去繼承Spring Data提供給咱們接口,即可實現對數據庫的訪問及操做,相似於spring-orm的TemplateDAO。 

----------------------------------------------邪惡的分割線------------------------------------------------------------------------------ 
核心接口: 

下面來看一下Repository的最頂層接口: spring

Java代碼   收藏代碼
  1. public interface Repository<T, ID extends Serializable> {  
  2.   
  3. }  


這個接口只是一個空的接口,目的是爲了統一全部Repository的類型,其接口類型使用了泛型,泛型參數中T表明實體類型,ID則是實體中id的類型。 

再來看一下Repository的直接子接口CrudRepository中的方法: 數據庫

Java代碼   收藏代碼
  1. public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {  
  2.   
  3.     <S extends T> S save(S entity);  
  4.   
  5.     <S extends T> Iterable<S> save(Iterable<S> entities);  
  6.   
  7.     T findOne(ID id);  
  8.   
  9.     boolean exists(ID id);  
  10.   
  11.     Iterable<T> findAll();  
  12.   
  13.     Iterable<T> findAll(Iterable<ID> ids);  
  14.   
  15.     long count();  
  16.   
  17.     void delete(ID id);  
  18.   
  19.     void delete(T entity);  
  20.   
  21.     void delete(Iterable<? extends T> entities);  
  22.   
  23.     void deleteAll();  
  24. }  


此接口中的方法大可能是咱們在訪問數據庫中經常使用的一些方法,若是咱們要寫本身的DAO類的時候,只需定義個接口來集成它即可使用了。 

再來看看Spring Data未咱們提供分頁和排序的Repository的接口PagingAndSortingRepository: app

Java代碼   收藏代碼
  1. public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {  
  2.   
  3.     Iterable<T> findAll(Sort sort);  
  4.   
  5.     Page<T> findAll(Pageable pageable);  
  6. }  


這些Repository都是spring-data-commons提供給咱們的核心接口,spring-data-commons是Spring Data的核心包。這個接口中爲咱們提供了數據的分頁方法,以及排序方法。看吧,spring-data讓咱們省了不少心了,一切都按照這個規範進行構造,就連業務系統中經常使用到的一些操做都爲咱們考慮到了,而咱們只需更用心的去關注業務邏輯層。spring-data將repository的顆粒度劃得很細,其實我以爲spring的框架中將每一個類的顆粒度都劃得很細,這主要也是爲了責任分離。 


----------------------------------------------邪惡的分割線------------------------------------------------------------------------------ 
JPA實現: 
針對spring-data-jpa又提供了一系列repository接口,其中有JpaRepository和JpaSpecificationExecutor,這2個接口又有什麼區別呢,咱們分別來看看這2個接口的源碼。 

JpaRepository.class 框架

Java代碼   收藏代碼
  1. public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {  
  2.   
  3.     List<T> findAll();  
  4.   
  5.     List<T> findAll(Sort sort);  
  6.   
  7.     <S extends T> List<S> save(Iterable<S> entities);  
  8.     void flush();  
  9.   
  10.     T saveAndFlush(T entity);  
  11.   
  12.     void deleteInBatch(Iterable<T> entities);  
  13.   
  14.     void deleteAllInBatch();  


這個類繼承自PagingAndSortingRepository,看其中的方法,能夠看出裏面的方法都是一些簡單的操做,並未涉及到複雜的邏輯。當你在處理一些簡單的數據邏輯時,即可繼承此接口,看一個小例子吧。本文JPA供應者選擇的是Hibernate EntityManager,固然讀者們也能夠選擇其餘的JPA供應者,好比EclipseLink、OpenJPA,反正JPA是個標準,在無須修改的狀況下即可移植。 

先定義一用戶實體類User.class: 單元測試

Java代碼   收藏代碼
  1. @Entity  
  2. @Table( name = "spring_data_user" )  
  3. @PrimaryKeyJoinColumn( name = "id" )  
  4. public class User extends IdGenerator{  
  5.   
  6.     private static final long serialVersionUID = 1L;  
  7.       
  8.     private String name;  
  9.     private String username;  
  10.     private String password;  
  11.     private String sex;  
  12.     private Date birth;  
  13.     private String address;  
  14.     private String zip;  
  15.           
  16.         //省略getter和setter  
  17. }  


Id生成策略是採用的表生成策略,這裏就不貼代碼了,spring的配置文件我也就不貼出來了,反正就那些東西,網上一查,遍地都是。後續我會在將demo附上來。 

實體類是有了,如今得寫一個持久層,這樣才能操做數據庫啊,如今咱們來看一下持久層。IUserDao.class: 學習

Java代碼   收藏代碼
  1. @Repository("userDao")  
  2. public interface IUserDao extends JpaRepository<User, Long>{}  


再在spring的配置文件中加上如下代碼。 測試

Xml代碼   收藏代碼
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  3.     xmlns:jpa="http://www.springframework.org/schema/data/jpa"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/data/jpa  
  6.     http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">  
  7.   
  8.     <jpa:repositories base-package="org.tea.springdata.**.dao" />  
  9. </beans>  


加上這段後Spring就會將指定包中@Repository的類註冊爲bean,將bean託管給Spring。這樣定義完了就OK了!哦,就這樣就能夠操做數據庫了? 
是的,前面我就已經說了,Spring data已經幫咱們寫好一個實現類了,而簡單的操做咱們只須這樣繼承JpaRepository就能夠作CRUD操做了。再寫個業務類來測試一把吧。因爲我用的Cglib來動態代理,因此就不定義接口了,直接定義類UserService.class: 雲計算

Java代碼   收藏代碼
  1. @Service("userService")  
  2. public class UserService {  
  3.       
  4.     @Autowired  
  5.     private IUserDao dao;  
  6.       
  7.     public void save(User user) {  
  8.         dao.save(user);  
  9.     }  
  10.   
  11.     public void delete(Long id) {  
  12.         dao.delete(id);  
  13.     }  
  14.   
  15.     public void update(User user) {  
  16.         dao.saveAndFlush(user);  
  17.     }  
  18.   
  19.     public List<User> findAll() {  
  20.         return dao.findAll();  
  21.     }  
  22. }  


來寫一單元測試。 spa

Java代碼   收藏代碼
  1. public class UserServiceTest {  
  2.       
  3.     private static ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  4.       
  5.     private static UserService userService = (UserService) context.getBean("userService");  
  6.       
  7.     public void saveUser() {  
  8.         StopWatch sw = new StopWatch(getClass().getSimpleName());  
  9.         sw.start("Add a user information.");  
  10.         User u = new User();  
  11.         u.setName("John");  
  12.         u.setSex("Man");  
  13.         u.setUsername("JohnZhang");  
  14.         u.setPassword("123456");  
  15.         u.setBirth(new Date());  
  16.         userService.save(u);  
  17.         sw.stop();  
  18.         System.err.println(sw.prettyPrint());  
  19.     }  
  20.   
  21.      public static void main(String[] args) {  
  22.         UserServiceTest test = new UserServiceTest();  
  23.         test.saveUser();  
  24.     }  
  25. }  


綠了,高興了,測試經過! 
額,都沒用Junit怎麼會綠呢,開個玩笑。 
其他繼承下來的操做方法,你們均可以本身測試一下,如沒意外,應該都會測試經過。 

好吧,今天就暫時分享到這了,你千萬別覺得Spring-data就這麼點功能,這只是spring-data中最入門級的知識,後續還有不少東西值得學習,在下一篇文章中我會列出spring-data-jpa中精華的部分,對其進行講解,並附上Demo供下載。 代理

相關文章
相關標籤/搜索