나는 페이징 유형을 2개 사용하고 있다. (queryDsl 유무)
public Page<ProjectDashboardDto> pagingProject(@PageableDefault(size=5)
@SortDefault.SortDefaults({
@SortDefault(
sort = "createdAt",
direction = Sort.Direction.DESC)
})
Pageable pageRequest,
ProjectMemberRequest req) {
Page<ProjectDashboardDto> projectDashboardDtos = projectService.readPageAll(pageRequest, req);
return projectDashboardDtos;
}
@CrossOrigin(origins = "https://naughty-raman-7e7eb1.netlify.app")
@GetMapping("/project/page")
@AssignMemberId
public Page<ProjectDashboardDto> pagingProject(
@PageableDefault(size=5)
@SortDefault.SortDefaults({
@SortDefault(
sort = "createdAt",
direction = Sort.Direction.DESC)
})
Pageable pageRequest,
ProjectMemberRequest req,
@RequestParam(value = "search", required = false) String search) {
if(search==null) { // 만약 넘겨져온 검색어가 없다면 그냥 다 가져와
return projectService.readPageAll(pageRequest, req);
}else{ // 검색어가 존재한다면 검색어 사용해서 검색
return projectService.readPageAllSearch(pageRequest, req,name );
}
}
readPageAllSearch
라는 메소드를 설정해주었다. ProjectService.java
Page<Project> projectListBefore =
projectRepository.
findByNameContainingIgnoreCaseOrProjectNumberContainingIgnoreCaseOrLifecycleContainingIgnoreCaseOrClientItemNumberContainingIgnoreCase(
search,
search,
search,
search,
pageRequest
);
ProjectRepository.java
Page<Project>
findByNameContainingIgnoreCaseOrProjectNumberContainingIgnoreCaseOrLifecycleContainingIgnoreCaseOrClientItemNumberContainingIgnoreCase
(String name,
String projectNumber,
String lifecycle,
String clientItemNumber,
Pageable pageable);
findByNameContainingIgnoreCaseOrProjectNumberContainingIgnoreCaseOrLifecycleContainingIgnoreCaseOrClientItem
라는 JPA 문을 작성해주었다.
- Containing : 포함하는 지
- IgnoreCase : 대소문자 구별 x
findByNameContainingIgnoreCase // name 이라는 string 으로 넘겨져온 아이가 프로젝트의 이름에 존재하는지 (대소문자 구별 X)
Or // 혹은
ProjectNumberContainingIgnoreCase
Or
LifecycleContainingIgnoreCase
Or
ClientItemItemNumberContainingIgnoreCase
ReadCondition.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProduceOrganizationReadCondition {
@NotNull(message = "페이지 번호를 입력해주세요.")
@PositiveOrZero(message = "올바른 페이지 번호를 입력해주세요. (0 이상)")
private Integer page;
@NotNull(message = "페이지 크기를 입력해주세요.")
@Positive(message = "올바른 페이지 크기를 입력해주세요. (1 이상)")
private Integer size;
}
RepositoryImpl.java
@Transactional(readOnly = true)
public class CustomProduceOrganizationRepositoryImpl extends QuerydslRepositorySupport implements CustomProduceOrganizationRepository {
private final JPAQueryFactory jpaQueryFactory;
public CustomProduceOrganizationRepositoryImpl(JPAQueryFactory jpaQueryFactory) {
super(ProjectType.class);
this.jpaQueryFactory = jpaQueryFactory;
}
@Override
public Page<ProduceOrganizationReadResponse> findAllByCondition(ProduceOrganizationReadCondition cond) {
Pageable pageable = PageRequest.of(cond.getPage(), cond.getSize());
Predicate predicate = createPredicate(cond);
return new PageImpl<>(fetchAll(predicate, pageable), pageable, fetchCount(predicate));
}
private List<ProduceOrganizationReadResponse> fetchAll(Predicate predicate, Pageable pageable) {
return getQuerydsl().applyPagination(
pageable,
jpaQueryFactory
.select(constructor(
ProduceOrganizationReadResponse.class,
produceOrganization.id,
produceOrganization.name
))
.from(produceOrganization)
.where(predicate)
.orderBy(produceOrganization.id.desc())
).fetch();
}
private Long fetchCount(Predicate predicate) {
return jpaQueryFactory.select(
produceOrganization.count()
).from(produceOrganization).
where(predicate).fetchOne();
}
private Predicate createPredicate(ProduceOrganizationReadCondition cond) {
return new BooleanBuilder(); # 따로 뭐가 없어
}
private <T> Predicate orConditions(List<T> values, Function<T, BooleanExpression> term) {
return values.stream()
.map(term)
.reduce(BooleanExpression::or)
.orElse(null);
}
}
private Predicate createPredicate(ProduceOrganizationReadCondition cond) {
return new BooleanBuilder(); # 따로 뭐가 없어
}
검색어가 생산조직의 이름에 포함 되어있다면 (contatins) 나타나게 해주기
ReadCondition.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProduceOrganizationReadCondition {
@NotNull(message = "페이지 번호를 입력해주세요.")
@PositiveOrZero(message = "올바른 페이지 번호를 입력해주세요. (0 이상)")
private Integer page;
@NotNull(message = "페이지 크기를 입력해주세요.")
@Positive(message = "올바른 페이지 크기를 입력해주세요. (1 이상)")
private Integer size;
private String name; # 이러한 검색 조건 하나를 추가 !
}
RepositoryImpl.java
// 읽기 조건에서 얻어온 이름 참 거짓 유무 판별
private Predicate createPredicate(ProduceOrganizationReadCondition cond) {
return new BooleanBuilder()
.and(orConditionsByEqNames(cond.getName())); // 포함되어있다면 그에 따른 predicate 생성
}
//검색어로 넘어온 단어가 이름에 contain (포함) 되어있는지 판별
private Predicate orConditionsByEqNames(String word) {
List<String> words = new ArrayList<>();
words.add(word);
return orConditions(words, produceOrganization.name::contains);
}
// 전달받은 value들을 OR 연산으로 묶어서 반환 (지금은)
private <T> Predicate orConditions(List<T> values, Function<T, BooleanExpression> term) {
return values.stream()
.map(term)
.reduce(BooleanExpression::or)
.orElse(null);
}