728x90
1. test - 임베디드 모드 db
- 사용 이유
- test case를 실행하려고 별도의 db를 설치하고, 운영하는 것이 비효율적
- 단순 검증 용도로 사용하므로 test 종료시 db의 data를 모두 삭제해도 된다.
- 더해서 test 종료시, db 자체를 날려도 된다.
- 임베디드 모드
- H2 db는 java로 개발 되어있고 JVM 안에서 memory 모드로 동작한느 특별한 기능 제공
- app 실행할 때 H2 데이터베이스도 해당 JVM 메모리에 포함해서 함께 실행 하 수 있다.
- db를 app에 내장해서 함께 실행한다고 Embedded mode라고 한다.
- app 종료시, embedded mode로 동장하는 H2 db도 함께 종료되고 data도 모두 사라진다.
= java libarary처럼 동작한다.
- 수동, 자동 공통 적용 부분
- db database 관련 설정 등록 하면 안된다.
- main/resources/schema.sql 파일에 table 생성 sql 등록이 필요하다.
1.1. 메모리 db용 sql 파일 생성 (공통)
- embedded 용 db기 때문에 매번 사라졌다 생기므로 table 자체가 저장 될 수 없다.
- repository에 ddl 로 table을 넣을 수도 있지만 번거롭다.
- 조금 더 편리한 emebedded(=memory) db 용 sql 파일을 생성
- 경로 : main/resources/schema.sql
-- memory h2는 현재 table이 생성되어있지 않는 상태
-- 해당 file에서 table을 생성 해줄 것
-- 규칙이니깐 걍 따를 것
drop table if exists item CASCADE;
create table item
(
id bigint generated by default as identity,
item_name varchar(10),
price integer,
quantity integer,
primary key (id)
);
1.2. application.properties database 설정 (공통)
- 우선 순위 : @SpringBootApplication 내부 @Bean 수동 등록 > @application.properties 수동등록 > 자동등록
- 수동 모드일 경우는 결국 최상단의 @SpringBootApplication의 main method 내부에서 @Bean을 등록하기 때문에 application.properties의 database 등록이 덮어지지만
- 자동 모드일 경우, embedded 모드가 수행되지 않게 된다. application.properties에서 database를 수동으로 등록했기 때문
- 결론 : 헷갈리지 않게 embedded 모드 쓸꺼면 application.properties에서 database 등록 하지 말 것
spring.profiles.active=test
# db 연결 - test -> testcase 변경
# spring.datasource.url=jdbc:h2:tcp://localhost/~/testcase
# spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug
1.3. 임베디드 모드 직접 사용
1.3.1. application Class
package hello.itemservice;
@Slf4j
@Import(JdbcTemplateV3Config.class)
@SpringBootApplication(scanBasePackages = "hello.itemservice.web")
public class ItemServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
// application.properties의 설정 중 local 환경일 경우 @Bean으로 등록한다.
@Bean
@Profile("local")
public TestDataInit testDataInit(ItemRepository itemRepository) {
return new TestDataInit(itemRepository);
}
@Bean
@Profile("test")
public DataSource dataSource() {
log.info("memory database init");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
}
- embedded용 datasource 및 Driver @Bean 등록 - 핵심
@Bean
@Profile("test")
public DataSource dataSource() {
log.info("memory database init");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
- @Profile("test") : 프로필이 test일 경우에만 해당 class를 스프링 빈으로 등록
- jdbc:h2:mem:db : 데이터소스를 만들때 이렇게만 적으면 임베디드 모드로 동작하는 h2 사용가능
- DB_CLOSE_DELAY=-1 : 임베디드 모드에서 db connection 연결이 모두 끊어지면 db도 종료되는데, 그것을 방지하는 설정
- datasource와 driver만 잘 설정하면 된다.
1.4. test - springboot와 임베디드 모드
- spring boot는 @Bean 등록과정을 자동으로 처리
- @Bean 제거
- 수동 모드와 동일하게 작동
package hello.itemservice;
@Slf4j
@Import(JdbcTemplateV3Config.class)
@SpringBootApplication(scanBasePackages = "hello.itemservice.web")
public class ItemServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
@Bean
@Profile("local")
public TestDataInit testDataInit(ItemRepository itemRepository) {
return new TestDataInit(itemRepository);
}
}
2. test / main Profile 실험
- application.properties == AP라고 표현
- test 패키지 경로에 AP file 자체가 없으면 main의 AP를 properties로 사용
- main AP에 datasource 등록이 되어있으면 해당 db를 이용해서 test 수행
- main AP에 datasource 등록 없으면 embedded mode db 수행
- test 패키지 경로에 AP file 이 있는 경우
- 내부에 profile 설정 여부와 관계없이 해당 test AP를 이용해서 springboot test 수행- test AP에 datasource 등록이 되어있으면 해당 db를 이용해서 test 수행
- test AP에 datasource 등록 없으면 embedded mode db 수행
- test class에 @Transactional 존재 여부시, 달라지는 log
- mem이 나오는 것이 확실이 embedded mode임을 나타내는데 2번의 경우도 db를 실행안해도 test가 정상 동작하므로 embedded 모드라고 추정할 수 있다.
- @Transactional 존재 시,
> [HikariProxyConnection@1631143060 wrapping conn0: url=jdbc:h2:mem:b175c7c8-3ee4-4c58-9773-f0be5b88066d user=SA] - @Transactional 존재 안할 시,
> com.h2database/h2/1.4.200/f7533fe7cb8e99c87a43d325a77b4b678ad9031a/h2-1.4.200
- @Transactional 존재 시,
참고 발행글 : 2023.09.25 - [spring/spring db2] - 3. 데이터 접근 기술 - 테스트