Java/Spring

[SpringBoot/JPA] 검색을 ν¬ν•¨ν•œ νŽ˜μ΄μ§• 처리 DTO

벼리01 2024. 3. 13. 10:59

πŸ“Œν™˜κ²½

IntelliJ Ultimate

Java 17

 

Spring boot 3.2.3

Gradle - Groovy

Dependencies: 

Spring Web

Thymeleaf

Spring Data JPA

lombok

MariaDB 10.11

Spring Dev tool

 

πŸ“Œνλ¦„

κ²Œμ‹œκΈ€ 검색 κΈ°λŠ₯을 ν¬ν•¨ν•˜μ—¬ νŽ˜μ΄μ§•ν•œλ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ, ν˜„μž¬ μš”μ²­ν•˜λŠ” νŽ˜μ΄μ§€, νŽ˜μ΄μ§€λ‹Ή κ²Œμ‹œκΈ€ 수, 검색 νƒ€μž…, 검색 ν‚€μ›Œλ“œ, 링크λ₯Ό μš”μ²­ν•˜λŠ” μš”μ²­ DTO 객체와 ν˜„μž¬ νŽ˜μ΄μ§€, νŽ˜μ΄μ§€λ‹Ή κ²Œμ‹œκΈ€ 수, 이전/λ‹€μŒ νŽ˜μ΄μ§€ 쑴재 μ—¬λΆ€, κ²Œμ‹œκΈ€λ“€μ„ 담을 listλ₯Ό ν¬ν•¨ν•œ 응닡 DTO 객체가 ν•„μš”ν•˜λ‹€. 

 

