Spring Data JDBC
SQL 중심 기술
SQL 중심 기술은 애플리케이션에서 데이터베이스에 접근하기 위해 SQL 쿼리문을 애플리케이션 내부에 직접적으로 작성하는 것이 중심이 되는 기술입니다.
Spring JDBC는 대표적인 SQL 중심 기술이라고 할 수 있습니다.
Spring JDBC의 JdbcTemplate 사용 예)
Member member = this.jdbcTemplate.queryForObject(
"select * from member where member_id=?", 1, Member.class);
위 예시코드는 Spring JDBC의 jdbcTemplate라는 템플릿 클래스를 사용한 데이터베이스 접근 예 입니다.
Spring JDBC는 Java 코드에 SQL 쿼리문이 직접적으로 포함되어 있습니다.
객체(Object) 중심 기술
객체(Object) 중심 기술은 데이터를 SQL 쿼리문 위주로 생각하는 것이 아니라 모든 데이터를 객체(Object) 관점으로 바라보는 기술입니다.
즉, 객체(Object) 중심 기술은 데이터베이스에 접근하기 위해서 SQL 쿼리문을 직접적으로 작성하기보다는 데이터베이스의 테이블에 데이터를 저장하거나 조회할 경우, Java 객체(Object)를 이용해 애플리케이션 내부에서 이 Java 객체(Object)를 SQL 쿼리문으로 자동 변환 한 후에 데이터베이스의 테이블에 접근합니다.
이러한 객체(Object) 중심의 데이터 액세스 기술을 ORM(Object-Relational Mapping)이라고 합니다.
Java에서 대표적인 ORM 기술이 바로 JPA(Java Persistence API)입니다.
JPA를 사용하면 SQL 쿼리문을 직접적으로 다룰 상황은 많지 않습니다.
복잡한 조건의 데이터 조회를 위해 SQL 쿼리문을 사용하기도 하지만 그 사용 빈도수는 이 전보다 급격히 줄어듭니다.
Spring Data JDBC
Spring Data JDBC는 JAP처럼 ORM 기술을 사용하지만 JPA의 기술적 복잡도를 낮춘 기술입니다.
JPA는 기술 전체를 놓고 보았을 때, 기술적인 난이도와 복잡도가 꽤 높은 편이기 때문에 학습 곡선이 일정 부분에서 꽤 가파른 편입니다. 반면 Spring Data JDBC는 JPA보다 상대적으로 학습 곡선이 가파르지 않습니다.
Spring Data JDBC 적용 순서를 살펴보겠습니다.
1. build.gradle에 사용할 데이터베이스를 위한 의존 라이브러리를 추가합니다.
Spring Data JDBC를 사용하기 위해서는 아래 예시 코드와 같이 build.gradle에 Spring Boot Starter를 추가해야 합니다.
dependencies {
...
...
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
runtimeOnly 'com.h2database:h2'
}
2. application.yml 파일에 사용할 데이터베이스에 대한 설정을 합니다.
Spring에서는 application.properties 또는 application.yml 파일을 통해 Spring에서 사용하는 다양한 설정 정보들을 입력할 수 있습니다.
.yml 파일은 애플리케이션의 설정 정보(프로퍼티)를 depth 별로 입력할 수 있는 더 나은 방법을 제공하기 때문에 application.properties의 파일 확장자를 application.yml로 변경하겠습니다.
파일을 선택한 후, [Shift + F6] 키를 누르면 파일 확장자를 손쉽게 바꿀 수 있습니다.(Windows, Mac 동일)
그리고 아래 예시 코드와 같이 H2 관련 설정을 추가합니다.
spring:
h2:
console:
enabled: true
예시 코드와 같이 설정하면 웹 브라우저 상(H2 콘솔)에서 H2 DB에 접속한 후, 데이터베이스를 관리할 수 있습니다.
이제 H2 데이터베이스 연동이 잘 되었는지 확인해 봅시다.
Spring 애플리케이션이 출력한 로그들을 보면 이제 데이터베이스와 관련된 로그들이 출력된 것이 보입니다.
오후 2:15:06: Executing ':Section3Week1JdbcApplication.main()'...
> Task :compileJava UP-TO-DATE
> Task :processResources
> Task :classes
> Task :Section3Week1JdbcApplication.main()
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.0)
No active profile set, falling back to 1 default profile: "default"
Bootstrapping Spring Data JDBC repositories in DEFAULT mode. // 데이터베이스와 관련된 로그
Finished Spring Data repository scanning in 10 ms. Found 0 JDBC repository interfaces. // 데이터베이스와 관련된 로그
Tomcat initialized with port(s): 8080 (http)
Starting service [Tomcat]
Starting Servlet engine: [Apache Tomcat/9.0.63]
Initializing Spring embedded WebApplicationContext
Root WebApplicationContext: initialization completed in 1830 ms
HikariPool-1 - Starting... // 데이터베이스와 관련된 로그
HikariPool-1 - Start completed. // 데이터베이스와 관련된 로그
H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:26d0d5d3-dcef-47f8-8e6b-67898bdcfbd0' // (1)
Tomcat started on port(s): 8080 (http) with context path ''
Started Section3Week1JdbcApplication in 3.018 seconds (JVM running for 3.423)
이 중에서 맨 마지막쯤에 (1)이라고 표기한 ‘H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:26d0d5d3-dcef-47f8-8e6b-67898bdcfbd0’ 라는 로그는 이제 H2 데이터베이스를 정상적으로 사용할 준비가 되었으며, 웹 브라우저로 접속해서 데이터베이스를 관리할 수 있음을 의미합니다.
이 정보를 이용해서 H2 데이터베이스에 접속해 보겠습니다.
애플리케이션 로그에서 확인한 URL 컨텍스트인 ‘/h2-console’을 그림 3-35와 같이 복사해서 웹 브라우저에 주소를(localhost:8080/h2-console)를 입력합니다.
위와 같은 화면이 보인다면 H2 DB에 정상적으로 접속한 것입니다.
그런데, H2 DB는 애플리케이션을 재시작할 때마다 애플리케이션 로그에 출력되는 JDBC URL이 매번 랜덤하게 바뀌기 때문에 매번 랜덤하게 변경된 JDBC URL을 다시 입력하는 것은 상당히 불편합니다.
이 문제는 application.yml 파일에 H2에 대한 추가 설정을 함으로써 해결할 수 있습니다.
이 문제를 해결하기 위한 추가 설정을 해봅시다.
spring:
h2:
console:
enabled: true
path: /h2 # (1) Context path 변경
datasource:
url: jdbc:h2:mem:test # (2) JDBC URL 변경
application.yml에 코드를 추가합니다.
(1)에서는 H2 콘솔의 접속 URL Context path를 조금 더 간결하게 ‘/h2’로 설정했습니다.
(2)에서는 JDBC URL이 매번 랜덤하게 바뀌지 않도록 ‘jdbc:h2:mem:test’로 설정했습니다.
위 코드들을 작성할 때는 들여쓰기를 정확하게 넣어주어야 합니다.
이전 까지는 데이터 베이스 연결을 위한 기본적인 사전 준비였습니다. 이후 부터는 직접 코드 입력을 통해 연결을 해야합니다.
나머지 순서는 아래와 같습니다.
3. ‘schema.sql’ 파일에 필요한 테이블 스크립트를 작성합니다.
4. application.yml 파일에서 ‘schema.sql’ 파일을 읽어서 테이블을 생성할 수 있도록 초기화 설정을 추가합니다.
5. 데이터베이스의 테이블과 매핑할 엔티티(Entity) 클래스를 작성합니다.
6. 작성한 엔티티 클래스를 기반으로 데이터베이스의 작업을 처리할 Repository 인터페이스를 작성합니다.
7. 작성된 Repository 인터페이스를 서비스 클래스에서 사용할 수 있도록 DI 합니다.
8. DI 된 Repository의 메서드를 사용해서 서비스 클래스에서 데이터베이스에 CRUD 작업을 수행합니다.
위 진행 사항들은 직접 작성을 통해 학습하시면 좋을것 같습니다.
학습정리
- 데이터 액세스 기술의 유형은 크게 SQL 중심의 기술과 객체(Object) 중심의 기술로 나눌 수 있다.
- SQL 중심의 기술에는 mybatis, Spring JDBC 등이 있다.
- 객체(Object) 중심의 기술에는 JPA, Spring Data JDBC 등이 있다.
- JPA 같은 객체(Object) 중심의 기술을 ORM(Object-Relational Mapping) 기술이라고 한다.
- 인메모리(In-memory) DB는 애플리케이션이 실행된 상태에서만 데이터를 저장하고 애플리케이션 실행이 중지되면 인메모리 DB 역시 실행이 중지되어 저장된 데이터가 사라진다.
- Spring에서 지원하는 CrudRepository 인터페이스는 CRUD에 대한 기본적인 메서드를 정의하고 있기 때문에 별도의 CRUD 기능을 개발자가 직접 구현할 필요가 없다.
- application.properties 또는 application.yml 파일의 설정 정보 등록을 통해 데이터베이스 설정, 데이터베이스의 초기화 설정 등의 다양한 설정을 할 수 있다.
- application.yml 방식은 중복되는 프로퍼티의 입력을 줄여주기 때문에 application.properties 방식보다 더 선호되는 추세이다.
- 엔티티(Entity) 클래스 이름은 데이터베이스 테이블의 이름에 매핑되고, 엔티티 클래스 각각의 멤버 변수는 데이터베이스 테이블의 열에 매핑된다.
- 엔티티 클래스의 멤버 변수에 @Id 애너테이션을 추가하면 데이터베이스 테이블의 기본키(Primary key) 열과 매핑된다.