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)文章
Java double轉(zhuǎn)BigDecimal的注意事項(xiàng)說(shuō)明
這篇文章主要介紹了Java double轉(zhuǎn)BigDecimal的注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Java中String.join()高效字符串拼接的實(shí)現(xiàn)
本文主要介紹了Java中String.join()高效字符串拼接的實(shí)現(xiàn),包括基礎(chǔ)拼接、StreamAPI結(jié)合、非字符串類型處理及與傳統(tǒng)方式對(duì)比,具有一定的參考價(jià)值,感興趣的可以了解一下2025-05-05
深入解析四大主流Java?AI?Agent框架的選擇與應(yīng)用
本文將帶你全面盤點(diǎn)當(dāng)前主流的?Java?AI?Agent?框架,深入解析它們的技術(shù)特性、使用方式,并通過(guò)實(shí)戰(zhàn)案例教你如何快速上手,快跟隨小編一起學(xué)習(xí)起來(lái)吧2026-04-04
Spring Boot Web應(yīng)用開(kāi)發(fā) CORS 跨域請(qǐng)求支持
本篇文章主要介紹了Spring Boot Web應(yīng)用開(kāi)發(fā) CORS 跨域請(qǐng)求支持,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
Springboot敏感字段脫敏的實(shí)現(xiàn)思路
這篇文章主要介紹了Springboot敏感字段脫敏的實(shí)現(xiàn)思路,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
解決Error occurred during initialization o
這篇文章主要介紹了解決Error occurred during initialization of VM Java虛擬機(jī)初始化失敗問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03

