2023.11.05 - [웹/Spring vue 웹 개발] - spring vue 댓글03
먼저 오늘 좀 여러가지 문제점발견하면서 해결을 했습니다.
먼저 기존에 말했던 @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 |