본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Document

[SpringBoot] 공식 문서 요약(7) - SQL 데이터베이스

by 김코더 김주역 2021. 12. 19.
반응형

SpringBoot Document Review 7

https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/

 

 

 

SQL 데이터베이스

https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-sql.html

 

 

 

- Spring Framework는 JdbcTemplate과 ORM기술을 제공한다.

- Spring Data는 인터페이스들로부터 직접적으로 Repository 구현체를 만들고, 메소드명으로부터 쿼리로 변환시킬 수 있는 기능을 제공한다.

1. DataSource 설정

- Java의 javax.sql.DataSource 인터페이스는 데이터베이스 연동을 위한 표준 방법을 제공한다.

- 보통, DataSource는 데이터베이스 연결을 구축하기 위해 인증과 함께 URL을 사용한다.

 

1) 내장 DB에 연결하기

- in-memory DB는 persistent storage를 제공하지는 않는다.

- SpringBoot는 내장 H2, HSQL, Derby DB들을 자동 설정 해주기 때문에, 연결 URL들을 설정하지 않아도 되고 관련 dependency만 추가해주면 된다. 참고로, spring-jdbc가 포함되어 있어야 자동 설정이 이루어지는데, 웬만하면 DB관련 starter들에 포함되어 있다.

- 'spring.datasource.generate-unique-name=true'로 설정하면 각 application context가 하나의 개별 내장 DB를 가질 수 있도록 보장된다.

- 내장 DB의 연결 URL을 설정할 때, DB의 자동 shutdown이 비활성화 되도록 신경써야 한다. 이를 비활성화하면, DB의 종료를 SpringBoot가 DB로의 접근이 더 이상 필요하지 않으면 연결이 종료되도록 제어를 할 수 있게 된다.

※ H2의 경우 : "DB-CLOSE-ON-EXIT=FALSE"

※ HSQLDB의 경우 : "shutdown=true"를 제외할 것

- SpringBoot는 자동으로 DataSource의 스키마를 생성하고 초기화한다. DDL script와 DML script로 각각 root classpath의 schema.sql, data.sql 파일을 참조한다. 만약 platform을 사용한다면 schema-${platform}.sql, data-${platform.sql}.sql 파일을 참조한다. platform 값은 spring.datasource.platform 속성에 지정된 값으로, hsqldb, h2, oracle, mysql, postgresql 등을 지정 가능하다.

 

 

2) Production DB에 연결하기

- DataSource를 사용하여 Production DB 연결에 대한 자동 설정이 이루어질 수 있다.

- DataSource의 적용 우선순위는 HikariCP>Tomcat>Commons DBCP2이며, spring-boot-starter-jdbc 혹은 spring-boot-starter-data-jpa를 사용하면 HikariCP dependency가 자동으로 적용된다. 이 우선순위를 우회하기 위해 spring.datasource.type 속성을 지정하는 방법도 있다.

- DataSource Bean을 따로 정의하면 자동 설정은 이루어지지 않는다.

 

application.properties에서의 DataSource 설정 예시

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

 

2. JdbcTemplate 사용하기

- Spring의 JdbcTemplate, NamedParameterJdbcTemplate 클래스는 자동 설정되며, 아래 예시와 같이 이들을 Autowire하여 사용할 수 있다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
	private final JdbcTemplate jdbcTemplate;

	@Autowired
	public MyBean(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	// ...
}

- spring.jdbc.template.* 속성으로 JdbcTemplate 관련 설정이 가능하다.

- NamedParameterJdbcTemplate는 동일한 JdbcTemplate를 재사용하는 클래스이고, 2개 이상의 JdbcTemplate이 정의되었으면서 primary candidate가 존재하지 않는다면 NamedParameterJdbcTemplate는 자동 설정되지 않는다.

 

+참고) 여러 DataSource 사용하기

https://knight76.tistory.com/entry/spring-boot-multidatasource-multi-db-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

[spring boot] multi-datasource (multi db) 간단하게 사용하기

spring boot에서 아주 간단히 multi-datasource를 관리하고 jdbctemplate를 사용할 수 있는 예제를 소개한다. 먼저 maven또는 gradle 파일의 dependency에 db의 driver, spring-boot-starter-jdbc, commons-dbcp2..

knight76.tistory.com

https://2dongdong.tistory.com/33

 

Spring JPA Multiple Databases 설정

