Specifications動態查詢


有時我們在查詢某個實體的時候,給定的條件是不固定的,這時就需要動態構建相應的查詢語句,在Spring Data JPA中可以通過JpaSpecificationExecutor接口查詢。相比JPQL,其優勢是類型安全,更加的面向對象。

 

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

/**
 *    JpaSpecificationExecutor中定義的方法
 **/
 public interface JpaSpecificationExecutor<T> {
       //根據條件查詢一個對象
     T findOne(Specification<T> spec);    
       //根據條件查詢集合
     List<T> findAll(Specification<T> spec);
       //根據條件分頁查詢
     Page<T> findAll(Specification<T> spec, Pageable pageable);
       //排序查詢查詢
     List<T> findAll(Specification<T> spec, Sort sort);
       //統計查詢
     long count(Specification<T> spec);
}

 

對於JpaSpecificationExecutor,這個接口基本是圍繞着Specification接口來定義的。我們可以簡單的理解為,Specification構造的就是查詢條件。

 

Specification接口中只定義了如下一個方法:

 

//構造查詢條件
    /** 
    *    root    :Root接口,代表查詢的根對象,可以通過root獲取實體中的屬性
    *    query    :代表一個頂層查詢對象,用來自定義查詢
    *    cb        :用來構建查詢,此對象里有很多條件方法
    **/
    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);

 

使用Specifications完成條件查詢

//依賴注入customerDao
    @Autowired
    private CustomerDao customerDao;    
    @Test
    public void testSpecifications() {
          //使用匿名內部類的方式,創建一個Specification的實現類,並實現toPredicate方法
        Specification <Customer> spec = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //cb:構建查詢,添加查詢方式   like:模糊匹配
                //root:從實體Customer對象中按照custName屬性進行查詢
                return cb.like(root.get("Name").as(String.class), "上海堡%");
            }
        };
        Customer customer = customerDao.findOne(spec);
        System.out.println(customer);
    }

基於Specifications的分頁查詢

 

 @Test
    public void testPage() {
        //構造查詢條件
        Specification<Customer> spec = new Specification<Customer>() {
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(root.get("Name").as(String.class), "上海堡%");
            }
        };
/**
 * 構造分頁參數
 * Pageable : 接口
 * PageRequest實現了Pageable接口,調用構造方法的形式構造
 * 第一個參數:頁碼(從0開始)
 * 第二個參數:每頁查詢條數
 */
 Pageable pageable = new PageRequest(0, 5);
        
 /**
 * 分頁查詢,封裝為Spring Data Jpa 內部的page bean
 * 此重載的findAll方法為分頁方法需要兩個參數
 * 第一個參數:查詢條件Specification
 * 第二個參數:分頁參數
 */
 Page<Customer> page = customerDao.findAll(spec,pageable);
        
    }

 

3 方法對應關系

方法名稱

Sql對應關系

equle

filed = value

gt(greaterThan )

filed > value

lt(lessThan )

filed < value

ge(greaterThanOrEqualTo )

filed >= value

le( lessThanOrEqualTo)

filed <= value

notEqule

filed != value

like

filed like value

notLike

filed not like value

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM