Spring/Spring Boot

[Spring Boot] 4. Data: SQL Databases

noahkim_ 2023. 10. 13. 17:06

1. SQL Database

Spring Framework는 광범위한 SQL Database 와의 작업을 지원합니다.

  • JdbcTemplate : JDBC 기술을 사용하여 기존의 코드를 단순화화고, 오류 처리 및 리소스 관리를 개선한 헬퍼 클래스
  • Hibernate : JPA 기반 ORM 기술

 

Spring Data JPA는 Repository 인터페이스를 제공합니다.

  • Repository 인터페이스 구현을 통해 Entity 관련  Table과 직접적으로 통신할 수 있습니다.
  • Repository 인터페이스가 제공하는 메서드 이름의 컨벤션으로 메서드를 생성하면 자동으로 관련 쿼리를 생성하여 통신합니다.

 

Configure a DataSource

  • java의 javax.sql.DataSource 인터페이스는 database connections 작업을 담당합니다.
  • DataSource는  URL와 credentials 정보를 사용하여 database connections를 구축합니다.
  • 풀링된 연결이나 분산된 연결 등 다양한 연결 유형을 처리할 수 있습니다.

 

Embedded Database Support
  • in-memory embedded database 자동설정을 제공합니다. (H2, HSQL, Derby)
  • classpath에 존재하는 의존성을 확인하여 자동설정합니다.
  • connection URL 자동으로 설정합니다.
  • spring.datasource.embedded-database-connection : 사용할 의존성을 선택할 수 있습니다.

 

DataSource Configuration
  • spring.datasource*의 external configuration properties를 통해 편리하게 설정할 수 있습니다.
  • 풀링된 연결을 사용하기 위해서 검증된 Driver 클래스를 사용해야 합니다.
    • spring.datasource.driver-class-name 에 database 벤더별 driver의 FQCN을 전달해서 사용합니다.

 

Supported Connection Pools
  • 기본 추천 커넥션 풀
    • Spring Boot는 커넥션 풀 라이브러리인 HikariCP를 권장합니다.
    • HikariCP는 spring-boot-starter-jdbc 혹은 spring-boot-starter-data-jpa 모듈에서 제공됩니다.
    • 동시성과 성능 면에서 훌륭합니다.
  • 커넥션 풀 선택
    • spring.datasource.type 프로퍼티를 사용하여 원하는 커넥션 풀 라이브러리를 지정할 수 있습니다.
  • 추가적으로 지원되는 커넥션 풀
    • Tomcat, DBCP, Oracle UCP, JdbcDataSource, PGSimpleDataSource, SimpleJdbcDatasource(test purpose)
  • 자동 설정
    • DataSourceBuilder를 사용하여 커넥션 풀에 대한 자동 설정이 적용됩니다.
    • 사용자가 DataSource 빈을 직접 정의하면 자동설정은 발생하지 않습니다.

 

Using JdbcTemplate

  • Spring Boot는 JdbcTemplate와 NamedParameterJdbcTemplate 클래스를 자동설정합니다.
  • 빈을 주입받아 사용할 수 있습니다.

 

JPA and Spring Data JPA

  • JPA는 Java Persistence API의 약자로 Object를 RDB의 테이블과 매핑을 도와주는 자바 핵심 명세입니다.
  • spring-boot-starter-data-jpa POM에서는 빠르고 쉽게 사용할 수 있도록 관련 핵심 의존성들을 제공합니다.
    • Hibernate : JPA 표준 명세를 구현하는 가장 유명한 JPA 라이브러리입니다.
    • Spring Data JPA : JPA 기반의 repository의 구현을 담당합니다.
    • Spring ORM : Spring Framework의 핵심 ORM 기술을 지원합니다.

 

