-
게시판 만들기 📋 데이터베이스(MariaDB) 연동 및 JPA 입력, 조회, 수정, 삭제 구현Spring Boot/게시판 만들기 2022. 6. 18. 00:26
이전 글) 스프링 부트 프로젝트 생성하기
[개발환경] - 윈도우 MariaDB 설치 및 접속하기
🌈 데이터베이스(MariaDB) 연동 및 JPA 입력, 조회, 수정, 삭제 구현
📌 개발환경
IntelliJ Community, SpringBoot, Java 1.8, Gradle, Jar, Thymeleaf, JPA, MariaDB
테이블 생성
데이터베이스 연동 및 CRUD 구현하기에 앞서 테이블(board)을 먼저 생성합니다.
📁 SQL Download
Dependency 추가
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' annotationProcessor 'org.projectlombok:lombok'
Gradle 적용
build.gradle에서 Load Gradle Chagnes (Ctrl + Shift + O)
또는 우측 Gradle 탭에서 Reload All Gradle Projects
lombok Enabled
Settings → Plugins에서 lombok을 검색한 뒤 Enabled 되어있는지 확인합니다.
데이터베이스 설정
application.properties
spring.datasource.driverClassName=org.mariadb.jdbc.Driver spring.datasource.url=jdbc:mariadb://localhost:3306/toy spring.datasource.username=계정 spring.datasource.password=비밀번호
properties를 사용해도 되지만 개인적으로 중복되는 부분과 가독성을 위해서 yml를 사용하겠습니다. 변경하는 방법은 확장자를 yml로 바꿔주기만 하면 됩니다.
application.yml
spring: datasource: driverClassName: org.mariadb.jdbc.Driver url: jdbc:mariadb://localhost:3306/toy username: 계정 password: 비밀번호
서비스 구현
BaseTimeEntity.java
반복 사용되는 컬럼을 공통으로 정의합니다.
📌 어노테이션 설명
@Getter
↪ Getter 메서드를 생성
@MappedSuperclass
↪ 해당 클래스를 상속받는 자식 클래스에게 매핑 정보만 제공
@EntityListeners(AuditingEntityListener.class)
↪ 해당 클래스에 Auditing 기능을 포함
@CreateDate
↪ Entity가 생성되어 저장될 때 시간이 자동 저장
@LastModifedDate
↪ 조회한 Entity의 값을 변경할 때 시간이 자동 저장@Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class BaseTimeEntity { @CreatedDate private LocalDateTime registerTime; @LastModifiedDate private LocalDateTime modifyTime; }
Board.java
Entity 정의와 요청, 응답 멤버 클래스를 작성합니다.
@NoargsConstructor
↪ 파라미터가 없는 생성자 생성
@Entity
↪ 테이블과 매칭 될 Class 명시
@GeneratedValue
↪ PK 생성 규칙 명시
@Id
↪ PK 필드를 명시
@Builder
↪ 빌더 패턴을 생성
@Getter
↪ Getter 메서드를 생성
@Setter
↪ Setter 메서드를 생성@NoArgsConstructor @Getter @Entity(name = "board") public class Board extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Long id; private String title; private String contents; private String useYn; private Long registerId; private Long modifyId; @Builder public Board(Long id, String title, String contents, String useYn, Long registerId, Long modifyId) { this.id = id; this.title = title; this.contents = contents; this.useYn = useYn; this.registerId = registerId; this.modifyId = modifyId; } @Getter @Setter public static class RequestDto { private Long id; private String title; private String contents; private String useYn; private Long registerId; private Long modifyId; public Board toEntity() { return Board.builder() .title(title) .contents(contents) .useYn(useYn) .registerId(registerId) .modifyId(modifyId) .build(); } } @Getter public static class ResponseDto { private Long id; private String title; private String contents; private String useYn; private Long registerId; private LocalDateTime registerTime; private Long modifyId; private LocalDateTime modifyTime; public ResponseDto(Board board) { this.id = board.id; this.title = board.title; this.contents = board.contents; this.useYn = board.useYn; this.registerId = board.getRegisterId(); this.registerTime = board.getRegisterTime(); this.modifyId = board.getModifyId(); this.modifyTime = board.getRegisterTime(); } }
BoardRepository
업데이트 쿼리는 @Query를 이용한 JPQL방식으로 정의
@Transactional
↪ 선언적 트랜잭션 사용
@Modifying
↪ @Query로 작성된 변경 쿼리를 사용할 때 필요
@Query
↪ SQL을 JPQL로 작성, 네이티브 쿼리 사용 유무 설정 가능public interface BoardRepository extends JpaRepository<Board, Long> { String updateBoardQuery = "update board " + "set title = :#{#requestDto.title}, " + "contents = :#{#requestDto.contents}, " + "use_yn = :#{#requestDto.useYn}, " + "modify_id = :#{#requestDto.modifyId}, " + "modify_time = NOW() " + "where id = :#{#requestDto.id}"; @Transactional @Modifying @Query(value = updateBoardQuery, nativeQuery = true) public int updateBoard(@Param("requestDto") Board.RequestDto requestDto); }
BoardService.java
CRUD 메서드를 작성합니다.
@RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; @Transactional public Long save(Board.RequestDto requestDto) { return boardRepository.save(requestDto.toEntity()).getId(); } public List<Board.ResponseDto> findAll() { return boardRepository.findAll(Sort.by(Sort.Direction.DESC, "registerTime")).stream().map(Board.ResponseDto::new).collect(Collectors.toList()); } public Board.ResponseDto findById(Long id) { return new Board.ResponseDto(boardRepository.findById(id).get()); } public int updateBoard(Board.RequestDto requestDto) { return boardRepository.updateBoard(requestDto); } public void deleteBoard(Board.RequestDto requestDto) { boardRepository.deleteById(requestDto.getId()); } }
ToyApplicationTests.java
test 구조에 있는 클래스로 Junit 테스트에 사용됩니다.
CRUD 테스트
@Test 어노테이션이 있는 메서드가 실행되는데 업데이트, 조회, 삭제 메서드의 경우 기존에 테스트하려는 데이터가 없기 때문에 주석으로 임시로 막아둔 상태에서 save() 메서드부터 실행합니다.
인텔리제이 주석/주석해제하는 단축키는 해당 라인 선택 후 Ctrl + / 입니다.@SpringBootTest class ToyApplicationTests { @Autowired private BoardService boardService; @Test public void save() { Board.RequestDto requestDto = new Board.RequestDto(); requestDto.setTitle("제목"); requestDto.setContents("내용"); requestDto.setUseYn("Y"); requestDto.setRegisterId(117L); requestDto.setModifyId(117L); // 2개의 데이터 입력 Assertions.assertNotEquals(0, boardService.save(requestDto)); Assertions.assertNotEquals(0, boardService.save(requestDto)); } // @Test // public void findAll() { // Assertions.assertNotEquals(0, boardService.findAll().size()); // } // @Test // public void updateBoard() { // Board.RequestDto requestDto = new Board.RequestDto(); // requestDto.setId(1L); // requestDto.setTitle("제목 업데이트"); // requestDto.setContents("내용 업데이트"); // requestDto.setModifyId(322L); // // Assertions.assertEquals(1, boardService.updateBoard(requestDto)); // } // @Test // public void deleteBoard() { // Board.RequestDto requestDto = new Board.RequestDto(); // requestDto.setId(2L); // boardService.deleteBoard(requestDto); // } }
테스트 실행
ToyApplicationTest에 우 클릭 → Run ToyApplicationTests
save() 메서드만 실행한 결과 #1
2개의 데이터가 입력되었는지 데이터베이스 GUI툴을 통해 확인해보겠습니다.
MariaDB 설치 시 같이 생성되는 HeidiSQL 툴을 사용했습니다.나머지 수정, 조회, 삭제 메서드의 주석을 해제하고 실행한 결과 #2
PK가 1인 데이터 수정되고 2인 데이터는 삭제 그리고 PK 3,4 데이터가 입력되어 정상 결과를 확인할 수 있습니다.
Next Step
📁 Project Download
'Spring Boot > 게시판 만들기' 카테고리의 다른 글
게시판 만들기 📋 페이징 (PageRequest) 처리 (0) 2022.06.21 게시판 만들기 📋 목록, 조회, 등록, 상세 페이지 구현하기 (0) 2022.06.20 스프링 부트 프로젝트 생성하기 (0) 2022.06.17