<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # JpaSpeci?cationExecutor **用來做動態查詢,可以實現帶查詢條件的分頁** **不屬于Repository體系,實現一組 JPA Criteria 查詢相關的方法** 我們可以通過 AND 或者 OR 等連接詞來不斷拼接屬性來構建多條件查詢, 但如果參數?于 6 個時,?法名就會變得?常的長,并且還不能解決動態多條件查詢的場景。 到這?就需要給?家介紹另外?個利器 JpaSpeci?cationExecutor 了 JpaSpeci?cationExecutor 是 JPA 2.0 提供的 Criteria API 的使?封裝,可以?于動態?成 Query 來滿?我們業務中的各種復雜場景。Spring Data JPA 為我們提供了 JpaSpeci?cationExecutor 接?,只要簡單實現 toPredicate ?法就可以實現復雜的查詢。 JpaSpeci?cationExecutor源碼 ~~~ public interface JpaSpecificationExecutor<T> { /** 根據查詢條件返回一個實體, 注意如果結果多余一條,則拋異常 */ T findOne(Specification<T> spec); /** 根據查詢條件返回多個實體.*/ List<T> findAll(Specification<T> spec); /** 根據查詢條件和分頁參數,返回當前頁的實體信息.*/ Page<T> findAll(Specification<T> spec, Pageable pageable); /*根據查詢條件和排序規則,返回一個排序好的實體集合. */ List<T> findAll(Specification<T> spec, Sort sort); /** 根據查詢條件統計實體的數量 */ long count(Specification<T> spec); } ~~~ JpaSpeci?cationExecutor 的源碼很簡單,根據 Speci?cation 的查詢條件返回 List、Page 或者 count 數據。 在使? JpaSpeci?cationExecutor 構建復雜查詢場景之前,我們需要了解?個概念 * `Root<T> root`,代表了可以查詢和操作的實體對象的根,開?個通過 get("屬性名") 來獲取對應的值。 * `CriteriaQuery<?> query`,代表?個 speci?c 的頂層查詢對象,它包含著查詢的各個部分,?如 select 、from、where、group by、order by 等。 * `CriteriaBuilder cb`,來構建 CritiaQuery 的構建器對象,其實就相當于條件或者是條件組合,并以 Predicate 的形式返回。 # 例子 ## 持久化層 ~~~ @Repository public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { } ~~~ ## service業務層 ~~~ public interface UserService { //條件查詢 id 范圍在 [start,end] 之間的數據。如果 age 不為空,加上條件 List<User> findAll(Long start, Long end, String age); //查詢 id 大于等于 start 的數據,且進行分頁查詢 Page<User> findAll(Long start, int page, int size); //模糊查詢 like List<User> findAllLike(String name); } ~~~ ~~~ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.ArrayList; import java.util.List; @Service public class UserServiceImpl implements UserService { @Resource private UserRepository userRepository; @Override public List<User> findAll(Long start, Long end, String age) { //直接使用匿名內部類實現接口 Specification<User> specification = new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { List<Predicate> predicateList = new ArrayList<>(); //條件1:查詢 id 為 海信 的數據,root.get 中的值與 User 實體中的屬性名稱對應 if (age != null && !"".equals(age)) { predicateList.add(criteriaBuilder.equal(root.get("age").as(String.class), age)); } //條件2:User id(id)大于等于 start 的數據,root.get 中的 id 必須對應 User 中的屬性 predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("id").as(Long.class), start)); //日期是 as(Date.class) //條件3:User id(id) 小于等于 end predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("id").as(Long.class), end)); Predicate[] pre = new Predicate[predicateList.size()]; pre = predicateList.toArray(pre); return criteriaQuery.where(pre).getRestriction(); } }; return userRepository.findAll(specification); } @Override public Page<User> findAll(Long start, int page, int size) { page--; page = page < 0 ? 0 : page; //page 為頁碼,數據庫從0頁開始 //可以使用重載的 of(int page, int size, Sort sort) 方法指定排序字段 Pageable pageable = PageRequest.of(page, size); //創建查詢規范 Specification<User> tvSpecification = new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicateList = new ArrayList<>(); //查詢 id 在 start 與 end 之間的數據,閉區間 predicateList.add(cb.between(root.get("id").as(Long.class), start, 10L)); //數字可以自己傳也可以 Predicate[] predicates = new Predicate[predicateList.size()]; return query.where(predicateList.toArray(predicates)).getRestriction(); } }; return userRepository.findAll(tvSpecification, pageable);//無數據時返回空列表 } @Override public List<User> findAllLike(String name) { Specification<User> tvSpecification = new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate[] predicates = new Predicate[1]; //like(Expression<String> x, String pattern):參數 pattern 表示匹配的格式 predicates[0] = cb.like(root.get("name").as(String.class), "%" + name + "%"); //同理以 xxx 開頭,則為 tvNameLike + "%" return query.where(predicates).getRestriction(); } }; //規范查詢的同時,指定以主鍵 id 倒序排序 return userRepository.findAll(tvSpecification, Sort.by(Sort.Direction.DESC, "id")); } } ~~~ ## 測試 ~~~ List<User> users = userService.findAll(1L, 9L, "33"); ~~~ ~~~ int page = 2; int size = 4; //page = page == null ? 1 : page; //size = size == null ? 2 : size; Page<User> res = userService.findAll(1L, page, size); log.info("總記錄數:" + res.getTotalElements()); log.info("總頁數:" + res.getTotalPages()); List<User> users = res.getContent(); System.out.println(users); ~~~ ~~~ List<User> res = userService.findAllLike("a1"); System.out.println(res); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看