JDBC템플릿 JDBC트랜잭션 매니저를 DataSource에 등록해보겠습니다.
두개의 빈은 DataSource빈에 의존해야합니다.
또한, DataSource구성정보가 한개만 등록되었을때 동작해야합니다.
JDBC템플릿
: SQL쿼리를 자바 코드로 DB에 전송해줌
JDBC트랜잭션
: SQL쿼리를 하나의 트랙잭션으로 관리해줍니다.
@ConditionalOnSingleCandidate(DataSource.class)
: DataSource Bean 이 한개만 등록되었다면 사용해야 합니다.
@ConditionalOnMissingBean
: 커스텀으로 등록할 것을 대비하여 등록
@EnableMyConfigurationProperties
: @Transaction 어노테이션을 사용할 수 있게 합니다.
@MyAutoConfiguration
@ConditionalMyOnClass("org.springframework.jdbc.core.JdbcOperations")
@EnableMyConfigurationProperties(MyDataSourceProperties.class)
@EnableTransactionManagement // 트랜잭션 매니져를 적용하여 @Transaction 어노테이션을 사용 할 수 있게 합니다.
public class DataSourceConfig {
// ... 히카리, 싱클데이터 소스 빈
@Bean
@ConditionalOnSingleCandidate(DataSource.class) // DataSource Bean 이 한개만 등록되었다면 사용한다는 뜻.
@ConditionalOnMissingBean // 커스텀으로 등록할 것을 대비
JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
@ConditionalOnSingleCandidate(DataSource.class) // DataSource Bean 이 한개만 등록되었다면 사용한다는 뜻.
@ConditionalOnMissingBean // 커스텀으로 등록할 것을 대비
JdbcTransactionManager jdbcTransactionManager(DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
}
DB관련 테스트는 테스트마다 DB가 독립적이여야 하기 때문에 @Transaction 어노테이션이 필수입니다!
이번에는 커스텀 어노테이션을 만들어 사용해 보겠습니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = HellobootApplication.class)
@TestPropertySource("classpath:/application.properties")
@Transactional
public @interface HellobootTest {
}
In-Memory는 휘발성메모리이기 때문에 애플리케이션을 시작할때 테이블을 만들고, 데이터를 초기화 하는 작업을 해야합니다.
@BeforeEach
void init(){
jdbcTemplate.execute("create table if not exists hello(name varchar(50) primary key, count int)");
}
@Transaction
이 걸려있어 단위테스트마다 DB가 롤백이 됩니다!@HellobootTest
public class JdbcTemplateTest {
@Autowired
JdbcTemplate jdbcTemplate;
// ... 테이블 생성
@Test
void insertAndQuery(){
jdbcTemplate.update("insert into hello values(?, ?)", "Toby", 3);
jdbcTemplate.update("insert into hello values(?, ?)", "Spring", 1);
Long count = jdbcTemplate.queryForObject("select count(*) from hello", Long.class);
Assertions.assertThat(count).isEqualTo(2);
}
@Test
void insertAndQuery2(){
jdbcTemplate.update("insert into hello values(?, ?)", "Toby", 3);
jdbcTemplate.update("insert into hello values(?, ?)", "Spring", 1);
Long count = jdbcTemplate.queryForObject("select count(*) from hello", Long.class);
Assertions.assertThat(count).isEqualTo(2);
}
DB와도 잘 연결되어 테스트가 잘 통과되는것을 확인 할수 있습니다!