2023. 4. 25. 09:36ใ์ธํ๋ฐ/์คํ๋ง ๋ถํธ - ํต์ฌ ์๋ฆฌ์ ํ์ฉ
0๏ธโฃ ์์ ํ๋ก์ ํธ ์์ฑ
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//ํ
์คํธ์์ lombok ์ฌ์ฉ
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}
์์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ ๋ Lombok, Spring Web, H2 Database, JDBC API ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ dependencies๋ฅผ ์ถ๊ฐํด์คฌ๋ค.
Member
@Data
public class Member
{
private String memberId;
private String name;
public Member()
{
}
public Member(String memberId, String name)
{
this.memberId = memberId;
this.name = name;
}
}
์์ ํ๋ก์ ํธ๋ ๊ฐ๋จํ๊ฒ ํ์์ ์์ฑํ๊ณ ์ ์ฅํ๋ฉฐ ์กฐํํ๋ ๊ฐ๋จํ ํ๋ก์ ํธ๋ก Member ํ์์๋ memberId์ name ํ๋๊ฐ ์๋ ๊ฐ์ฒด์ด๋ค.
DbConfig
@Slf4j
@Configuration
public class DbConfig
{
@Bean
public DataSource dataSource()
{
log.info("dataSource ๋น ๋ฑ๋ก");
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setJdbcUrl("jdbc:h2:mem:test");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
@Bean
public TransactionManager transactionManager()
{
log.info("transactionManager ๋น ๋ฑ๋ก");
return new JdbcTransactionManager(dataSource());
}
@Bean
public JdbcTemplate jdbcTemplate()
{
log.info("jdbcTemplate ๋น ๋ฑ๋ก");
return new JdbcTemplate(dataSource());
}
}
์์ ํ๋ก์ ํธ๋ jdbcTemplate๋ฅผ ์ฌ์ฉํด์ ํ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์๋ ์ง์ DataSource, TransactionManager, JdbcTemplate ์ ์คํ๋ง ๋น์ผ๋ก ์ง์ ๋ฑ๋กํ๋ค.
(JdbcTanscationManager๋ DataSoureTransactionManager ์ ๊ฐ์ ๊ฒ์ผ๋ก ๋ณด๋ฉด ๋๋๋ฐ JdbcTransactionManager๋ ๊ธฐ์กด์์ ์์ธ ๋ณํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์๋ค.)
MemberRepository
@Repository
public class MemberRepository
{
public final JdbcTemplate template;
public MemberRepository(JdbcTemplate template)
{
this.template = template;
}
public void initTable()
{
template.execute("create table member (member_id varchar primary key , name varchar)");
}
public void save(Member member)
{
template.update("insert into member(member_id, name) values (?,?)", member.getMemberId(), member.getName());
}
public Member find(String memberId)
{
return template.queryForObject(
"select member_id , name from member where member_id = ? ", BeanPropertyRowMapper.newInstance(Member.class), memberId);
}
public List<Member> findAll()
{
return template.query("select member_id, name from member", BeanPropertyRowMapper.newInstance(Member.class));
}
}
JdbcTemplate๋ฅผ ์ฌ์ฉํด์ ํ์์ ๊ด๋ฆฌํ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ด๋ค.
*initTable : ๋ณดํต ๋ฆฌํฌ์งํ ๋ฆฌ์ ํ ์ด๋ธ์ ์์ฑํ๋ ์คํฌ๋ฆฝํธ๋ ๋ฃ์ด๋์ง ์๋๋ฐ ์์ ํ๋ก์ ํธ๋ผ์ ์ฌ๊ธฐ์ ๋จ์ํ ํ๊ธฐ ์ํด์ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ฃ์ด๋๋ค.
MemberRepositoryTest
@SpringBootTest
class MemberRepositoryTest
{
@Autowired
MemberRepository memberRepository;
@Transactional
@Test
void memberTest()
{
Member member = new Member("idA", "memberA");
memberRepository.initTable();
memberRepository.save(member);
Member findMember = memberRepository.find(member.getMemberId());
Assertions.assertThat(findMember.getMemberId()).isEqualTo(member.getMemberId());
Assertions.assertThat(findMember.getName()).isEqualTo(member.getName());
}
}
๊ทธ๋ฆฌ๊ณ ๋ง๋ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํ ์คํธํด๋ณผ ๊ฒ์ธ๋ฐ ctrl+ shift + T ๋๋ฅด๋ฉด ์ฝ๊ฒ ํ ์คํธ ํด๋์ค๋ฅผ ์์ฑํ ์์๋ค. (์ธํ ๋ฆฌ์ ์ด ๋จ์ถํค ใ ใ )
์คํ๋ง ๋ถํธ๋ฅผ ์ฌ์ฉํด์ ํ ์คํธํด์ผํ๊ธฐ ๋๋ฌธ์ @SpringbootTest ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๊ณ ,
@Transactional ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ ํธ๋์ญ์ ๊ธฐ๋ฅ์ ์ ์ฉํ๋ค. (์ด ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ ค๋ฉด TransactionManager๊ฐ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋์ด ์์ด์ผ ํ๋ค.)
๐ ์์ ํ ์คํธ๋ฅผ ์คํํด๋ณด๊ณ ์ ์ ๋์ํ๋ฉด ๋ ๊ฒ์ธ๋ฐ...
์ง๊ธ ๋ณด๋ฉด ์ง์ DataSource, TransacionManager, JdbcTemplate๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์คฌ๋๋ฐ..
DB๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ค๋ฅธ ํ๋ก์ ํธ๋ฅผ ๋ ํ๋ค๋ฉด ์ด๋ฌํ ๊ฐ์ฒด๋ค์ ๋ฐ๋ณตํด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์ผ ํ๋ค..
1๏ธโฃ ์คํ๋ง ๋ถํธ ์๋ ๊ตฌ์ฑ Auto Configuration
์ฌ์ค DbConfig์ @Configuration ์ด๋ ธํ ์ด์ ์ ์ ๊ฑฐํ๊ณ ํ ์คํธ๋ฅผ ์คํํด๋ ์ ์ ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฐ๋ฆฌ๊ฐ ์ง์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ์ง ์์๋ ์ฌ์ค ์คํ๋ง ๋ถํธ๊ฐ ์๋์ผ๋ก ๋ฑ๋กํด์ค๋ค.
์คํ๋ง ๋ถํธ๋ ์๋ ๊ตฌ์ฑ Auto Configuration ์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ ์ผ๋ฐ์ ์ผ๋ก ์์ฃผ ์ฌ์ฉํ๋ ์๋ง์ ๋น๋ค์ ์๋์ผ๋ก ๋ฑ๋กํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค. ์์์ ๋ดค๋ JdbcTemplate, DataSource, TransactionManager ๋ชจ๋ ์คํ๋ง ๋ถํธ๊ฐ ์๋ ๊ตฌ์ฑ(Auto Configuration) ์ ์ ๊ณตํด์ ์๋์ผ๋ก ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์ค๋ค.
JdbcTemplateAutoConfiguration
@AutoConfiguration(after = DataSourceAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(JdbcProperties.class)
@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {
}
์คํ๋ง ๋ถํธ๋ spring-boot-autoconfiguration ์ด๋ผ๋ ํ๋ก์ ํธ ์์์ ์๋ง์ ์๋ ๊ตฌ์ฑ์ ์ ๊ณตํ๋ค.
@AutoConfiguration : ์๋ ๊ตฌ์ฑ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ด ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ผ ํ๋ค.
@ConditionalOnClass ({DataSource.class, JdbcTemplate.class})
: if ๋ฌธ๊ณผ ์ ์ฌํ๊ฒ ์๊ฐํ๋ฉด ๋๋๋ฐ ์์ ์ง์ ํ ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง ์ค์ ์ด ๋์ํ๋๋ก ์ค์ ํ๋ค. ๋ง์ฝ ์ด ํด๋์ค๋ค์ด ์๋ค๋ฉด ์ฌ๊ธฐ ์๋ ์ค์ ์ ํ์ง ์๋๋ค.
JdbcTemplateConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JdbcOperations.class)
class JdbcTemplateConfiguration {
@Bean
@Primary
JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
JdbcProperties.Template template = properties.getTemplate();
jdbcTemplate.setFetchSize(template.getFetchSize());
jdbcTemplate.setMaxRows(template.getMaxRows());
if (template.getQueryTimeout() != null) {
jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());
}
return jdbcTemplate;
}
}
@Configuartion : ์๋ฐ ์ค์ ํ์ผ๋ก ์ฌ์ฉ๋๋ค.
@ConditionalOnMissinigBean (JdbcOperationis.class)
: JdbcOperation ๋น์ด ์์ ๋ ๋์ํ๋๋ก ํ๋ ๊ฒ์ผ๋ก JdbcOperations๋ JdbcTemplate์ ๋ถ๋ชจ ์ธํฐํ์ด์ค๋ก ์ฆ, JdbcTemplate ๊ฐ ๋น์ผ๋ก ๋ฑ๋ก๋์ด ์์ง ์๋ ๊ฒฝ์ฐ์๋ง ๋์ํ๋ค.
-> ์ฆ, ๊ฐ๋ฐ์๊ฐ ์ง์ JdbcTemplate ์ ๋ฑ๋กํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ฑ๋กํ ๋น์ ์ฌ์ฉํ๊ณ , ์๋ ๊ตฌ์ฑ์ ๋์ํ์ง ์๊ฒ ๋๋ค.
์ด๋ฐ์์ผ๋ก ์๋ ๊ตฌ์ฑ ๊ธฐ๋ฅ๋ค์ด ํ์ํ ๊ฒ๋ค์ ๋น์ผ๋ก ๋ฑ๋กํด์ค๋ค.
DataSource -> DataSourceAutoConfiguration
TransactionManager -> DataSourceTransactionManagerAutoConfigurationi
JdbcTemplate -> JdbcTemplateAutoConfiguration
๐ Auto Configuration
์คํ๋ง ๋ถํธ๋ ์ ๋ง์ ์๋ ๊ตฌ์ฑ์ ์ ๊ณตํ๊ณ , spring-boot-autoconfigure ์ ์๋ ๊ตฌ์ฑ์ ๋ชจ์๋๋ค.
๊ทธ๋ฆฌ๊ณ ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ๋ฉด spring-boot-autoconfigure ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉํ๋ค.