Entity Classes
  • Entity Scanning
    • 전통적으로 JPA에서 엔터티 클래스는 persistence.xml 파일에 명시되었습니다.
    • Spring Boot를 사용하면 persistence.xml 파일 대신 "Entity Scanning"이라는 방법을 사용합니다.
    • 기본적으로 메인 설정 클래스 아래의 모든 패키지를 검색합니다.
      • @EnableAutoConfiguration 또는 @SpringBootApplication이 붙은 클래스
      • 패키지 내에서 @Entity, @Embeddable, @MappedSuperclass 주석이 있는 클래스는 JPA 엔터티로 간주됩니다.
  • Bootstrapping mode
    • Spring Data JPA가 EntityManager와 Repository를 초기화하는 방식을 뜻합니다. 
    • default, deferred, lazy라는 세 가지 mode를 지원합니다.
    • spring.data.jpa.repositories.bootstrap-mode 속성을 deferred 또는 lazy로 설정하여 해당 모드를 활성화 할 수 있습니다.
  • Deferred 및 Lazy Bootstrapping
    • 초기화 과정이 비동기 방식으로 이루어집니다.
      • 이때 auto-configured EntityManagerFactoryBuilder는 AsyncTaskExecutor를 부트스트랩 실행자로 사용합니다.
      • 여러 AsyncTaskExecutor가 있을 경우 applicationTaskExecutor라는 이름의 것이 사용됩니다.
    • 이 모드를 사용할 때는 애플리케이션 컨텍스트 부트스트랩 단계 이후에 JPA 인프라에 액세스를 지연시켜야 합니다.
  • JPA 초기화
    • SmartInitializingSingleton을 사용하여 JPA 관련 인프라의 초기화를 수행할 수 있습니다.
    • SmartInitializingSingleton는 모든 싱글턴 빈이 완전히 초기화된 후에 초기화 로직을 실행하려는 빈에 사용됩니다.
  • JPA 컴포넌트와 Spring Bean
    • ObjectProvider를 사용하여 Spring Bean의 특정 종속성의 초기화를 지연시킵니다.
    • ObjectProvider는 빈의 지연로딩 및 조회를 지원하는 인터페이스 입니다.

 

Creating and Dropping JPA Databases
  • JPA 데이터베이스 자동 생성
    • 기본적으로 JPA는 embedded in-memory database를 사용할 때만 database를 자동으로 생성합니다.
  • 자동 생성 설정 (ddl execution)
    • Hibernate property : hibernate.hbm2ddl.auto 
      • Hibernate property는 spring.jpa.hibernate 속성으로 설정할 수 있습니다.
    • JPA property
      • spring.jpa.hibernate.ddl-auto
      • spring.jpa.generate-ddl (hibernate 자동 구성이 활성화 될 경우 사용되지 않음)
  • DDL 실행 지연
    • 기본적으로 DDL 실행은 ApplicationContext가 시작될 때까지 지연됩니다. 

 

Open EntityManager in View
  • Open EntityManager in View" (OEMIV) 패턴
    • JPA와 관련된 웹 애플리케이션에서 사용하는 디자인 패턴 중 하나입니다.
  • HTTP 요청의 수명 동안 EntityManager (또는 Session in Hibernate)를 열어 두는 것입니다.
    • 일반적으로 서비스 계층에서 트랜잭션이 종료되고 데이터베이스 연결이 반환된 후에 EntityManager가 닫히게 됩니다.
      • 이 시점에 지연 로딩을 시도하면 LazyInitializationException이 발생합니다.
    • HTTP 응답을 생성하는 View 계층까지 EntityManager를 열린 상태로 유지합니다.
      • 이로 인해 HTTP 응답을 생성하는 동안 지연 로딩(Lazy Loading)을 사용할 수 있게 됩니다.
  • 문제점
    • 효율성 : View에서 필요하지 않은 데이터를 실수로 로딩할 수 있습니다. 이로인해 성능 저하가 발생할 수 있습니다.
    • 트랜잭션 관리 : OEMIV는 트랜잭션 범위 밖에서 데이터를 로딩하므로, 일관성 있는 트랜잭션 관리가 어려울 수 있습니다.
  • 설정
    • 웹 애플리케이션에서 OpenEntityManagerInViewInterceptor를 기본적으로 등록하여 OEMIV 패턴을 적용합니다.
    • spring.jpa.open-in-view 속성으로 끄고 켤수 있습니다.

 

 

 

참고