• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Spring Data JPA实现动态条件与范围查询实例代码

java 搞代码 4年前 (2022-01-05) 38次浏览 已收录 0个评论

本篇文章主要介绍了Spring Data JPA实现动态条件与范围查询实例代码,非常具有实用价值,需要的朋友可以参考下

Spring Data JPA为我们提供了Query With Example来实现动态条件查询,当查询条件为空的时候,我们不用做大量的条件判断。但是Query With Example却不支持范围查询(包括日期范围,数值范围查询),本文通过Specification实现了既支持动态条件查询又支持范围查询的方法。

1 实现方式

1.1 范围对象Range定义

 import java.io.Serializable; public class Range 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 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 s<p style="color:transparent">来源gao!%daima.com搞$代*!码网</p>etTo(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 implements Specification { private final Example example; public ByExampleSpecification(Example example) { Assert.notNull(example, "Example must not be null!"); this.example = example; } @Override public Predicate toPredicate(Root 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 implements Specification { private final List<Range> ranges; public ByRangeSpecification(List<Range> ranges) { this.ranges = ranges; } @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { List predicates = newArrayList(); for (Range 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 range, Root 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与实现

 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 extends JpaRepository { Page queryByExampleWithRange(Example example,List<Range> 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 extends SimpleJpaRepository implements WiselyRepository { private final EntityManager entityManager; public WiselyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { super(entityInformation, entityManager); this.entityManager = entityManager; } @Override public Page queryByExampleWithRange(Example example, List<Range> ranges, Pageable pageable) { Specification byExample = new ByExampleSpecification(example); Specification 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 { }

测试控制器

 @RestController @RequestMapping("/people") public class PersonController { @Autowired PersonRepository personRepository; @PostMapping public ResponseEntity save(@RequestBody Person person){ Person p = personRepository.save(person); return new ResponseEntity(p, HttpStatus.CREATED); } @GetMapping public ResponseEntity<Page> query(Person person, @DateTimeFormat(pattern = "yyyy-MM-dd")Date startDate, @DateTimeFormat(pattern = "yyyy-MM-dd")Date endDate, Integer startHeight, Integer endHeight, Pageable pageable){ Example personExample = Example.of(person); List<Range> ranges = newArrayList(); Range birthRange = new Range("birthday",startDate,endDate); Range heightRange = new Range("height",startHeight,endHeight); ranges.add(birthRange); ranges.add(heightRange); Page page = personRepository.queryByExampleWithRange(personExample,ranges,pageable); return new ResponseEntity<Page>(page,HttpStatus.OK); } } 

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持gaodaima搞代码网

以上就是Spring Data JPA实现动态条件与范围查询实例代码的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring Data JPA实现动态条件与范围查询实例代码

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址