最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Data JPA實現(xiàn)動態(tài)條件與范圍查詢實例代碼

 更新時間:2017年06月26日 11:09:16   作者:汪云飛記錄本  
本篇文章主要介紹了Spring Data JPA實現(xiàn)動態(tài)條件與范圍查詢實例代碼,非常具有實用價值,需要的朋友可以參考下

Spring Data JPA為我們提供了Query With Example來實現(xiàn)動態(tài)條件查詢,當查詢條件為空的時候,我們不用做大量的條件判斷。但是Query With Example卻不支持范圍查詢(包括日期范圍,數(shù)值范圍查詢),本文通過Specification實現(xiàn)了既支持動態(tài)條件查詢又支持范圍查詢的方法。

1 實現(xiàn)方式

1.1 范圍對象Range定義

import java.io.Serializable;


public class Range<E> implements Serializable {
  private static final long serialVersionUID = 1L;

  private String field;
  private Comparable from;
  private Comparable to;
  private Boolean includeNull;


  public Range(String field) {
    this.field = field;
  }


  public Range(String field, Comparable from, Comparable to) {
    this.field = field;
    this.from = from;
    this.to = to;
  }

  public Range(String field, Comparable from, Comparable to, Boolean includeNull) {
    this.field = field;
    this.from = from;
    this.to = to;
    this.includeNull = includeNull;
  }


  public Range(Range<E> other) {
    this.field = other.getField();
    this.from = other.getFrom();
    this.to = other.getTo();
    this.includeNull = other.getIncludeNull();
  }

  public String getField() {
    return field;
  }

  public Comparable getFrom() {
    return from;
  }


  public void setFrom(Comparable from) {
    this.from = from;
  }

  public boolean isFromSet() {
    return getFrom() != null;
  }


  public Comparable getTo() {
    return to;
  }

  public void setTo(Comparable to) {
    this.to = to;
  }

  public boolean isToSet() {
    return getTo() != null;
  }

  public void setIncludeNull(boolean includeNull) {
    this.includeNull = includeNull;
  }

  public Boolean getIncludeNull() {
    return includeNull;
  }

  public boolean isIncludeNullSet() {
    return includeNull != null;
  }

  public boolean isBetween() {
    return isFromSet() && isToSet();
  }

  public boolean isSet() {
    return isFromSet() || isToSet() || isIncludeNullSet();
  }

  public boolean isValid() {
    if (isBetween()) {
      return getFrom().compareTo(getTo()) <= 0;
    }

    return true;
  }
}

1.2 example的Specification

import org.springframework.data.domain.Example;
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.Assert;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
 * Created by wangyunfei on 2017/6/6.
 */
public class ByExampleSpecification<T> implements Specification<T> {
  private final Example<T> example;

  public ByExampleSpecification(Example<T> example) {

    Assert.notNull(example, "Example must not be null!");
    this.example = example;
  }


  @Override
  public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    return QueryByExamplePredicateBuilder.getPredicate(root, cb, example);
  }
}

1.3 Range的Specification

import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;

import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.Lists.newArrayList;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;

/**
 * Created by wangyunfei on 2017/6/6.
 */
public class ByRangeSpecification<T> implements Specification<T> {
  private final List<Range<T>> ranges;

  public ByRangeSpecification(List<Range<T>> ranges) {
    this.ranges = ranges;
  }

  @Override
  public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
    List<Predicate> predicates = newArrayList();

