
1. BoardRepository 에 deleteById() 만들기
package shop.mtcoding.blog.board;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import shop.mtcoding.blog.user.User;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RequiredArgsConstructor
@Repository
public class BoardRepository {
private final EntityManager em;
@Transactional
public void deleteById(int id){
Query query = em.createQuery("delete from Board b where b.id = :id");
query.setParameter("id", id);
query.executeUpdate();
}
@Transactional
public void save(Board board){
em.persist(board);
}
public List<Board> findAllV3() {
String q1 = "select b from Board b order by b.id desc";
List<Board> boardList = em.createQuery(q1, Board.class).getResultList();
int[] userIds = boardList.stream().mapToInt(board -> board.getUser().getId()).distinct().toArray();
String q2 = "select u from User u where u.id in (";
for (int i = 0; i < userIds.length; i++) {
if (i == userIds.length - 1) {
q2 = q2 + userIds[i] + ")";
} else {
q2 = q2 + userIds[i] + ",";
}
}
List<User> userList = em.createQuery(q2, User.class).getResultList();
for (Board board : boardList) {
for (User user : userList) {
if (user.getId() == board.getUser().getId()) {
board.setUser(user);
}
}
}
return boardList; // user가 채워져 있어야함.
}
public List<Board> findAllV2() {
Query q1 = em.createQuery("select b from Board b order by b.id desc", Board.class);
List<Board> boardList = q1.getResultList();
Set<Integer> userIds = new HashSet<>();
for (Board board : boardList) {
userIds.add(board.getUser().getId());
}
Query q2 = em.createQuery("select u from User u where u.id in :userIds", User.class);
q2.setParameter("userIds", userIds);
List<User> userList = q2.getResultList();
for (Board board : boardList) {
for (User user : userList) {
if (user.getId() == board.getUser().getId()) {
board.setUser(user);
}
}
}
return boardList;
}
public List<Board> findAll() { // 다른 정보가 추가로 필요하면 조인하면 됨 - outer join일 때 outer는 생략 가능
Query query = em.createQuery("select b from Board b order by b.id desc", Board.class);
return query.getResultList();
}
public Board findByIdJoinUser(int id) { // on생략 가능, 알아서 pk연결해줌
Query query = em.createQuery("select b from Board b join fetch b.user u where b.id = :id", Board.class);
query.setParameter("id", id);
return (Board) query.getSingleResult();
}
public Board findById(int id) {
//id, title, content, user_id(이질감), created_at
Board board = em.find(Board.class, id);
return board;
}
}
- 단위 테스트 하기
package shop.mtcoding.blog.Board;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import shop.mtcoding.blog.board.Board;
import shop.mtcoding.blog.board.BoardRepository;
import shop.mtcoding.blog.user.User;
import java.util.List;
@Import(BoardRepository.class)
@DataJpaTest
public class BoardRepositoryTest {
@Autowired
private BoardRepository boardRepository;
@Autowired
private EntityManager em;
@Test
public void deleteById_test(){
// given
int id = 1;
// when
boardRepository.deleteById(id); // delete 쿼리 발동
// then
System.out.println("deleteById_test : " + boardRepository.findAll().size());
}
@Test
public void findAllV3_test(){
List<Board> boardList = boardRepository.findAllV2();
System.out.println("findAllV3_test : 조회완료 쿼리 2번");
boardList.forEach(board -> {
System.out.println(board);
});
}
@Test
public void findAllV2_test(){
List<Board> boardList = boardRepository.findAllV2();
System.out.println("findAllV2_test : 조회완료 쿼리 2번");
boardList.forEach(board -> {
System.out.println(board);
});
}
@Test
public void findAll_inqueryv2_test() {
String q = "SELECT DISTINCT b FROM Board b JOIN FETCH b.user";
List<Board> boards = em.createQuery(q, Board.class).getResultList();
for (Board board : boards) {
System.out.println("Board ID: " + board.getId());
System.out.println("User ID: " + board.getUser().getId());
// 사용자(User) 객체에 대한 다른 정보도 필요하다면 추가 가능
}
}
@Test
public void findAll_inquery_test() {
// 보드에 해당하는 모든 사용자 ID 조회
String q1 = "SELECT DISTINCT b.user.id FROM Board b";
List<Integer> userIds = em.createQuery(q1, Integer.class).getResultList();
// 각 사용자 ID에 해당하는 보드를 찾아서 사용자 할당
for (Integer userId : userIds) {
// 해당 사용자 ID에 해당하는 모든 보드를 찾기
String q2 = "SELECT b FROM Board b WHERE b.user.id = :userId";
List<Board> boards = em.createQuery(q2, Board.class)
.setParameter("userId", userId)
.getResultList();
// 해당 사용자 ID에 해당하는 사용자를 찾기
User user = em.find(User.class, userId);
// 각 보드에 사용자 할당 및 결과 출력
for (Board board : boards) {
board.setUser(user);
System.out.println("Board ID: " + board.getId() + ", User ID: " + user.getId());
}
}
}
@Test
public void randomquery_test(){
int[] ids = {1,2};
// select u from User u where u.id in (?,?);
String q = "select u from User u where u.id in (";
for (int i=0; i<ids.length; i++){
if(i==ids.length-1){
q = q + "?)";
}else{
q = q + "?,";
}
}
System.out.println(q);
}
@Test
public void findAll_custom_inquery_test() {
String q = "SELECT DISTINCT b.user.id FROM Board b";
List<Integer> userIds = em.createQuery(q, Integer.class).getResultList();
for (Integer userId : userIds) {
System.out.println(userId);
}
}
@Test
public void findAll_LazyLoading_test() {
// given
// when
List<Board> boardList = boardRepository.findAll();
boardList.forEach(board -> {
System.out.println(board.getUser().getUsername());
});
// then
}
@Test
public void findAll_test() {
// given
// when
List<Board> boardList = boardRepository.findAll();
boardList.forEach(board -> {
System.out.println(board.getUser().getUsername());
});
// then
}
@Test
public void findByIdJoinUser_test() {
int id = 1;
boardRepository.findByIdJoinUser(id);
}
@Test
public void findById_test() {
int id = 1;
System.out.println("start - 1");
Board board = boardRepository.findById(id);
System.out.println("start - 2");
System.out.println(board.getUser().getId());
System.out.println("start - 3");
System.out.println(board.getUser().getUsername());
}
}


