티스토리 뷰

Projection

게시글 전체 리스트를 조회할 때 게시글 제목, 내용, 작성자, 작성일 뿐만 아니라 집계 함수의 결과, join 한 결과를 바로 내가 만든 Response 객체로 매핑하고 싶을 수 있다. 그리고 엔티티의 속성 값이 너무 많거나 pw 같이 보안이 중요한 데이터가 담겨있는 경우 몇몇 속성을 제외한 Response 를 받고 싶을 수도 있다. 엔티티에 값을 추가하거나 개인정보가 담긴 속성을 전부 가지고 오는 것보다 내가 원하는 데이터만 가지고 올 수 있도록(SELECT 대상 지정) JPA 에서는 커스텀 객체로 바로 매핑할 수 있게 해주는 Projection 기능을 제공한다.

 

Board Entity
@Entity
data class Board(
    var title: String,
    var content: String,
    var count: Long = 0,
    @ManyToOne
    @JoinColumn(name = "member_id")
    val member: Member2,
    @OneToMany(cascade = [CascadeType.PERSIST], orphanRemoval = true)
    @JoinColumn(name = "board_id")
    var comments: MutableList<Comment> = mutableListOf()
)

BoardEntity는 글 제목, 글 내용, 조회수, 회원 아이디, 댓글 목록 항목을 가지고 있고 댓글 수 속성은 가지고 있지 않다. comments.size로 가져와서 Entity를 Response로 만드는 함수를 만들면.. Projection을 사용하지 않아도 되지만 ㅠ Projectino 사용 예제를 보여주기 위해 ㅋ

BoardListItemResponse 
data class BoardListItemResponse @QueryProjection constructor(
    val boardId: Long,
    val title: String,
    val conetent: String,
    val memberEmail: String,
    val view: Long,
    val registerDate: LocalDateTime,
    val commentCount: Int
)

BoardListItemResponse 는 게시판 목록에 있는 item이고 하나의 item 에는 게시판 id, 게시글 제목, 내용, 작성자, 조회수, 등록일, 댓글 수로 구성되어있다. 

Projection을 사용하기 위해서는 해당 클래스가 Projection 대상임을 알려주는 @QueryProjection 을 사용해야 한다.

해당 클래스를 QueryDsl 에서 사용하기 위해서는 BoardListItemResponse의 Q 클래스를 만들어줘야 하는데 생성 방법은 프로젝트를 빌드하면 자동으로 생성된다. 

Projection을 활용한 데이터 조회 쿼리 생성
override fun 함수이름(
        page: Pageable,
        query: String?,
        searchType: SEARCHTYPE?,
        order: ORDERTYPE?
    ): List<BoardListItemResponse> {
        return jpaQueryFactory.select(QBoardListItemResponse(
           board.id,
           board.title,
           board.content,
           board.member.email,
           board.count,
           board.createdDate,
           board.comments.size()
        )).from(board)
            ..

Entity 결과를 가져와서 DTO 형태로 만들어 줄 수도 있지만 QueryDsl Projection을 사용하면 원하는 DTO 타입으로 리턴 받을 수 있다.

 해당 함수를 호출하는 코드
fun readBoards3(
        page: Int?, query: String?,
        searchType: SEARCHTYPE?, orderType: ORDERTYPE?
    ): List<BoardListItemResponse> {
        ..
        return boardRepository.findBoardAndCommentCountWithPaging(pageable, query, 
        searchType, orderType)
    }

Projection 을 사용하지 않았다면.. 부분에서 Entity로 결과를 받은 다음 BoardListItemResponse로 변환하는 과정이 있었을 거다. 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함