    for (Range<T> range : ranges) {
      if (range.isSet()) {
        Predicate rangePredicate = buildRangePredicate(range, root, builder);

        if (rangePredicate != null) {
          if (!range.isIncludeNullSet() || range.getIncludeNull() == FALSE) {
            predicates.add(rangePredicate);
          } else {
            predicates.add(builder.or(rangePredicate, builder.isNull(root.get(range.getField()))));
          }
        }

        if (TRUE == range.getIncludeNull()) {
          predicates.add(builder.isNull(root.get(range.getField())));
        } else if (FALSE == range.getIncludeNull()) {
          predicates.add(builder.isNotNull(root.get(range.getField())));
        }
      }
    }
    return predicates.isEmpty() ? builder.conjunction() : builder.and(toArray(predicates, Predicate.class));
  }

  private Predicate buildRangePredicate(Range<T> range, Root<T> root, CriteriaBuilder builder) {
    if (range.isBetween()) {
      return builder.between(root.get(range.getField()), range.getFrom(), range.getTo());
    } else if (range.isFromSet()) {
      return builder.greaterThanOrEqualTo(root.get(range.getField()), range.getFrom());
    } else if (range.isToSet()) {
      return builder.lessThanOrEqualTo(root.get(range.getField()), range.getTo());
    }
    return null;
  }

}

1.4 自定義Repository與實現(xiàn)

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.List;

@NoRepositoryBean
public interface WiselyRepository<E, PK extends Serializable> extends JpaRepository<E, PK> {


 Page<E> queryByExampleWithRange(Example example,List<Range<E>> ranges, Pageable pageable);

}
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;

import static org.springframework.data.jpa.domain.Specifications.where;


public class WiselyRepositoryImpl<E, PK extends Serializable> extends SimpleJpaRepository<E, PK> implements
    WiselyRepository<E, PK> {
  private final EntityManager entityManager;

  public WiselyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
    super(entityInformation, entityManager);
    this.entityManager = entityManager;
  }



  @Override
  public Page<E> queryByExampleWithRange(Example example, List<Range<E>> ranges, Pageable pageable) {
    Specification<E> byExample = new ByExampleSpecification<>(example);
    Specification<E> byRanges = new ByRangeSpecification<>(ranges);
    return findAll(where(byExample).and(byRanges),pageable);
  }
}

2 使用方式

2.1 開啟支持

通過@EnableJpaRepositories(repositoryBaseClass = WiselyRepositoryImpl.class)開啟對定義功能的支持。

2.2 示例

實體類

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  private Integer height;
  @DateTimeFormat(pattern = "yyyy-MM-dd")
  private Date birthday;
}

PersonRepository

public interface PersonRepository extends WiselyRepository<Person,Long> {
}

測試控制器

@RestController
@RequestMapping("/people")
public class PersonController {

  @Autowired
  PersonRepository personRepository;

  @PostMapping
  public ResponseEntity<Person> save(@RequestBody Person person){
    Person p = personRepository.save(person);
    return new ResponseEntity<Person>(p, HttpStatus.CREATED);
  }


  @GetMapping
  public ResponseEntity<Page<Person>> query(Person person,
                       @DateTimeFormat(pattern = "yyyy-MM-dd")Date startDate,
                       @DateTimeFormat(pattern = "yyyy-MM-dd")Date endDate,
                       Integer startHeight,
                       Integer endHeight,
                       Pageable pageable){
    Example<Person> personExample = Example.of(person);

    List<Range<Person>> ranges = newArrayList();
    Range<Person> birthRange = new Range<Person>("birthday",startDate,endDate);
    Range<Person> heightRange = new Range<Person>("height",startHeight,endHeight);
    ranges.add(birthRange);
    ranges.add(heightRange);

    Page<Person> page = personRepository.queryByExampleWithRange(personExample,ranges,pageable);

    return new ResponseEntity<Page<Person>>(page,HttpStatus.OK);

  }
}