<!doctype html> Spring JPA – Multiple Databases 1. 다중 DB 설정 시, 알아야 할 것2. 소스코드2-1. Entity2-2. Repository2-3. DB Configuration2-3-1 application.properties2-3-2 Main Datasource2-3-3 Seco..

2dongdong.tistory.com

 

 

 

3. JPA

https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-sql.html#boot-features-jpa-and-spring-data

- JPA(Java Persistence API)는 객체를 Relational DB와 매핑해주는 표준 기술이다.

- spring-boot-starter-data-jpa pom을 추가함으로써 적용되며, Hibernate, Spring Data JPA, Spring ORMs dependency들이 같이 제공된다.

  • ORM(Object Relational Mapping) : 객체와 관계형 데이터베이스(RDB)를 매핑시켜주는 프레임워크
  • JPA(Java Persistent API) : ORM을 사용하기 위한 인터페이스들을 모아둔 것
  • Hibernate : JPA를 구현한 ORM 라이브러리들중 하나

 

1) Entity Classes

- 보통 JPA Entity 클래스들은 persistence.xml에 명시되어 있지만, SpringBoot에서는 persistence.xml 파일이 필수가 아닌 대신에 Entity Scanning이 사용된다.

- 기본적으로 main configuration 클래스(@EnableAutoConfiguration 혹은 @SpringBootApplication)가 포함되어 있는 모든 패키지들이 스캐닝되고, @Entity, @Embeddable, 혹은 @MappedSuperclass가 붙은 모든 클래스들이 스캐닝된다.

- @EntityScan 어노테이션을 이용하여 Entity를 스캐닝할 위치를 커스터마이징할 수 있다.

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class City implements Serializable {

	@Id
	@GeneratedValue
	private Long id;

	@Column(nullable = false)
	private String name;

	@Column(nullable = false)
	private String state;

	// ... additional members, often include @OneToMany mappings

	protected City() {
		// JPA에서는 argument가 없는 생성자도 필요하다.
		// 직접적으로 사용되지 않도록 protected 접근자를 사용한 것이다.
	}

	public City(String name, String state) {
		this.name = name;
		this.state = state;
	}

	public String getName() {
		return this.name;
	}

	public String getState() {
		return this.state;
	}

	// ... etc

}

 

 

2) Spring Data JPA Repositories

- Spring Data JPA Repository는 데이터 접근을 위해 정의할 수 있는 인터페이스이다.

- JPA 쿼리들은 메소드명에 의해 자동으로 생성된다. - 예) findAllByState(String state)

- 더 복잡한 JPA 쿼리들의 경우에는, Spring Data의 @Query 어노테이션에 SQL문을 직접 작성해서 메소드에 붙일 수도 있다.

- 자동 설정을 사용한다면, repository들은 메인 configuration 클래스(@EnableAutoConfiguration 또는 @SpringBootApplication)를 포함하는 패키지로부터 스캐닝된다.

- Spring Data repository들은 보통 Repositoy, CrudRepository, 혹은 JpaRepository 클래스를 상속 받는다.

import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
	Optional<User> findByEmail(String email);
}
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {
	Page<City> findAll(Pageable pageable);
	City findByNameAndStateAllIgnoringCase(String name, String state);
}

※ Spring Data repository 클래스를 상속받는 인터페이스는 자동으로 Bean 등록이 된다.

 

 

3) Creating and Dropping JPA Databases

- 기본적으로, JPA 데이터베이스는 내장 데이터베이스(H2, HSQL, Derby)를 사용할 경우에만 자동 생성된다.

- "spring.jpa.*" 속성을 사용하여 명시적으로 JPA 설정을 할 수 있다.

spring.jpa.hibernate.ddl-auto=create-drop

※ 위의 설정에 대한 Hibernate의 내부 속성명은 hibernate.hbm2ddl.auto이며, "spring.jpa.properties.*" 속성을 사용함으로써 다른 Hibernate의 고유의 속성들과 함께 사용할 수 있다.

spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop

- 기본적으로, DDL 실행은 ApplicationContext가 시작될때까지 미뤄진다.

- 자동 설정이 활성화되어 있다면 "spring.jpa.generate-ddl" 속성은 사용되지 않는다.

 

 

4) Open EntityManager in View

- Web application을 실행하면 Spring Boot는 기본적으로 Web View에서 lazy loading을 허용하도록 OpenEntityManagerInViewInterceptor를 등록하여 "Open EntityManager in View" 패턴을 적용한다. 이 동작을 원하지 않는다면, application.jpa.open-in-view 속성을 application.properties에서 false로 설정하면 된다.

 

 

 

