JDBC 기반 데이터 액세스 계층(2) - Spring Data JDBC란?

Backend kwon·2023년 8월 31일
0

데이터 엑세스 기술 유형

Spring에서 사용할 수 있는 대표적인 데이터 액세스 기술에는 mybatis, Spring JDBC, Spring Data JDBC, JPA, Spring Data JPA 등이 있습니다.

 

SQL 중심 기술

  • mybatis
  • Spring JDBC

SQL 중심 기술은 애플리케이션에서 데이터베이스에 접근하기 위해 SQL 쿼리문을 애플리케이션 내부에 직접적으로 작성하는 것이 중심이 되는 기술입니다.

mybatis의 경우, SQL Mapper라는 설정 파일이 존재하는데 이 SQL Mapper에서 SQL 쿼리문을 직접적으로 작성합니다.

작성된 SQL 쿼리문을 기반으로 데이터베이스의 특정 테이블에서 데이터를 조회한 후, Java 객체로 변환해 주는 것이 mybatis의 대표적인 기술적 특징입니다.

Spring JDBC의 경우에도 JdbcTemplate이라는 템플릿 클래스를 사용하는데 Java 코드에 SQL 쿼리문이 직접적으로 포함이 되어 있습니다.

 

객체 중심 기술

객체(Object) 중심 기술은 데이터를 SQL 쿼리문 위주로 생각하는 것이 아니라 모든 데이터를 객체(Object) 관점으로 바라보는 기술입니다.

즉, 객체 중심 기술은 데이터베이스에 접근하기 위해서 SQL 쿼리문을 직접적으로 작성하기보다는 데이터베이스의 테이블에 데이터를 저장하거나 조회할 경우, Java 객체를 이용해 애플리케이션 내부에서 이 Java 객체를 SQL 쿼리문으로 자동 변환 한 후에 데이터베이스의 테이블에 접근합니다.

이러한 객체(Object) 중심의 데이터 액세스 기술을 ORM(Object-Relational Mapping)이라고 합니다.

Java에서 대표적인 ORM 기술이 바로 JPA(Java Persistence API)입니다.

 

Spring Data JDBC란?

Spring Data JDBC는 JPA처럼 ORM 기술을 사용하지만 JPA의 기술적 복잡도를 낮춘 기술입니다.

2018년에 1.0 버전이 처음 릴리스되었기 때문에 기술의 역사가 아직 짧은 편입니다. 따라서 현재도 기능 업그레이드가 꾸준히 이루어지고 있지만 아직까지는 JPA보다 상대적으로 적게 사용되고 있습니다.

하지만 애플리케이션의 규모가 상대적으로 크지 않고, 복잡하지 않을 경우에는 Spring Data JDBC가 뛰어난 생산성을 보여줄 거라 기대합니다.

 

Spring Data Jdbc를 사용하기 위한 사전 준비

1. 의존 라이브러리 추가

Spring Data JDBC를 사용하기 위해 ‘spring-boot-starter-data-jdbc’를 추가했습니다.

그리고 데이터베이스에서 데이터를 관리할 것이므로 개발 환경에서 손쉽게 사용할 수 있는 인메모리(In-memory) DB인 H2를 사용하기 위해 의존 라이브러리 설정에 추가했습니다.
(로컬 테스트 환경에서는 인메모리(In-memory) DB 사용을 권장한다)

인메모리 DB란?
인메모리(In-memory) DB는 이름 그대로 메모리 안에 데이터를 저장하는 데이터베이스입니다.
인메모리(In-memory) DB는 애플리케이션이 실행되는 동안에만 데이터를 저장하고 있기 때문에 애플리케이션 실행을 중지했다가 다시 실행시키면 인메모리(In-memory) DB안에 저장되어 있던 데이터는 모두 사라지게 됩니다.

 
2. application.yml 파일에 H2 Browser 활성화 설정 추가

Spring에서는 application.properties 또는 application.yml 파일을 통해 Spring에서 사용하는 다양한 설정 정보들을 입력할 수 있습니다.

(.yml 파일은 애플리케이션의 설정 정보를 depth 별로 입력할 수 있는 더 나은 방법을 제공합니다.)

spring:
  h2:
    console:
      enabled: true

위와 같이 설정하면 웹 브라우저 상(H2 콘솔)에서 H2 DB에 접속한 후, 데이터베이스를 관리할 수 있습니다.

로그에서 확인한 URL 컨텍스트인 ‘/h2-console’을 복사해서 웹 브라우저에 주소를(localhost:8080/h2-console) 입력합니다.

