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

上一篇文章對Spring Data JPA更深( )一步剖析。 

上一篇只是簡單的介紹了Spring Data JPA的簡單使用,而每每在項目中這一點功能並不能知足咱們的需求。這是固然的,在業務中查詢是一件很是頭疼的事,畢竟不可能只是對一張表的查詢是吧? 其實在業務中每每會涉及到多張表的查詢,以及查詢時須要的各類條件。固然這不用擔憂,畢竟這是對JPA的支持,而咱們在用JPA原生態API的時候每每可能會把一些個方法寫得很凌亂,沒得一個具體的規範來寫本身的方法在後期維護上確定會很困難。固然你本身也能夠封裝一些方法來使用,而當咱們使用到Spring Data JPA時,它已經幫助咱們完成了這個方法的規範了。 

來一塊兒看一下複雜查詢時它爲咱們提供的接口。 

JpaSpecificationExecutor.class app

Java代碼   收藏代碼
  1. public interface JpaSpecificationExecutor<T> {  
  2.   
  3.     T findOne(Specification<T> spec);  
  4.   
  5.     List<T> findAll(Specification<T> spec);  
  6.   
  7.     Page<T> findAll(Specification<T> spec, Pageable pageable);  
  8.   
  9.     List<T> findAll(Specification<T> spec, Sort sort);  
  10.   
  11.     long count(Specification<T> spec);  
  12. }  



在這個接口裏面出現次數最多的類就是Specification.class,而這個類主要也就是圍繞Specification來打造的,Specification.class是Spring Data JPA提供的一個查詢規範,而你只需圍繞這個規範來設置你的查詢條件即可,咱們來看一下Specification.class這個接口中有些什麼東西。 

Specification.class ide

Java代碼   收藏代碼
  1. public interface Specification<T> {  
  2.   
  3.     Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);  
  4. }  


只有一個方法toPredicate,而其中的參數你們並不陌生,都是JPA規範中的,ROOT查詢中的條件表達式、CriteriaQuery條件查詢設計器、CriteriaBuilder條件查詢構造器,而咱們在使用複雜對象查詢時,實現該方法用JPA去構造對象查詢即可。 

下面來看一個小例子: 學習

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


仍然只是一個空接口,此次繼承的是JpaSpecificationExecutor了。 
再寫一測試用例:查詢用戶表中name包含Sam的記錄,並分頁按照birth排倒序 測試

Java代碼   收藏代碼
  1. public class UserDaoTest {  
  2.   
  3.     private static ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  4.   
  5.     private static IUserDao userDao = (IUserDao) context.getBean("userDao");  
  6.   
  7.     public void findBySpecAndPaginate() {  
  8.         Page<User> page = userDao.findAll(new Specification<User>() {  
  9.             @Override  
  10.             public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {  
  11.                 root = query.from(User.class);  
  12.                 Path<String> nameExp = root.get("name");  
  13.                 return cb.like(nameExp, "%Sam%");  
  14.             }  
  15.   
  16.         }, new PageRequest(1, 5, new Sort(Direction.DESC, new String[] { "birth" })));  
  17.   
  18.         StringBuilder stout = new StringBuilder(" 如下是姓名包含Sam人員信息 : ").append("\n");  
  19.         stout.append("| 序號 | username | password | name | sex | birth |").append("\n");  
  20.         int sortIndex = 1;  
  21.         for (User u : page.getContent()) {  
  22.             stout.append(" | ").append(sortIndex);  
  23.             stout.append(" | ").append(u.getUsername());  
  24.             stout.append(" | ").append(u.getPassword());  
  25.             stout.append(" | ").append(u.getName());  
  26.             stout.append(" | ").append(u.getSex());  
  27.             stout.append(" | ").append(u.getBirth());  
  28.             stout.append(" | \n");  
  29.             sortIndex++;  
  30.         }  
  31.         System.err.println(stout);  
  32.     }  
  33.   
  34.     public static void main(String[] args) {  
  35.         UserDaoTest test = new UserDaoTest();  
  36.         test.findBySpecAndPaginate();  
  37.     }  
  38. }  



固然,這只是一個測試,很簡單的一個條件查詢方法。你也能夠設計複雜的查詢來獲得本身所需的結果,我這只是寫一個很簡單的方法來帶你們入門。 

寫了兩篇文章了,尚未講Spring Data JPA爲何只需定義接口就可使用,其實這也不難發現,查看源碼,能夠找到針對JpaRepository和JpaSpecificationExecutor有一個實現類,SimpleJpaRepository.class,這個類實現了剛纔所提的兩個接口。而Spring在給咱們注入實現類的時候,就正是這個SimpleJpaRepository.class,具體的實現方式我就不在這意義贅述了,你們若是有興趣能夠去查看它的源碼,和傳統的JPA實現是同樣的。 



經過這篇文章咱們學習到了,當要使用複雜的條件查詢時,咱們能夠選擇使用此接口來完善咱們的需求,這篇文章就講到這裏,在下一篇文章中我主要是講Spring Data JPA爲咱們提供的註解查詢。 ui

轉自:http://z276356445t.iteye.com/blog/1602258spa

相關文章
相關標籤/搜索