4. H2의 Web Console 사용하기

- H2 Database는 Spring Boot에 의해 자동 설정된 브라우저 기반 콘솔을 제공해 준다. 웹 애플리케이션(WebFlux 해당 안됨)이고, com.h2database:h2가 classpath에 있고, Spring Boot의 개발툴을 사용해야지만 자동 설정이 이루어진다.

※ Spring Boot의 개발툴을 사용하지 않는 대신에, spring.h2.console.enabled 속성을 true로 설정하는 방법도 있다.

- H2 console을 개발용으로만 사용하는 것이라면, Production 환경에서 spring.h2.console.enabled 속성을 true로 지정하지 않도록 각별한 주의가 필요하다.

- 기본 console 경로는 "/h2-console"인데, "spring.h2.console.path" 속성을 이용하여 console의 경로를 커스터마이징할 수 있다.

 

 

 

5. jOOQ 사용하기

https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-sql.html#boot-features-jooq

https://www.jooq.org/doc/3.11.12/manual-single-page/#Overview

- jOOQ는 Java Object Oriented Querying의 줄임말로, 데이터베이스로부터 Java 코드를 생성해주는 Data Geekery의 유명 제품이다.

- jOOQ는 type-safe SQL 쿼리들을 API를 통하여 빌드해준다.

- Spring Boot와 함께 상업용과 오픈소스판이 둘다 사용될 수 있다.

 

 

1) Code 생성

- jOOQ의 type-safe 쿼리들을 이용하기 위해, 데이터베이스 스키마에 대한 Java 클래스를 미리 생성해야 한다.

- jooq-codegen-maven 플러그인을 사용할 때 spring-boot-starter-parent가 있다면, 플러그인의 <version> 태그를 생략할 수 있다. 추가로, 플러그인의 dependency를 선언하기 위해 "h2.version"과 같은 Spring Boot가 정의하는 버전 변수를 사용할 수도 있다.

 

- 플러그인 설정 : https://github.com/jOOQ/jOOQ/blob/main/jOOQ-examples/jOOQ-jpa-example/pom.xml (<!-- The jOOQ code generator plugin --> 부분)

※ 위 붉은 상자 부분에는 스캔하려는 여러분의 패키지명을 입력하고, 아래 붉은 상자 부분에는 DB 스키마로부터 생성된 Java 클래스를 생성할 패키지 위치를 입력한다.

 

 

2) DSLContext 사용

- DSL은 SQL을 코드로 작성할 수 있도록 하는 빌더 오픈소스 API이다.

- jOOQ가 제공하는 API는 org.jooq.DSLContext 인터페이스를 통해 초기화된다.

- DSLContext는 Spring Bean으로 자동 설정되고, DSLContext를 애플리케이션의 DataSource에 연결한다.

- DSLContext를 사용하기 위해 @Autowired를 사용할 수 있다.

...
@Autowired
DSLContext dsl;
...
dsl.insertInto(USER)
    .set(USER.ID, Sequences.HIBERNATE_SEQUENCE.nextval())
    .set(USER.NAME, "Jooyeok")
    .set(USER.AGE, 24")
    .execute();

 

 

3) jOOQ SQL Dialect(방언)

- 만약 "spring.jooq.sql-dialect" 속성이 설정되어 있지 않다면, Spring Boot가 datasourse를 위한 SQL Dialect를 직접 판단한다. Dialect를 판단하지 못했을 경우에는 DEFAULT를 반환한다.

※ dialect(방언) : DB로서의 방언은, 같은 동작이라도 DB 종류마다 사용하는 명령어가 다르기 때문에 방언이라고 표현한 것이다. 즉, 해당 DB의 방언으로 소통하기 위해 dialect 설정을 해주는 것이다.

※ jOOQ의 오픈 소스 버전에서 지원해주는 방언만 자동 설정 될 수 있다.

 

 

4) jOOQ 커스터마이징

- @Bean을 직접 정의함으로서, 더 개선된 커스터마이징이 가능하다.

- 아래에 있는 jOOQ 종류들에 대한 @Bean을 정의할 수 있다.

- 만약 jOOQ의 설정을 자신이 완전히 제어하고싶다면, org.jooq.Configuration에 @Bean을 추가하여 생성한다.

 

 

 

반응형

댓글