package org.zerock.b02.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageRequestDTO {

    @Builder.Default
    private int page = 1;

    @Builder.Default
    private int size = 10;

//    검색 μΉ΄ν…Œκ³ λ¦¬: t(title), c(content), w(writer), tc, tw, twc
    private String type;

    private String keyword;

    private String link;

    public String[] getType(){
        if(type == null || type.isEmpty()){
            return null;
        }

        return type.split("");
    }

    public Pageable getPageable(String... props){

//        PageRequest.of(νŽ˜μ΄μ§€ 번호, μ‚¬μ΄μ¦ˆ, Sort)
        return PageRequest.of(this.page - 1, this.size, Sort.by("bno").descending());
    }

    public String getLink(){
        if(link == null){
            StringBuilder sb = new StringBuilder();

            sb.append("page=").append(this.page).append("&size=").append(this.size);

//            type이 λΉ„μ–΄μžˆμœΌλ©΄
            if(type == null && type.isEmpty()){
                sb.append("&type=").append(type);
            }

//            keywordκ°€ null이면
            if(keyword != null){
                try {
                    sb.append("&keyword").append(URLEncoder.encode(keyword, "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                }
            }
//		ex) page=1&type=tcw&keyword=μ•ˆλ…•ν•˜μ„Έμš”
            link = sb.toString();
        }

        return link;
    }


}

 

 

package org.zerock.b02.dto;

import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;

import java.util.List;

@Getter
@ToString
public class PageResponseDTO<E> {

    private int page;
    private int size;
    private int total;

//    μ‹œμž‘ νŽ˜μ΄μ§€ 번호
    private int start;

//    끝 νŽ˜μ΄μ§€ 번호
    private int end;

//    이전/λ‹€μŒ νŽ˜μ΄μ§€ μ—¬λΆ€
    private boolean prev;
    private boolean next;

    private List<E> dtoList;

    @Builder(builderMethodName = "withAll")
    public PageResponseDTO(PageRequestDTO pageRequestDTO, List<E> dtoList, int total){

//        κ²Œμ‹œκΈ€ κ°œμˆ˜κ°€ 0이면 νŽ˜μ΄μ§• μ²˜λ¦¬ν•˜μ§€ μ•ŠμŒ
        if(total <= 0){
            return;
        }

//        ν˜„μž¬ λͺ‡ νŽ˜μ΄μ§€?
        this.page = pageRequestDTO.getPage();

//        νŽ˜μ΄μ§€ λ‹Ή κΈ€ 개수?
        this.size = pageRequestDTO.getSize();

//        κ²Œμ‹œκΈ€ λ‹΄κΈ΄ list
        this.dtoList = dtoList;
//        총 κ²Œμ‹œκΈ€ 수
        this.total = total;

//        ν™”λ©΄μ—μ„œ λ§ˆμ§€λ§‰ 번호
//        10으둜 λ‚˜λˆ„λŠ” 게 μ•„λ‹ˆλΌ (double)size둜 λ‚˜λˆ μ•Όν•˜λŠ” κ±° μ•„λ‹Œκ°€...? κ³±ν•˜λŠ” 것도 λ§ˆμ°¬κ°€μ§€
        this.end = (int)(Math.ceil(this.page / 10.0)) * 10;

//        ν™”λ©΄μ—μ„œ μ‹œμž‘ 번호
//        μ—¬κΈ°κ°€ 9κ°€ μ•„λ‹ˆλΌ size - 1이어야 ν•˜λŠ” κ±° μ•„λ‹Œκ°€?
        this.start = this.end - 9;

//        데이터 개수λ₯Ό κ³„μ‚°ν•œ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ 번호
        int last = (int)(Math.ceil((total / (double)size)));

        this.end = Math.min(end, last);

//        μ‹œμž‘ λ²ˆν˜Έκ°€ 1보닀 크면 이전 νŽ˜μ΄μ§€κ°€ μ‘΄μž¬ν•¨
        this.prev = this.start > 1;

//        κ²Œμ‹œκΈ€ 총 κ°œμˆ˜κ°€ (λ§ˆμ§€λ§‰ 번호 * νŽ˜μ΄μ§€ μ‚¬μ΄μ¦ˆ)보닀 크면 λ‹€μŒ νŽ˜μ΄μ§€κ°€ μ‘΄μž¬ν•¨
        this.next = total > this.end * this.size;

    }
}

 

 

νŽ˜μ΄μ§€λ‹Ή λ³΄μ—¬μ£ΌλŠ” κ²Œμ‹œκΈ€ 개수(size)κ°€ λ‹¬λΌμ§ˆ μˆ˜λ„ 있기 λ•Œλ¬Έμ— end와 start λΆ€λΆ„μ˜ μˆ˜μ •μ΄ ν•„μš”ν•΄λ³΄μΈλ‹€.

일단 10개둜 κ³ μ •λ˜μ–΄μžˆλ‹€λŠ” κ°€μ • ν•˜μ— μž‘μ„±ν•˜λ„λ‘ ν•œλ‹€.

 

 

@Test
    public void listTest(){

        PageRequestDTO pageRequestDTO = PageRequestDTO.builder()
                .type("tcw")    //  제λͺ©, λ‚΄μš©, μž‘μ„±μž λͺ¨λ‘ 검색함
                .keyword("1")   //  1을 검색함
                .page(1)        //  1νŽ˜μ΄μ§€
                .size(10)       //  νŽ˜μ΄μ§€λ‹Ή 10κ°œμ”©
                .build();


//        νŽ˜μ΄μ§€ μš”μ²­ 객체둜 νŽ˜μ΄μ§€ 응닡 객체λ₯Ό λ°›μ•„μ˜΄
        PageResponseDTO<BoardDTO> pageResponseDTO = boardService.list(pageRequestDTO);

        log.info("[pageResponseDTO] " + pageResponseDTO);
        log.info("board list: " + pageResponseDTO.getDtoList());
        log.info("total page: " + pageResponseDTO.getTotal());
        log.info("current page: " + pageResponseDTO.getPage());
        log.info("start: " + pageResponseDTO.getStart());
        log.info("end: " + pageResponseDTO.getEnd());

    }

 

 

 

Hibernate: 
    select
        b1_0.bno,
        b1_0.content,
        b1_0.moddate,
        b1_0.regdate,
        b1_0.title,
        b1_0.writer 
    from
        board b1_0 
    where
        (
            b1_0.title like ? escape '!' 
            or b1_0.content like ? escape '!' 
            or b1_0.writer like ? escape '!'
        ) 
        and b1_0.bno>? 
    order by
        b1_0.bno desc 
    limit
        ?, ?
Hibernate: 
    select
        count(b1_0.bno) 
    from
        board b1_0 
    where
        (
            b1_0.title like ? escape '!' 
            or b1_0.content like ? escape '!' 
            or b1_0.writer like ? escape '!'
        ) 
        and b1_0.bno>?

 

 

2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : [pageResponseDTO] PageResponseDTO(page=1, size=10, total=18, start=1, end=2, prev=false, next=false, dtoList=[BoardDTO(bno=91, title=title...91, content=content... 91, writer=user1, regDate=2024-03-12T17:36:01.847149, modDate=2024-03-12T17:36:01.847149), BoardDTO(bno=81, title=title...81, content=content... 81, writer=user1, regDate=2024-03-12T17:36:01.831171, modDate=2024-03-12T17:36:01.831171), BoardDTO(bno=71, title=title...71, content=content... 71, writer=user1, regDate=2024-03-12T17:36:01.812196, modDate=2024-03-12T17:36:01.812196), BoardDTO(bno=61, title=title...61, content=content... 61, writer=user1, regDate=2024-03-12T17:36:01.785425, modDate=2024-03-12T17:36:01.785425), BoardDTO(bno=51, title=title...51, content=content... 51, writer=user1, regDate=2024-03-12T17:36:01.747887, modDate=2024-03-12T17:36:01.747887), BoardDTO(bno=41, title=title...41, content=content... 41, writer=user1, regDate=2024-03-12T17:36:01.712196, modDate=2024-03-12T17:36:01.712196), BoardDTO(bno=31, title=title...31, content=content... 31, writer=user1, regDate=2024-03-12T17:36:01.663344, modDate=2024-03-12T17:36:01.663344), BoardDTO(bno=21, title=title...21, content=content... 21, writer=user1, regDate=2024-03-12T17:36:01.600227, modDate=2024-03-12T17:36:01.600227), BoardDTO(bno=19, title=title...19, content=content... 19, writer=user9, regDate=2024-03-12T17:36:01.589458, modDate=2024-03-12T17:36:01.589458), BoardDTO(bno=18, title=title...18, content=content... 18, writer=user8, regDate=2024-03-12T17:36:01.585534, modDate=2024-03-12T17:36:01.585534)])
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : board list: [BoardDTO(bno=91, title=title...91, content=content... 91, writer=user1, regDate=2024-03-12T17:36:01.847149, modDate=2024-03-12T17:36:01.847149), BoardDTO(bno=81, title=title...81, content=content... 81, writer=user1, regDate=2024-03-12T17:36:01.831171, modDate=2024-03-12T17:36:01.831171), BoardDTO(bno=71, title=title...71, content=content... 71, writer=user1, regDate=2024-03-12T17:36:01.812196, modDate=2024-03-12T17:36:01.812196), BoardDTO(bno=61, title=title...61, content=content... 61, writer=user1, regDate=2024-03-12T17:36:01.785425, modDate=2024-03-12T17:36:01.785425), BoardDTO(bno=51, title=title...51, content=content... 51, writer=user1, regDate=2024-03-12T17:36:01.747887, modDate=2024-03-12T17:36:01.747887), BoardDTO(bno=41, title=title...41, content=content... 41, writer=user1, regDate=2024-03-12T17:36:01.712196, modDate=2024-03-12T17:36:01.712196), BoardDTO(bno=31, title=title...31, content=content... 31, writer=user1, regDate=2024-03-12T17:36:01.663344, modDate=2024-03-12T17:36:01.663344), BoardDTO(bno=21, title=title...21, content=content... 21, writer=user1, regDate=2024-03-12T17:36:01.600227, modDate=2024-03-12T17:36:01.600227), BoardDTO(bno=19, title=title...19, content=content... 19, writer=user9, regDate=2024-03-12T17:36:01.589458, modDate=2024-03-12T17:36:01.589458), BoardDTO(bno=18, title=title...18, content=content... 18, writer=user8, regDate=2024-03-12T17:36:01.585534, modDate=2024-03-12T17:36:01.585534)]
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : board count: 10
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : total page: 18
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : current page: 1
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : start: 1
2024-03-13T10:46:49.375+09:00  INFO 66142 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : end: 2

 

 

잘 λ™μž‘ν•˜λŠ” 것을 확인할 수 μžˆλ‹€.

 

 

πŸ“Œμ°Έκ³ 

μžλ°” μ›Ή 개발 μ›Œν¬λΆ - κ΅¬λ©κ°€κ²Œ 코딩단