SpringJPA?做分頁(yè)條件查詢的代碼實(shí)踐
前言:
相信小伙伴們的項(xiàng)目很多都用到SpringJPA框架的吧,對(duì)于單表的增刪改查利用jpa是很方便的,但是對(duì)于條件查詢并且分頁(yè) 是不是很多小伙伴不經(jīng)常寫到. 今天我整理了一下在這里分享一下.
話不多說(shuō)直接上代碼:
Controller:
@RestController public class ProductInstanceController { @Autowired private ProductInstanceService productInstanceService; @PostMapping("page-find-instance") public PageInfoVO<ProductInst> pageFindInstance(@RequestBody ProductInstParams productInstParams) { return productInstanceService.pageFindInstance(productInstParams); } }
Service:
@Service public class ProductInstanceService { @Autowired private ProductInstRepository productInstRepository; public PageInfoVO<ProductInst> pageFindInstance(ProductInstParams productInstParams) { Sort.Direction direction = Sort.Direction.DESC; //創(chuàng)建一個(gè)Pageable對(duì)象,其中包含了請(qǐng)求的頁(yè)碼(productInstParams.getPageNo()),每頁(yè)大小(productInstParams.getPageSize()),排序規(guī)則以及排序字段名。 Pageable pageable = PageRequest.of(productInstParams.getPageNo(), productInstParams.getPageSize(), direction, "createdTime"); //將傳入的字符串類型的開(kāi)始日期(startDate)和結(jié)束日期(endDate)轉(zhuǎn)換成Date類型 Date start = DateUtil.parseUTC(productInstParams.getStartDate()); Date end = DateUtil.parseUTC(productInstParams.getEndDate()); //執(zhí)行JPA分頁(yè)查詢: Page<ProductInst> productInstPage = productInstRepository.findAll((root, query, criteriaBuilder) -> { //初始化一個(gè)ArrayList<Predicate>,存儲(chǔ)多個(gè)謂詞條件,這些條件最終會(huì)被組合成一個(gè)邏輯與(AND)表達(dá)式 List<Predicate> predicatesAndList = new ArrayList<>(); // deleted = 'true' if (null != productInstParams.getIsDeleted()) { predicatesAndList.add(criteriaBuilder.equal(root.get("deleted").as(Boolean.class), productInstParams.getIsDeleted())); } // name like %name% if (StringUtils.isNotBlank(productInstParams.getName())) { predicatesAndList.add(criteriaBuilder.like(root.get("name").as(String.class), productInstParams.getName())); } // runStatus = "運(yùn)行中" if (StringUtils.isNotBlank(productInstParams.getRunStatus())) { predicatesAndList.add(criteriaBuilder.equal(root.get("runStatus").as(String.class), productInstParams.getRunStatus())); } // createdTime >= start if (!Objects.isNull(start)) { predicatesAndList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdTime").as(Date.class), start)); } // createdTime <= end if (!Objects.isNull(end)) { predicatesAndList.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdTime").as(Date.class), end)); } // id in ('1','2') if (!CollectionUtils.isEmpty(productInstParams.getIds())) { CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("id").as(String.class)); productInstParams.getIds().forEach(in::value); predicatesAndList.add(in); } Predicate andPredicate = criteriaBuilder.and(predicatesAndList.toArray(new Predicate[predicatesAndList.size()])); query.where(andPredicate); return query.getRestriction(); }, pageable); return PageUtil.generatePageInfoVO(productInstPage); } }
解釋:
jpa分頁(yè)查詢調(diào)的方法是:
Page findAll(@Nullable Specification spec, Pageable pageable);
該方法接受兩個(gè)參數(shù):
一個(gè)是 Specification 對(duì)象,用于構(gòu)建復(fù)雜的查詢條件;
另一個(gè)是之前創(chuàng)建的pageable對(duì)象,用于指定分頁(yè)及排序信息。
點(diǎn)進(jìn)去可以直接看到
下面我再解釋一下這行代碼
criteriaBuilder.equal(root.get("runStatus").as(String.class), productInstParams.getRunStatus());
1. criteriaBuilder 是javax.persistence.criteria.CriteriaBuilder的一個(gè)實(shí)例,它是用來(lái)構(gòu)建JPQL查詢條件的對(duì)象。
2. root 是代表查詢主表的Root對(duì)象,它指向ProductInst實(shí)體類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表。
3. root.get(“runStatus”) 表示獲取ProductInst實(shí)體類中的runStatus屬性(注意:這地方寫的不是數(shù)據(jù)庫(kù)的字段,我數(shù)據(jù)庫(kù)的字段是:run_status)。這個(gè)方法返回的是一個(gè)Path<未知類型>對(duì)象,表示runStatus字段在查詢路徑上的位置。
4. .as(String.class) 是類型轉(zhuǎn)換,確保runStatus被視為String類型,因?yàn)樵跀?shù)據(jù)庫(kù)中它可能被映射為VARCHAR或者其他文本類型字段。
5. productInstParams.getRunStatus() 獲取傳入?yún)?shù)對(duì)象productInstParams中的runStatus屬性值,這是一個(gè)待匹配的實(shí)際值。
綜上所述:這段代碼對(duì)應(yīng)的sql
WHERE run_status = 'XXXX'
Repository:
@Repository public interface ProductInstRepository extends JpaRepository<ProductInst, String>, JpaSpecificationExecutor<ProductInst> { }
PageInfoVO:
package com.king.alice.common.base; import lombok.Getter; import lombok.Setter; import java.util.List; /** * @Author wlt * @Description 分頁(yè)數(shù)據(jù)中的元素 * @Date 2022/8/26 **/ @Getter @Setter public class PageInfoVO<T> extends BaseVO{ private static final long serialVersionUID = -3542944936096780651L; /** * 總記錄數(shù) */ private long total; /** * 當(dāng)前頁(yè) */ private int pageNum; /** * 每頁(yè)的數(shù)量 */ private int pageSize; /** * 結(jié)果集 */ private List<T> list; }
PageUtil:
package com.king.alice.common.util; import com.king.alice.common.base.PageInfoVO; import org.springframework.data.domain.Page; /** * @author 大魔王 * @description: * @date 2024/3/22 11:02 */ public class PageUtil { /** * 根據(jù)Page對(duì)象生成PageInfoVO * * @param page Page包裝對(duì)象 * @return PageDto 對(duì)象 */ @SuppressWarnings({"unchecked"}) public static <T> PageInfoVO<T> generatePageInfoVO(Page page) { PageInfoVO result = new PageInfoVO(); result.setPageNum(page.getNumber() + 1); result.setPageSize(page.getPageable().getPageSize()); result.setTotal(page.getTotalElements()); result.setList(page.getContent()); return result; } }
ProductInstParams:
package com.king.alice.manage.instance.params; import lombok.Data; import java.util.List; /** * @author 大魔王 * @description: TODO * @date 2024/3/21 16:56 */ @Data public class ProductInstParams { /** * 當(dāng)前頁(yè) */ private int pageNo; /** * 每頁(yè)的數(shù)量 */ private int pageSize; /** * 名字 */ private List<String> ids; /** * 名字 */ private String name; /** * 運(yùn)行狀態(tài) */ private String runStatus; private String startDate; private String endDate; private Boolean isDeleted; }
測(cè)試:
響應(yīng)結(jié)果:
控制臺(tái)打印sql:
到此這篇關(guān)于SpringJPA 做分頁(yè)條件查詢的文章就介紹到這了,更多相關(guān)SpringJPA 分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解讀SpringBoot為什么要用DeferredImportSelector
這篇文章主要介紹了SpringBoot為什么要用DeferredImportSelector的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03JAVA通過(guò)Filter實(shí)現(xiàn)允許服務(wù)跨域請(qǐng)求的方法
這里的域指的是這樣的一個(gè)概念:我們認(rèn)為若協(xié)議 + 域名 + 端口號(hào)均相同,那么就是同域即我們常說(shuō)的瀏覽器請(qǐng)求的同源策略。這篇文章主要介紹了JAVA通過(guò)Filter實(shí)現(xiàn)允許服務(wù)跨域請(qǐng)求,需要的朋友可以參考下2018-11-11Java獲取時(shí)間打印到控制臺(tái)代碼實(shí)例
這篇文章主要介紹了Java獲取時(shí)間打印到控制臺(tái)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02如何使用Spring RestTemplate訪問(wèn)restful服務(wù)
這篇文章主要介紹了如何使用Spring RestTemplate訪問(wèn)restful服務(wù),詳細(xì)的介紹了什么是RestTemplate以及簡(jiǎn)單實(shí)現(xiàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-10-10JavaWeb評(píng)論功能實(shí)現(xiàn)步驟以及代碼實(shí)例
項(xiàng)目初始版本上線,有時(shí)間寫點(diǎn)東西記錄一下項(xiàng)目中的心得體會(huì),通過(guò)這個(gè)項(xiàng)目學(xué)習(xí)了很多,要寫下來(lái)的有很多,先從評(píng)論功能開(kāi)始吧,下面這篇文章主要給大家介紹了關(guān)于JavaWeb評(píng)論功能實(shí)現(xiàn)步驟以及代碼的相關(guān)資料,需要的朋友可以參考下2023-01-01基于Java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列的兩種方法小結(jié)
下面小編就為大家分享一篇基于Java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列的兩種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12java實(shí)時(shí)監(jiān)控文件行尾內(nèi)容的實(shí)現(xiàn)
這篇文章主要介紹了java實(shí)時(shí)監(jiān)控文件行尾內(nèi)容的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02java開(kāi)發(fā)WMS倉(cāng)庫(kù)商品預(yù)警需求示例解析
這篇文章主要為大家介紹了java開(kāi)發(fā)WMS倉(cāng)庫(kù)商品預(yù)警需求示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04