1. 程式人生 > >SpringDataJPA之Specification複雜查詢

SpringDataJPA之Specification複雜查詢

前言

繼上次SpringData-JPA之ExampleMatcher例項查詢使用一會之後發現ExampleMatcher對日期的查詢特別糟糕,所以才有了Specification查詢的研究。

2018年8月11日:根據所學所用,重新更新了文章,並增加了Pageable分頁排序功能。

實現

對應的Repository需要實現JpaSpecificationExecutor介面

public interface EventRepository extends JpaRepository<Event, Integer> , JpaSpecificationExecutor
<Event>{

Specification與Controller業務邏輯

    @GetMapping("/event/list")
    public ApiReturnObject findAllEvent(String event,Timestamp registerTime,Integer pageNumber,Integer pageSize) {
        if(pageNumber==null) pageNumber=1;
        if(pageSize==null) pageNumber=10;
        //分頁
        //Pageable是介面,PageRequest是介面實現,new PageRequest()是舊方法,PageRequest.of()是新方法
//PageRequest.of的物件建構函式有多個,page是頁數,初始值是0,size是查詢結果的條數,後兩個引數參考Sort物件的構造方法 Pageable pageable = PageRequest.of(pageNumber,pageSize,Sort.Direction.DESC,"id"); //Specification查詢構造器 Specification<Event> specification=new Specification<Event>() { private static
final long serialVersionUID = 1L; @Override public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) { Predicate condition1 = null; if(StringUtils.isNotBlank(eventTitle)) { condition1 = criteriaBuilder.like(root.get("eventTitle"),"%"+eventTitle+"%"); }else { condition1 = criteriaBuilder.like(root.get("eventTitle"),"%%"); } Predicate condition2 = null; if(registerTime!=null) { condition2 = criteriaBuilder.greaterThan(root.get("registerTime"), registerTime); }else { condition2 = criteriaBuilder.greaterThan(root.get("registerTime"), new Timestamp(1514736000000L)); } //Predicate conditionX=criteriaBuilder.and(condition1,condition2); //query.where(conditionX); query.where(condition1,condition2); //query.where(getPredicates(condition1,condition2)); //這裡可以設定任意條查詢條件 return null; //這種方式使用JPA的API設定了查詢條件,所以不需要再返回查詢條件Predicate給Spring Data Jpa,故最後return null } }; Page<Event> list=eventRepository.findAll(specification, pageable); return ApiReturnUtil.page(list); }

ApiReturnUtil.page封裝

    public static ApiReturnObject page(Page returnObject) {
        return new ApiReturnObject(returnObject.getNumber()+"",returnObject.getNumberOfElements()+"",returnObject.getTotalElements()+"",returnObject.getTotalPages()+"","00","success",returnObject.getContent());  
    }
    String errorCode="00";
    Object errorMessage;
    Object returnObject;
    String pageNumber;
    String pageSize;
    String totalElements;
    String totalPages;

    public ApiReturnObject(String pageNumber,String pageSize,String totalElements,String totalPages,String errorCode, Object errorMessage, Object returnObject) {
        super();
        this.pageNumber = pageNumber;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.returnObject = returnObject;
        this.pageSize = pageSize;
        this.totalElements = totalElements;
        this.totalPages = totalPages;
    }

返回物件有用的是pageNumber、pageSize、totalElements、totalPages等屬性,可對其進行封裝

{
    "errorCode": "00",
    "errorMessage": "success",
    "pageNumber": "1",
    "pageSize": "2",
    "returnObject": [
        {
            "eventTitle": "1111",
            "id": 3,
            "registerTime": 1528702813000,
            "status": "0"
        },
        {
            "eventTitle": "小明失蹤",
            "id": 2,
            "registerTime": 1526268436000,
            "status": "0"
        }
    ],
    "totalElements": "5",
    "totalPages": "3"
}

可以查詢了。網上關於這個的資料也很少。希望可以幫到大家。

可能遇到的錯誤

Unable to locate Attribute  with the the given name [event] on this ManagedType [org.microservice.tcbj.yytsg.checkcentersys.entity.Event]

出現這樣的情況,一般是因為實體類中沒有這個屬性,例如我Event的是eventTitle,寫成了event,就會報錯。