그리고 애플리케이션 로그에 출력된 ‘jdbc:h2:mem:26d0d5d3-dcef-47f8-8e6b-297853bdcffg3’ 을 [JDBC URL]이라는 항목에 복사/붙여넣기 한 후, [Connect] 버튼을 클릭합니다.

그러면 H2 DB에 정상적으로 접속할 수 있습니다.

H2 DB 디폴트 설정의 문제점 : H2 DB는 애플리케이션을 재시작할 때마다 애플리케이션 로그에 출력되는 JDBC URL이 매번 랜덤하게 바뀌기 때문에 매번 랜덤하게 변경된 JDBC URL을 다시 입력하는 것은 상당히 불편합니다.

이 문제는 application.yml 파일에 H2에 대한 추가 설정을 함으로써 해결할 수 있습니다.

 
3. H2 DB 설정 추가

spring:
  h2:
    console:
      enabled: true
      path: /h2     # (1) Context path 변경
  datasource:
    url: jdbc:h2:mem:test     # (2) JDBC URL 변경

(1)에서는 H2 콘솔의 접속 URL Context path를 조금 더 간결하게 ‘/h2’로 설정했습니다.

(2)에서는 JDBC URL이 매번 랜덤하게 바뀌지 않도록 ‘jdbc:h2:mem:test’로 설정했습니다.

이제 ‘localhost:8080/h2’로 접속한 뒤 [JDBC URL] 항목에 ‘jdbc:h2:mem:test’을 입력하고 [Connect] 버튼을 클릭하면 접속이 될 것입니다.

 
4. H2 DB에 MESSAGE 테이블 생성
데이터를 저장할 테이블을 H2 DB에 생성하지 않았습니다.

spring:
  h2:
    console:
      enabled: true
      path: /h2     
  datasource:
    url: jdbc:h2:mem:test
  sql:
    init:
      schema-locations: classpath*:db/h2/schema.sql   // (1) 테이블 생성 파일 경로

Spring에서는 (1)과 같이 테이블 생성을 위한 SQL 문이 추가된 ‘schema’라는 파일명으로 .sql 파일의 경로를 지정해 주면 이 schema.sql 파일에 있는 스크립트를 읽어서 애플리케이션 실행 시, 데이터베이스에 테이블을 자동으로 생성해 줍니다.

인메모리 DB를 사용할 경우, 애플리케이션이 실행될 때마다 schema.sql 파일의 스크립트가 매번 실행된다는 사실 또한 기억하기 바랍니다.

schema.sql 파일은 ‘src/main/resources/db/h2’ 디렉토리 내에 위치해 있습니다.

CREATE TABLE IF NOT EXISTS MESSAGE (
    message_id bigint NOT NULL AUTO_INCREMENT,
    message varchar(100) NOT NULL,
    PRIMARY KEY (message_id)
);

‘message_id’는 MESSAGE 테이블의 Primary key이고 AUTO_INCREMENT를 지정했기 때문에 데이터가 insert될 때마다 자동으로 증가됩니다.

즉, 애플리케이션 쪽에서 데이터베이스에 데이터를 insert할 때 ‘message_id’ 열에 해당하는 값을 지정해주지 않아야 한다는 의미입니다.

그리고 MESSAGE 테이블은 Message 클래스 명과 매핑되고 ‘message_id’ 열은 Message 클래스의 messageId 멤버 변수와 매핑됩니다.

‘message’ 열은 Message 클래스의 message 멤버 변수와 매핑됩니다.

이렇듯 ORM(Object-Relational Mapping)에서는 객체의 멤버 변수와 데이터베이스 테이블의 열이 대부분 1대1로 매핑이 됩니다.

 

정리 : Spring Data JDBC 적용 순서

  1. build.gradle에 사용할 데이터베이스를 위한 의존 라이브러리를 추가합니다.
  2. application.yml 파일에 사용할 데이터베이스에 대한 설정을 합니다.
  3. ‘schema.sql’ 파일에 필요한 테이블 스크립트를 작성합니다.
  4. application.yml 파일에서 ‘schema.sql’ 파일을 읽어서 테이블을 생성할 수 있도록 초기화 설정을 추가합니다.
  5. 데이터베이스의 테이블과 매핑할 엔티티(Entity) 클래스를 작성합니다.
  6. 작성한 엔티티 클래스를 기반으로 데이터베이스의 작업을 처리할 Repository 인터페이스를 작성합니다.
  7. 작성된 Repository 인터페이스를 서비스 클래스에서 사용할 수 있도록 DI 합니다.
  8. DI 된 Repository의 메서드를 사용해서 서비스 클래스에서 데이터베이스에 CRUD 작업을 수행합니다.
profile
백엔드개발자를 향해서

0개의 댓글