Spring Boot 3 與 Hibernate JPA 教學(六) 動態條件查詢 JpaSpecificationExecutor

Spring Boot 3 使用 Hibernate JPA 碰到動態條件,比如,UI上有四個欄位,使用可能輸入的條件數量不等,如何可以依照不同數量的條件進行查詢呢?

需要使用 JpaSpecificationExecutor 這個介面。

JpaSpecificationExecutor 有哪些 method

public interface JpaSpecificationExecutor<T> {
  Optional<T> findOne(@Nullable Specification<T> spec);

  List<T> findAll(@Nullable Specification<T> spec);

  Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

  List<T> findAll(@Nullable Specification<T> spec, Sort sort);

  long count(@Nullable Specification<T> spec);
}

JpaSpecificationExecutor 怎麼用

以上個文章中的 dao 為例,增加介面的實作

@Repository
public interface MyBookDao  extends JpaRepository<MyBook, Long> , JpaSpecificationExecutor<MyBook>

在 controller 或是 service 增加動態條件的查詢 method

import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
......

@GetMapping("mywhere")
	public Map mywhere() {
		Map rs = new HashMap();
		
		List<MyBook> list=findWithCondition("第一本書",null);
		List<MyBookVo> listVo = new ArrayList<>();
		for(MyBook book:list) {
			MyBookVo vo = new MyBookVo();
			BeanUtils.copyProperties(book, vo);//複製資廖
			listVo.add(vo);
		}
		rs.put("success", true);
		rs.put("book", listVo);
		return rs;
	}
	
	  public List<MyBook> findWithCondition(String name, String email) {
		    Specification<MyBook> spec = (root, query, builder) -> {
		      List<Predicate> predicates = new ArrayList<>();
		      if (name != null) {
		        Expression<String> nameExp = root.get("name").as(String.class);
		        predicates.add(builder.equal(nameExp, name));
		      }
		      if (email != null) {
		        Expression<String> publishingHouseExp = root.get("publishingHouse").as(String.class);
		        predicates.add(builder.equal(publishingHouseExp, email));
		      }
		      query.where(builder.and(predicates.toArray(new Predicate[0])));
		      return query.getRestriction();
		    };
		    return myBookDao.findAll(spec);
		  }

在瀏覽器上執行 http://localhost:8080/MyBook/mywhere

JpaSpecificationExecutor 達到動態查詢的效果

This Post Has One Comment

Comments are closed.