2.
package shop.mtcoding.blog.board;
import ch.qos.logback.core.model.Model;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import shop.mtcoding.blog.user.User;
import java.lang.annotation.Native;
import java.util.List;
@RequiredArgsConstructor
@Controller
public class BoardController {
private final BoardRepository boardRepository;
private final HttpSession session;
// @Transactional 트랜잭션 시간이 너무 길어져서 service에 넣어야함
@PostMapping("/board/{id}/update")
public String update(@PathVariable Integer id) {
return "redirect:/board/" + id;
}
@GetMapping("/board/{id}/update-form")
public String updateForm(@PathVariable(name = "id") Integer id, HttpServletRequest request) {
return "/board/update-form"; // 서버가 내부적으로 index를 요청 - 외부에서는 다이렉트 접근이 안됨
}
@PostMapping("/board/{id}/delete")
public String delete(@PathVariable Integer id) {
boardRepository.deleteById(id);
return "redirect:/";
}
@GetMapping("/")
public String index(HttpServletRequest request) {
List<Board> boardList = boardRepository.findAll();
request.setAttribute("boardList", boardList);
return "index"; // 서버가 내부적으로 index를 요청 - 외부에서는 다이렉트 접근이 안됨
}
@PostMapping("/board/save")
public String save(BoardRequest.SaveDTO reqDTO) {
User sessionUser = (User) session.getAttribute("sessionUser");
boardRepository.save(reqDTO.toEntity(sessionUser));
return "redirect:/";
}
@GetMapping("/board/save-form")
public String saveForm() {
return "board/save-form";
}
@GetMapping("/board/{id}")
public String detail(@PathVariable Integer id, HttpServletRequest request) { // Integer : 없으면 null, int : 0
Board board = boardRepository.findByIdJoinUser(id);
request.setAttribute("board", board);
return "board/detail";
}
}

Share article