要用到条件查询,找到了在Hibernate jpa中的实现方法,继承JpaSpecificationExecutor
做复杂查询,所以记一笔,如果你有更好的方法,欢迎评论。
JpaSpecificationExecutor
提供很多条件查询方法。
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> var1);
List<T> findAll(Specification<T> var1);
Page<T> findAll(Specification<T> var1, Pageable var2);
List<T> findAll(Specification<T> var1, Sort var2);
long count(Specification<T> var1);
}
比如方法:
List<T> findAll(Specification<T> var1);
就可以查找出符合条件的所有数据,如果你的框架使用的是前段分页的技术,那么这个方法就挺简便的。
那么这个方法该如何使用呢?我们看到它需要的参数是一个
org.springframework.data.jpa.domain.Specification
对象。那我们就创建这个对象先看看。
Specification specification = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
return null;
}
}
IDE自动生成了要重写的方法toPredicate。
root参数是我们用来对应实体的信息的。criteriaBuilder可以帮助我们制作查询信息。
/**
* A root type in the from clause.
* Query roots always reference entities.
*
* @param <X> the entity type referenced by the root
* @since Java Persistence 2.0
*/
public interface Root<X> extends From<X, X> {...}
/**
* Used to construct criteria queries, compound selections,
* expressions, predicates, orderings.
*
* <p> Note that <code>Predicate</code> is used instead of <code>Expression<Boolean></code>
* in this API in order to work around the fact that Java
* generics are not compatible with varags.
*
* @since Java Persistence 2.0
*/
public interface CriteriaBuilder {...}
CriteriaBuilder
对象里有很多条件方法,比如制定条件:某条数据的创建日期小于今天。
criteriaBuilder.lessThan(root.get("createDate"), today)
该方法返回的对象类型是Predicate
。正是toPredicate
需要返回的值。
如果有多个条件,我们就可以创建一个Predicate
集合,最后用CriteriaBuilder
的and
和or
方法进行组合,得到最后的Predicate
对象。
/**
* Create a conjunction of the given restriction predicates.
* A conjunction of zero predicates is true.
*
* @param restrictions zero or more restriction predicates
*
* @return and predicate
*/
Predicate and(Predicate... restrictions);
/**
* Create a disjunction of the given restriction predicates.
* A disjunction of zero predicates is false.
*
* @param restrictions zero or more restriction predicates
*
* @return or predicate
*/
Predicate or(Predicate... restrictions);
Entity
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zo.constant.ReportType;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.List;
@Entity
@Table(name = "form")
@Data
public class Form{
@NotNull
private Long projectStandardId;
@Enumerated(EnumType.STRING)
private ReportType type;
@ManyToOne
@JoinColumn(name = "sub")
private SubItem subItem;
@NotNull
private String name;
}
Repository
public interface FormRepository extends JpaRepository<Form,Long>,JpaSpecificationExecutor<Form> {
List<Form> findAll(Specification<Form> spec);
}
Service
public List<Form> findFormAll(Long standardId, ReportType categoryType,Long subItemId){
List<Form> formList = null;
Specification querySpecification = new Specification<Form>() {
@Override
public Predicate toPredicate(Root<Form> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
if (null!=standardId){
predicates.add(cb.equal(root.get("projectStandardId"),standardId));
}
if (null!=categoryType){
predicates.add(cb.equal(root.get("type"),categoryType));
}
if (null!=subItemId){
predicates.add(cb.equal(root.get("subItem"),subItemId));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
formList = this.formRepository.findAll(querySpecification);
return formList;
}
and到一起的话所有条件就是且关系,or就是或关系了。
public Page<Article> findAllFuzzy(String keyword,Pageable pageable){
logger.info("Fuzzy search by keyword: {}",keyword);
Page<Article> articles = articleRepository.findAll((root, query, cb) -> {
List<Predicate> list = new ArrayList<>();
if (!"".equals(keyword)){
list.add(cb.like(root.get("title").as(String.class),"%" + keyword + "%"));
list.add(cb.like(root.get("content").as(String.class),"%" + keyword + "%"));
list.add(cb.like(root.get("tag").as(String.class),"%" + keyword + "%"));
}
Predicate[] predicates = new Predicate[list.size()];
predicates = list.toArray(predicates);
query.orderBy(cb.desc(root.get("id").as(Integer.class)));
return cb.or(predicates);
},pageable);
return articles;
}
Comments (暂无评论)