1. Hello World 샘플 코드 구현
- 클라이언트 쪽에서 “Hello, World” 문자열 데이터를 Request Body로 전송한다
- Spring Data JDBC를 이용해서 전송받은 “Hello, World” 문자열을 H2 데이터베이스에 저장한다
1) Package 생성
- 기존 프로젝트 파일의 java > com.codestates > hello_world 패키지를 만든다
- 아래의 클래스 또는 인터페이스를 생성한다
- MessageDto(DTO 클래스) - PostDto / ResponseDto
package com.codestates.hello_world;
import lombok.Getter;
import javax.validation.constraints.NotBlank;
//클라이언트가 Request Body로 전달하는 “Hello, World” 문자열을 바인딩하는 DTO 클래스
@Getter
public class MessagePostDto {
@NotBlank
private String message;
}
package com.codestates.hello_world;
import lombok.Getter;
import lombok.Setter;
//Response에 사용할 Dto
@Getter
@Setter
public class MessageResponseDto {
private long messageId;
private String message;
}
- MessageController
package com.codestates.hello_world.messageController;
import com.codestates.hello_world.messageMapper.MessageMapper;
import com.codestates.hello_world.messageService.MessageService;
import com.codestates.hello_world.message.Message;
import com.codestates.hello_world.messageDto.MessagePostDto;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
//문자열을 전달받는 Controller
@RequestMapping("/v1/message")
@RestController
public class MessageController {
private final MessageService messageService;
private final MessageMapper mapper;
public MessageController(MessageService messageService,
MessageMapper mapper){
this.messageService = messageService;
this.mapper = mapper;
}
@PostMapping
public ResponseEntity postMessage(
@Valid @RequestBody MessagePostDto messagePostDto){
Message message =
messageService.createMessage(mapper.messageDtoToMessage(messagePostDto));
return ResponseEntity.ok(mapper.messageToMessageResponseDto(message));
}
}
- MessageMapper
package com.codestates.hello_world.messageMapper;
import com.codestates.hello_world.message.Message;
import com.codestates.hello_world.messageDto.MessagePostDto;
import com.codestates.hello_world.messageDto.MessageResponseDto;
import org.mapstruct.Mapper;
//DTO 클래스와 엔티티(Entity) 클래스를 매핑해주는 Mapper 인터페이스
@Mapper(componentModel = "spring")
public interface MessageMapper {
Message messageDtoToMessage(MessagePostDto messagePostDto);
MessageResponseDto messageToMessageResponseDto(Message message);
}
- MessageService
package com.codestates.hello_world.messageService;
import com.codestates.hello_world.message.Message;
import com.codestates.hello_world.messageRepository.MessageRepository;
import org.springframework.stereotype.Service;
//MessageRepository 인터페이스를 DI를 통해 주입받는다
//데이터베이스에 데이터를 저장하고 데이터베이스에 저장된 데이터를 다시 리턴
@Service
public class MessageService {
private MessageRepository messageRepositoty;
public MessageService(MessageRepository messageRepositoty){
this.messageRepositoty = messageRepositoty;
}
public Message createMessage(Message message){
return messageRepositoty.save(message);
}
}
→ MessageRepository가 상속받은 CrudRepository에 save() 메서드가 정의되어 있다
→ 개발자가 데이터의 생성, 조회, 수정, 삭제 작업을 위한 별도의 코드를 구현하지 않아도 CrudRepository가 작업을 대신해주는 역할을 한다
- Message(엔티티 클래스)
package com.codestates.hello_world.message;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
//Message 클래스명은 데이터베이스의 테이블명에 해당한다
//@Id 애너테이션을 추가한 멤버 변수는 해당 엔티티의 고유 식별자 역할을 한다
//식별자는 데이터베이스의 Primary key로 지정한 컬럼에 해당한다
@Getter
@Setter
public class Message {
@Id
private long messageId;
private String message;
}
- MessageRepository
package com.codestates.hello_world;
import org.apache.logging.log4j.message.Message;
import org.springframework.data.repository.CrudRepository;
//데이터베이스와의 연동을 담당하는 Repository
public interface MessageRepository extends CrudRepository<Message, Long>{
}
→ CrudRepository라는 인터페이스를 상속하고 있고, CrudRepository의 제너릭 타입이 <Message, Long>으로 선언되어 있다
→ CrudRepository 는 데이터베이스에 CRUD(데이터 생성, 조회, 수정, 삭제) 작업을 진행하기 위해 Spring에서 지원해주는 인터페이스이다
→ CrudRepository<Message, Long> 와 같이 제너릭 타입을 지정해줌으로써 Message 엔티티 클래스 객체에 담긴 데이터를 데이터베이스 테이블에 생성 또는 수정하거나 데이터베이스에서 조회한 데이터를 Message 엔티티 클래스로 변환할 수 있다
→ <Message, Long>에서 Long은 Message 엔티티 클래스의 멤버 변수 중에 식별자를 의미하는 @Id 라는 애너테이션이 붙어있는 멤버 변수의 데이터 타입이다
※ 짧은 문장이고 MessageRepository 인터페이스 내부에 아무런 코드도 없으나, MessageRepository 인터페이스를 서비스 계층에서 DI를 통해 주입받은 후 데이터베이스 작업을 위해 사용하게 된다
프로젝트를 실행시키고 error 발생 시 변수들의 경로에 유의하여 수정하도록 한다!!!
2) 프로젝트 실행
- 실행 전에 property 설정을 추가한다
spring:
h2:
console:
enabled: true
path: /h2 # (1) Context path
datasource:
url: jdbc:h2:mem:test # (2) JDBC URL
sql:
init:
schema-locations: classpath*:db/h2/schema.sql # 추가할 부분
# 테이블 생성을 위한 SQL 문이 추가된 ‘schema’라는 파일명으로 .sql 파일의 경로를 지정
- 추가 후 resource > db.h2 > schema.sql 파일을 보면 아래와 같이 테이블이 추가되어 있다
CREATE TABLE IF NOT EXISTS MESSAGE (
MESSAGE_ID bigint NOT NULL AUTO_INCREMENT,
MESSAGE varchar(100) NOT NULL,
PRIMARY KEY (MESSAGE_ID)
);
- postman에서 post : http://localhost:8080/v1/message 입력 후 전송하면 아래와 같이 응답한다
- 요청 전송 시 Request Body에 messageId 값은 포함하지 않았지만 Response Body에는 messageId가 포함되어 출력된다
- MESSAGE 테이블의 식별자(Primary key)인 ‘message_id’ 컬럼에 AUTO_INCREMENT 설정이 되어 있으므로 ‘message_id’ 컬럼에 값을 입력하지 않더라도 데이터가 저장이 될 때 마다 자동으로 포함이 된다
- chrome 화면으로 가서 다시 출력한 후 'SELECT *FROM MESSAGE'를 입력하고 RUN SELECT를 실행한다
- 1개의 데이터 (ID:1 , MESSAGE:Hello World)가 입력되어 있음을 확인할 수 있다
2. JDBC DATA 구현 순서
'Spring MVC' 카테고리의 다른 글
Spring MVC - Testing - Mockito (0) | 2022.07.14 |
---|---|
Spring MVC - 데이터 액서스 계층(Data Access Layer) - DDD (0) | 2022.07.03 |
Spring MVC - 데이터 액서스 계층(Data Access Layer) - Spring Data JDBC(개요) (0) | 2022.07.03 |
Spring MVC - 데이터 액서스 계층(Data Access Layer) - JDBC (0) | 2022.07.03 |
Spring MVC - 예외 처리(Handling Exception) - @ExceptionHandler (0) | 2022.06.28 |