7. (실습) 스프링 V1 (기본 - CRUD) (2)

박은서's avatar
Feb 05, 2026
7. (실습) 스프링 V1 (기본 - CRUD) (2)

5. 화면 연결

1) BoardController.java

C:\workspace\spring_lab\boardv1\src\main\java\com\example\boardv1\board\BoardController.java
package com.example.boardv1.board; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @Controller // @Controller 적어야 리턴값이 파일이 됨 public class BoardController { @GetMapping("/") public String index(){ return "index"; } @GetMapping("/boards/save-form") public String saveForm(){ return "board/save-form"; } @GetMapping("/boards/{id}/update-form") public String updateForm(@PathVariable("id") int id){ return "board/update-form"; } @GetMapping("/boards/{id}") public String detail(@PathVariable("id") int id){ return "board/detail"; } }

2) 테스트

notion image
notion image
notion image
notion image
notion image
notion image
notion image

6. BoardRepository 메서드 생성

1) BoardRepository.java

C:\workspace\spring_lab\boardv1\src\main\java\com\example\boardv1\board\BoardRepository.java
package com.example.boardv1.board; import java.util.List; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import lombok.RequiredArgsConstructor; /** * 하이버네이트 기술 */ @RequiredArgsConstructor // final이 붙어 있는 모든 필드를 초기화하는 생성자를 만들어줌 @Repository // DB에 연결되어 있는 컴퍼넌트 public class BoardRepository { private final EntityManager em; // EntityManager(DBConnection, 이름만 다름)는 인터페이스라서 new 할 수 없고, 내가 new해서 아래 매개변수로 넣기 어려움->프레임워크가 미리 띄워놓음 // DI = 의존성 주입 (의존하고 있는 게 IoC에 떠있어야 함) // public BoardRepository(EntityManager em) { // this.em = em; // } public Board findById(int id) { Board board = em.find(Board.class, id); return board; } public List<Board> findAll() { Query query = em.createQuery("select b from Board b order by b.id desc", Board.class); // 객체 지향 쿼리 List<Board> list = query.getResultList(); return list; } public Board save(Board board) { em.persist(board); // 영속화(영구히 저장한다)->디스크에 return board; } public void delete(Board board) { em.remove(board); } }

[참고] DI(의존성 주입, Dependency Injection)

[참고] DI(의존성 주입, Dependency Injection)

7. BoardRepository 메서드 테스트

# ==== query view ==== spring.jpa.show-sql=true // 디버그 콘솔에서 쿼리를 볼 수 있게 해줌 spring.jpa.properties.hibernate.format_sql=true // 쿼리를 예쁘게 볼 수 있게 해줌
application.properties에 추가

1) BoardRepositoryTest.java

C:\workspace\spring_lab\boardv1\src\test\java\com\example\boardv1\board\BoardRepositoryTest.java
package com.example.boardv1.board; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; import org.springframework.context.annotation.Import; import jakarta.persistence.EntityManager; @Import(BoardRepository.class) @DataJpaTest public class BoardRepositoryTest { @Autowired private BoardRepository boardRepository; @Autowired private EntityManager em; @Test public void save_test() { // given Board board = new Board(); board.setTitle("title7"); board.setContent("content7"); System.out.println("==before persist"); System.out.println(board); // when boardRepository.save(board); // eye (board 객체가 DB데이터와 동기화 되었음) System.out.println("==after persist"); System.out.println(board); } @Test public void findById_test() { // given int id = 1; // when Board board = boardRepository.findById(id); // boardRepository.findById(1); // eye System.out.println(board); } @Test public void findByIdV2_test() { // given int id = 1; // when boardRepository.findById(id); em.clear(); boardRepository.findById(id); } @Test public void findAll_test() { // when List<Board> list = boardRepository.findAll(); // eye for (Board board : list) { System.out.println(board); } } @Test public void findAllV2_test() { // when boardRepository.findAllV2(); // eye } @Test public void delete_test() { // given Board board = boardRepository.findById(1); // when boardRepository.delete(board); // eye em.flush(); } @Test public void update_test() { // given Board board = boardRepository.findById(1); // when board.setTitle("title1-update"); // eye em.flush(); List<Board> list = boardRepository.findAll(); for (Board b : list) { System.out.println(b); } } }

2) save_test() 결과

save_test() - persist 이후 id 입력됨
save_test() - persist 이후 id 입력됨
Board 클래스 createdAt 위에 어노테이션 달기
Board 클래스 createdAt 위에 어노테이션 달기
persist 이후 createdAt 날짜도 입력됨
persist 이후 createdAt 날짜도 입력됨

3) findById_test() 결과

