Flask接口签名sign原理与实例代码浅析
786
2023-05-05
Spring Data JPA实现动态条件与范围查询实例代码
Spring Data JPA为我们提供了Query With Example来实现动态条件查询,当查询条件为空的时候,我们不用做大量的条件判断。但是Query With Example却不支持范围查询(包括日期范围,数值范围查询),本文通过Specification实现了既支持动态条件查询又支持范围查询的方法。
1 实现方式
1.1 范围对象Range定义
import java.io.Serializable;
public class Range
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 froOGOTjUm, 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
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
private final Example
public ByExampleSpecification(Example
Assert.notNull(example, "Example must not be null!");
this.example = example;
}
@Override
public Predicate toPredicate(Root
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
private final List
public ByRangeSpecification(List
this.ranges = ranges;
}
@Override
public Predicate toPredicate(Root
List
for (Range
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
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
Page
}
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
WiselyRepository
private final EntityManager entityManager;
public WiselyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Override
public Page
Specification
Specification
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
Person p = personRepository.save(person);
return new ResponseEntity
}
@GetMapping
public ResponseEntity
@DateTimeFormat(pattern = "yyyy-MM-dd")Date startDate,
@DateTimeFormat(pattern = "yyyy-MM-dd")Date endDate,
Integer startHeight,
Integer endHeight,
Pageable pageable){
Example
List
Range
Range
ranges.add(birthRange);
ranges.add(heightRange);
Page
return new ResponseEntity
}
}
源码地址:https://github.com/wiselyman/query_with_example_and_range
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~