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>에서 LongMessage 엔티티 클래스의 멤버 변수 중에 식별자를 의미하는 @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 구현 순서

 

1. JDBC(Java Database Connectivity)

  • Java 기반 애플리케이션의 코드 레벨에서 사용하는 데이터를 데이터베이스에 저장 및 업데이트 하거나 반대로 데이터베이스에 저장된 데이터를 Java 코드 레벨에서 사용할 수 있도록 해주는 Java에서 제공하는 표준 API이다
  • Java 초창기(JDK 1.1) 버전부터 제공되는 데이터베이스 액세스 기능을 위한 API이다
  • JDBC API를 사용해서 Oracle, MS SQL, MySQL 등의 데이터베이스와 연동할 수 있다

Java Application → JDBC API → JDBC Driver → Database

  • JDBC Driver
    - 데이터베이스와의 통신을 담당하는 인터페이스이다
    - Oracle이나 MS SQL, MySQL 같은 다양한 벤더에서는 해당 벤더에 맞는 JDBC 드라이버를 구현해서 제공을 한다
    - JDBC 드라이버의 구현체를 이용해서 특정 벤더의 데이터베이스에 액세스 할 수 있다

2. Connection Pool

  • 데이터베이스 Connection을 보관하고 애플리케이션이 필요할 때 Connection을 제공해주는 Connection 관리자이다
  • 애플리케이션 로딩 시점에 Connection 객체를 미리 생성한다
  • 생성한 Connection 객체를 Connection Pool에 저장한다
  • 애플리케이션이 데이터베이스에 연결이 필요한 경우 미리 생성 보관 중인 Connection 객체를 사용한다
  • Spring Boot 2.0 이전 버전에는 Apache 재단의 오픈 소스인 Apache Commons DBCP(Database Connection Pool, DBCP)를 주로 사용했다
  • Spring Boot 2.0 부터는 HikariCP기본 DBCP로 채택하고 있다

 

※ 참조 링크

▶ JDBC : https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/

 

Java JDBC API

Java JDBC API The Java Database Connectivity (JDBC) API provides universal data access from the Java programming language. Using the JDBC API, you can access virtually any data source, from relational databases to spreadsheets and flat files. JDBC technolo

docs.oracle.com

https://docs.oracle.com/javase/tutorial/jdbc/basics/index.html

 

Lesson: JDBC Basics (The Java™ Tutorials > JDBC Database Access)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com

https://ko.wikipedia.org/wiki/JDBC

 

JDBC - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org

https://techxyte.com/tutorials/hibernate/pros-and-cons-of-jdbc.php

 

Premium Bootstrap 5 HTML, Angular 11, VueJS, React & Laravel Admin Dashboard Themes

Metronic - #1 Selling Premium Bootstrap Admin Theme of All Time. Built with Twitter Bootstrap 5 HTML, Angular 11, VueJS, React and Laravel. Trusted By Tens of Thousands Users.

keenthemes.com

HikariCP : https://github.com/brettwooldridge/HikariCP

 

GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

光 HikariCP・A solid, high-performance, JDBC connection pool at last. - GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

github.com

 

+ Recent posts