when까지 입력 후 테스트 → 쿼리 확인(행위 검증)
when까지 입력 후 테스트 → 쿼리 확인(행위 검증)
2번 조회 (다른 ID)
2번 조회 (다른 ID)
select 2번
select 2번
2번 조회(동일한 ID)
2번 조회(동일한 ID)
select 1번
select 1번
eye 테스트(상태 검증)
eye 테스트(상태 검증)

4) findByIdV2_test() 결과

notion image
notion image

5) findAll_test() 결과

when까지 입력 후 테스트 → 쿼리 확인(행위 검증)
when까지 입력 후 테스트 → 쿼리 확인(행위 검증)
BoardRepository.java에 해당 메서드 추가
BoardRepository.java에 해당 메서드 추가
BoardRepositoryTest.java에 추가
BoardRepositoryTest.java에 추가
결과
결과
eye 테스트(상태 검증)
eye 테스트(상태 검증)

6) delete_test() 결과

when까지 입력 후 테스트 → 쿼리 확인(행위 검증)
⚠️ select 쿼리는 있는데 delete쿼리는 없음!!
when까지 입력 후 테스트 → 쿼리 확인(행위 검증) ⚠️ select 쿼리는 있는데 delete쿼리는 없음!!
findAll로 eye 테스트(상태 검증)
⚠️ delete 쿼리가 생기고 delete가 완료됐다!!
findAll로 eye 테스트(상태 검증) ⚠️ delete 쿼리가 생기고 delete가 완료됐다!!
💡
행위 검증 때는 delete 쿼리가 없고 상태 검증 때는 delete 쿼리가 있다??
EntityManager 추가
EntityManager 추가
delete_test에 추가
delete_test에 추가
결과
결과

7) update_test() 결과

notion image
notion image

8. BoardNativeRepository 메서드 생성

1) BoardNativeRepository.java

C:\workspace\spring_lab\boardv1\src\main\java\com\example\boardv1\board\BoardNativeRepository.java
package com.example.boardv1.board; import java.util.List; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Repository public class BoardNativeRepository { private final EntityManager em; public Board findById(int id) { Query query = em.createNativeQuery("select * from board_tb where id = :id", Board.class); query.setParameter("id", id); Board board = (Board) query.getSingleResult(); return board; } public List<Board> findAll() { Query query = em.createNativeQuery("select * from board_tb", Board.class); List<Board> list = query.getResultList(); // list는 다운캐스팅 안해도 됨 return list; } public void save(String title, String content) { Query query = em.createNativeQuery("insert into board_tb(title, content, created_at) values(:title, :content, now())"); query.setParameter("title", title); query.setParameter("content", content); query.executeUpdate(); } public void deleteById(int id) { Query query = em.createNativeQuery("delete from board_tv where id = :id"); query.setParameter("id", id); query.executeUpdate(); } public void updateById(int id, String title, String content) { Query query = em.createNativeQuery("update board_tb set title = :title, content = :content where id = :id"); query.setParameter("id", id); query.setParameter("title", title); query.setParameter("content", content); query.executeUpdate(); } }
 
resultClass 안적으면 직접 파싱해야 함
Query는 자카르타 쿼리! import 주의
resultClass 안적으면 직접 파싱해야 함 Query는 자카르타 쿼리! import 주의

9. BoardNativeRepository 메서드 테스트

1) BoardNitiveRepositoryTest.java

C:\workspace\spring_lab\boardv1\src\test\java\com\example\boardv1\board\BoardNativeRepositoryTest.java
package com.example.boardv1.board; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; import org.springframework.context.annotation.Import; @Import(BoardNativeRepository.class) // 이것도 IoC에 등록됨 @DataJpaTest // EntityManager가 IoC에 등록됨 public class BoardNativeRepositoryTest { @Autowired // 어노테이션 DI 기법 private BoardNativeRepository boardNativeRepository; @Test public void findById_test() { // given int id = 1; // when Board board = boardNativeRepository.findById(id); // eye System.out.println(board); } @Test public void findAll_test() { // when List<Board> list = boardNativeRepository.findAll(); // eye for (Board board : list) { System.out.println(board); } } @Test public void save_test() { // given String title = "title7"; String content = "content7"; // when boardNativeRepository.save(title, content); // eye List<Board> list = boardNativeRepository.findAll(); for (Board board : list) { System.out.println(board); } } @Test public void deleteById_test() { // given int id = 1; // when boardNativeRepository.deleteById(id); // eye List<Board> list = boardNativeRepository.findAll(); for (Board board : list) { System.out.println(board); } } @Test public void updateById_test() { // given int id = 1; String title = "title1_v1"; String content = "content1_v1"; // when boardNativeRepository.updateById(id, title, content); // eye List<Board> list = boardNativeRepository.findAll(); for (Board board : list) { System.out.println(board); } } }

2) findById_test() 결과

notion image

3) findAll_test() 결과

notion image

4) save_test() 결과

notion image

5) deleteById_test() 결과

notion image

6) updateById_test() 결과

notion image
Share article