源碼地址:https://github.com/wiselyman/query_with_example_and_range

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • WebDriver實現(xiàn)自動化打開IE中的google網(wǎng)頁并實現(xiàn)搜索

    WebDriver實現(xiàn)自動化打開IE中的google網(wǎng)頁并實現(xiàn)搜索

    這篇文章主要介紹了WebDriver實現(xiàn)自動化打開IE中的google網(wǎng)頁并實現(xiàn)搜索,需要的朋友可以參考下
    2014-04-04
  • SpringBoot統(tǒng)計接口調(diào)用耗時的三種方式

    SpringBoot統(tǒng)計接口調(diào)用耗時的三種方式

    在實際開發(fā)中,了解項目中接口的響應(yīng)時間是必不可少的事情,SpringBoot 項目支持監(jiān)聽接口的功能也不止一個,接下來我們分別以 AOP、ApplicationListener、Tomcat 三個方面去實現(xiàn)三種不同的監(jiān)聽接口響應(yīng)時間的操作,需要的朋友可以參考下
    2024-06-06
  • 淺談SpringBoot如何正確攔截thymeleaf異常

    淺談SpringBoot如何正確攔截thymeleaf異常

    Thymeleaf是一個模板引擎工具,主要用于頁面渲染操作,本文主要介紹了淺談SpringBoot如何正確攔截thymeleaf異常,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • 使用SkyWalking監(jiān)控Java服務(wù)的過程

    使用SkyWalking監(jiān)控Java服務(wù)的過程

    這篇文章主要介紹了使用SkyWalking監(jiān)控Java服務(wù),介紹一個對源碼0入侵的Java服務(wù)監(jiān)控方式,SkyWalking Agent,只需要啟動Java程序的時候加幾個參數(shù),就能對Java服務(wù)進行可視化監(jiān)控,需要的朋友可以參考下
    2023-08-08
  • 一篇文章帶你了解JavaSE的數(shù)據(jù)類型

    一篇文章帶你了解JavaSE的數(shù)據(jù)類型

    這篇文章主要給大家介紹了關(guān)于JavaSE的數(shù)據(jù)類型,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Java控制流程示例代碼詳解

    Java控制流程示例代碼詳解

    這篇文章主要介紹了Java控制流程,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • java使用jaxb操作xml示例

    java使用jaxb操作xml示例

    JAXB主要用來實現(xiàn)對象和XML之間的序列化和反序列化,關(guān)于JAXB的介紹就不多說了,這里主要總結(jié)下基本使用方法和一些注意事項
    2014-04-04
  • Springboot整合RabbitMq測試TTL的方法詳解

    Springboot整合RabbitMq測試TTL的方法詳解

    這篇文章主要介紹了Springboot整合RabbitMq測試TTL的設(shè)置,設(shè)置TTL一般由兩種設(shè)置方法,設(shè)置整個隊列的過期時間另一種設(shè)置單個消息的過期時間,通過示例圖文相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • 詳解Java中finally和return的執(zhí)行順序

    詳解Java中finally和return的執(zhí)行順序

    try-catch-finally是一種針對程序運行時出錯的響應(yīng)手段,對于一些可以預(yù)料到的出錯類型,在發(fā)生時對其進行報告和補救,這篇文章主要介紹了Java中finally和return的執(zhí)行順序,需要的朋友可以參考下
    2024-01-01
  • java多線程編程之Synchronized塊同步方法

    java多線程編程之Synchronized塊同步方法

    這篇文章主要介紹了java多線程編程之Synchronized塊同步方法,synchronized關(guān)鍵字又稱同步鎖,當方法執(zhí)行完后,會自動釋放鎖鎖,只有一個線程能進入此方法,看看下文中各種例子對synchronized的詳細解釋
    2015-12-12

最新評論

长武县| 泰宁县| 锡林浩特市| 贵阳市| 呼伦贝尔市| 灵台县| 灌云县| 安新县| 八宿县| 柳州市| 柘城县| 紫云| 莱阳市| 葵青区| 德昌县| 徐州市| 岗巴县| 宁夏| 敦煌市| 巴马| 正蓝旗| 沙洋县| 松桃| 高邑县| 喀喇沁旗| 潍坊市| 出国| 扎赉特旗| 原阳县| 临泽县| 沅陵县| 黄石市| 广饶县| 商河县| 密山市| 奉新县| 牙克石市| 无为县| 昆山市| 雅安市| 克什克腾旗|