2023.11.05 - [웹/Spring vue 웹 개발] - spring vue 댓글03

 

spring vue 댓글03

2023.10.14 - [웹/Spring vue 웹 개발] - spring vue 댓글 02 spring vue 댓글 02이전에 이어서 service랑 controller를 작성을 전부 완료하였고 테스트도 완료하였습니다. 내일은 프론트단을 완료하고 현재 pc내에서

kwaksh2319.tistory.com

먼저 오늘 좀 여러가지 문제점발견하면서 해결을 했습니다.

먼저 기존에 말했던 @Transational방식이 아니라 DTO를 이용하여 댓글을 post 했습니다. 

NoticeDTO

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class NoticeDTO {
    private Long id;
    private String username;
    private String title;
    private String contents;
    private String email;
    private String createdDate;

    // Constructor that takes an entity Notice
    public NoticeDTO(Notice notice) {
        this.id = notice.getId();
        this.username = notice.getUsername();
        this.title = notice.getTitle();
        this.contents = notice.getContents();
        this.email = notice.getEmail();
        this.createdDate = notice.getCreatedDate();
    }
}

 


NoticeRepositoryImpl 

package kr.co.kshproject.webDemo.Domain.Notice;

import lombok.extern.slf4j.Slf4j;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Optional;

@Slf4j
public class NoticeRepositoryImpl implements NoticeCustomRepository {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<NoticeDTO> findAllWithComments() {
        //Criteria API 사용
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        //NoticeDTO <= Notice 커멘트 사용하지 않기 위함
        CriteriaQuery<NoticeDTO> cq = cb.createQuery(NoticeDTO.class);

        //from 절
        Root<Notice> notice = cq.from(Notice.class);
        //선택 및 조건 설정 =>select id,username,title,contents,email,createdDate from notice;
        cq.select(cb.construct(
                NoticeDTO.class,
                notice.get("id"),
                notice.get("username"),
                notice.get("title"),
                notice.get("contents"),
                notice.get("email"),
                notice.get("createdDate")
        ));

        //cq 쿼리 실행
        TypedQuery<NoticeDTO> query = entityManager.createQuery(cq);
        //결과값 리턴
        return query.getResultList();
    }


    @Override
    public Optional<Notice> findWithCommentsById(Long id)  {
        //Criteria API 사용
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        //Notice 사용 이유는 댓글들을 불러오기때문
        CriteriaQuery<Notice> cq = cb.createQuery(Notice.class);

        /*select * from Notice LEFT JOIN Comments where id='id'*/
        //from Notice
        Root<Notice> notice = cq.from(Notice.class);
        //left join
        notice.fetch("comments", JoinType.LEFT);
        cq.where(cb.equal(notice.get("id"), id));
        //cq 쿼리 실행
        TypedQuery<Notice> query = entityManager.createQuery(cq);
        List<Notice> result = query.getResultList();
        //삼항 연산자 result 비엇을시 empty() 존재지 resutl 리턴
        return result.isEmpty() ? Optional.empty(): Optional.of(result.get(0));
    }
}

여기서  아래 findAllwithCommets는 게시글 전부 불러오는거고요. 제가 선택한 방법은 Criterai api를 사용해서 쿼리문을 불어왔습니다 left join에 대해서 이해하셔야 아래 구문이 이해가 가십니다.  

@Override
public List<NoticeDTO> findAllWithComments() {
    //Criteria API 사용
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    //NoticeDTO <= Notice 커멘트 사용하지 않기 위함
    CriteriaQuery<NoticeDTO> cq = cb.createQuery(NoticeDTO.class);

    //from 절
    Root<Notice> notice = cq.from(Notice.class);
    //선택 및 조건 설정 =>select id,username,title,contents,email,createdDate from notice;
    cq.select(cb.construct(
            NoticeDTO.class,
            notice.get("id"),
            notice.get("username"),
            notice.get("title"),
            notice.get("contents"),
            notice.get("email"),
            notice.get("createdDate")
    ));

    //cq 쿼리 실행
    TypedQuery<NoticeDTO> query = entityManager.createQuery(cq);
    //결과값 리턴
    return query.getResultList();
}

이런식으로 transactal query를 불러오지않고 불러오도록 하였습니다. 

결과 화면 : 

' > Spring vue 웹 개발' 카테고리의 다른 글

spring vue 댓글 완료  (0) 2023.11.12
spring vue 댓글 05  (1) 2023.11.11
spring vue 댓글03  (0) 2023.11.05
spring vue 댓글 02  (0) 2023.10.14
spring vue 댓글 01  (0) 2023.10.09

+ Recent posts