- Spring-Boot-Starter-JDBC
- spring-jdbc
- 스프링부트 자동설정
- DataSourceAutoConfiguration, JdbcTemplateAutoConfiguration 등이 적용
- 자동 설정된 빈: DataSource, JdbcTemplate
많이 쓰이는 인메모리 데이터베이스
- HSQL
- Derby
- H2 : 추천, 콘솔떄문?
H2 의존성 추가 : 버전은 스프링 부트가 관리
H2의존성이 클래스 패스에 들어가 있고 아무런 DataSource를 하지 않았다면
스프링부트가 자동으로 인메모리DB가 설정되고 이를 바탕으로 DataSource가 빈 등록되고
이 DataSource를 가지는 JdbcTemplate 빈도 등록이 되서 바로 작업 가능
해당 부분은 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
를 보면 알 수 있다
- Hikari CP
DataSourceProperties에서 DB,user,password 만드는 부분 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
//중간 생략
//DB 이름 : 따로 정의하지 않으면 testdb
public String determineDatabaseName() {
if (this.generateUniqueName) {
if (this.uniqueName == null) {
this.uniqueName = UUID.randomUUID().toString();
}
return this.uniqueName;
}
if (StringUtils.hasLength(this.name)) {return this.name;}
if (this.embeddedDatabaseConnection != EmbeddedDatabaseConnection.NONE) {
return "testdb";
}
return null;
}
//사용자 이름: 따로 정의하지 않으면 sa
public String determineUsername() {
if (StringUtils.hasText(this.username)) {
return this.username;
}
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {
return "sa";
}
return null;
}
//password: 따로 정의하지않으면 blank 암호
public String determinePassword() {
if (StringUtils.hasText(this.password)) {
return this.password;
}
if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {
return "";
}
return null;
}
}
스프링부트가 자동으로 만들어준 DataSource를 통해서 간단한 테스트를 해본다
1 |
|
- 설명
@Autowired로 스프링부트가 자동으로 생성한 DataSource를 받아왔다
@Autowired로 JdbcTemplate도 받아왔다
DataSource로부터 Connection을 만들었으며 커넥션의 getMetaData()를 통해서
필요한 정보를 getURL(), getUserName()로 가져왔다- getURL(): jdbc:h2:mem:testdb
- getUserName(): SA
테이블 생성후 값 2개 넣고 전체 조회해서 출력하는 간단한 예제
ResultSetMetaData를 이용해서 ResultSet의 컬럼수를 쉽게 알 수 있음을 주목
jdbcTemplate를 사용해서 바로 위의 Statement 사용과 간결해짐 비교
Spring-JDBC가 제공하는 JdbcTemplate를 사용하면 이렇게 간결하게 사용가능
try-catch를 따로 하지 않아도 리소스 처리가 잘되어있으며 예외처리의 경우에도
더 가독성이 좋은 메세지 확인 가능인텔리J Ultimate의 DB의 Datasource 추가로 간단하게 콘솔 접근 가능
H2 Console 직접 켜기 위해선 2가지 방법
- spring-boot-devtools 추가
- spring.h2.console.enabled=true(applications.properties)
올린후 localhost:8080/h2-console에 접속하면 끝
2. MySql
지원 DBCP
- HikariCP(default)
- TomcatCP
- Commons DBCP2
역시 applications.properties에 해당 DBCP의 설정이 가능하다
- 예)spring.datasource.hikari.maximum-pool-size=5
- HikariDataSource는 HikariConfig를 상속하고 있으며 여기에 많은 값들이 정의
요새는 직접 Mysql을 추가하기 보다는 도커로 mysql을 올린다
mysql-connector-java만 의존성에 추가한다(mysql에 대한 datasource 구현체 포함)
1 | <dependency> |
이러면 mysql-connector-java-
try (Connection conn = dataSource.getConnection()) {
1 | ##mysql |
- 에러처리
- 타임존
- 나의 경우에는 우분투를 사용하는 원격 컴퓨터에 도커로 mysql을 쓰고 접속했는데
타임존이 KST라는 에러가 나와서 타임존을표준인 UTC로 하도록 url쿼리에 설정
- 나의 경우에는 우분투를 사용하는 원격 컴퓨터에 도커로 mysql을 쓰고 접속했는데
- SSL
- mysql의 경우 특정버전이상인경우 SSL연결을 강제하는 것으로 보인다
- 이상적으로는 useSSL=true이고 truststore를 주어서 SSL로 접속할 수 있게끔
- 테스트시에는 무시
- 타임존
mysql 커뮤니티에디션도 영리목적으로 사용 불가하므로 MariaDB를 쓰자
3. PostgreSQL
1 | <dependency> |
1 | ##postgresql |
- 테스트 시작
- 테스트에서 썼던 테이블명을 users나 accounts등으로 바꾸자
- PostgreSQL에서 user는 키워드임
- spring.datasource-driver-class-name=에 들어가는 값을 스프링 부트가
datasource의 url을 보고 추측하여 자동으로 넣어준다
잘 작동하는 것을 볼 수 있다
4. 스프링데이터 JPA
ORM(Object-Relational Mapping)과 JPA (Java Persistence API)
- 객체와 릴레이션을 맵핑할 때 발생하는 개념적 불일치를 해결하는 프레임워크
- http://hibernate.org/orm/what-is-an-orm/
- JPA: ORM을 위한 자바 (EE) 표준
스프링 데이터 JPA
- Repository 빈 자동 생성
- 쿼리 메소드 자동 구현
- @EnableJpaRepositories
- 스프링에선 애노테이션 사용한뒤 사용해서 설정해야지 본격적으로 사용 가능
- 스프링 부트 사용시엔 자동으로 설정하기 때문에 안해도 됨
- Spring Data JPA -> JPA -> Hibernate -> Datasource
- 의존성
pom.xml 1
2
3
4<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> - 프로퍼티에는 h2가 test 스코프로, postgresql설정은 application.properties에 설정
먼저 엔티티 작성, Repository작성, 그리고 테스트 작성,
1 | //entity |
- 설명
- Entity는 Lombok을 써서 간결하게 하였다 , 아이디부분 잘 볼것
- @SpringBootTest를 사용하면 integration Test가 되서 application.properties가
적용되서 postgresql이 되고 @DataJpaTest를 사용하면 무조건 인메모리 DB사용 - JpaRepository를 상속받은 “가장 세련된 방법”을 사용하였다
기억안나면 예전 JPA공부하던것 다시 볼 것 - DataSource, JdbcTemplate 말고 AccountRepository까지 @Autowired 할 수 있음
- findById같은 것은 자동설정되나 findByUsername는 없는데 그냥 quick fix를 통해
바로 만들면 된다-아규먼트 타입과 리턴 타입만 한번 쓱 보고 끝
sql 사용할때도 사실 JPA를 통해서 사용할 수 있다
- JpaRepository의 메소드(여기서는 findByUsername)에 @Query 붙여서 가능
- 기본적으론 JPQL문법을 써야하는데 nativeQuery=true하면 native쿼리가 가능
public interface AccountRepository extends JpaRepository<Account, Long> {
@Query(nativeQuery = true, value = "select * from account where username= :username")
Optional<Account> findByUsername(String username);
}
위에서 Optional형태의 리턴으로 바꿨다
이경우에는 테스트를 empty 유무로 바꿔야한다
assertThat(existingAccount).isNotEmpty();
assertThat(nonExistingAccount).isEmpty();
tip : 전에 JPA공부할때 알았는데 또 까먹
- sql 보이게 하는 방법: spring.jpa.show-sql=true
- sql 이쁘게 보이는 방법: spring.jpa.properties.hibernate.format_sql=true
- ?값 보이게 하는 법: logging.level.org.hibernate.type.descriptor=trace
5. DB 초기화
초기화 방법
JPA를 사용한 DB 초기화 : DDL 자동생성 및 실행기능 -> 2개의 외부 속성
- spring.jpa.hibernate.ddl-auto(enum):하이버네이트 특성
- none: 자동 DDL 생성안함
- create: 하이버네이트 SessionFactory가 시작할떄마다 항상 다시 생성,
이미 존재하면 드롭후 다시 생성 - create-drop: SessionFactory 시작시 생성하고 종료할때 드롭
- update : SessionFactory 시작시 엔티티 클래스와 DB에 생성된 스키마를 비교해서
DB에 반영이 안된 테이블이나 컬럼이 있으면 생성, 기생성된 부분은 건들지 않음 - validate: update처럼 비교하되 변경은 하지 않고 다르다면 예외 발생
- hsqldb, h2, derby등의 in-memory DB는 create-drop이 기본값이며
나머지는 none이 기본값
- spring.jpa.generate-dll(boolean)
- DB벤더에 종속적이지 않는다
- 운영시엔 generate-dll=false에 ddl-auto=validate로 하면 된다
- spring.jpa.hibernate.ddl-auto(enum):하이버네이트 특성
SQL 스크립트를 사용한 DB 초기화
- schema.sql 또는 schema-${platform}.sql -> table 생성쪽
- data.sql 또는 data-${platform}.sql -> data 입력쪽
- ${platform}값은 spring.datasource.platform으로 설정가능
- 예를 들어서 에디션별, 버전별
개발시에는 update로 쓰다가 배포시점이 가까워지면 테스트실행후
나오는 sql문들로 schema.sql을 만들면 깔끔한 sql을 생성할 수 있다
DB와 DB데이타를 체계적으로 관리하고 싶다면 DB 마이그레이션 툴을 사용하는게 좋다
스프링 부트는 DB 마이 그레이션 툴도 지원한다
6. DB Migration tool
Flyway와 Liquibase가 대표적
Related POST
- [Spring Boot] 13. Spring REST Client
- [Spring Boot] 12. Spring Security
- [Spring Boot] 11. Spring Data
- [Spring Boot] 10. 스프링 웹 MVC-2: Spring HATOAS, CORS
- [Spring Boot] 9. 스프링 웹 MVC-1:
- [Spring Boot] 8. Spring-Boot-Devtools
- [Spring Boot] 7. 테스트(Testing)
- [Spring Boot] 6. 로깅(Logging)
- [Spring Boot] 5. Profiles
- [Spring Boot] 4. 스프링부트 외부설정
- [Spring Boot] 3. 스프링부트 핵심기능
- [Spring Boot] 2. 스프링부트 이해
- [Spring Boot] 1. 스프링부트 시작