๐ปConnection ๊ฐ์ฒด ์์ฑ
์ด์ ์๋ DBUtil.open()์ผ๋ก DB ์ฐ๊ฒฐํ์ฌ Connection ๊ฐ์ฒด ์์ฑํ๋ ๊ฒ์ ๋ฐ๋ณตํ๋ค.
๊ด๋ฆฌ๋์ง์๋ Connection ๊ฐ์ฒด๋ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๊ณ ์ฑ๋ฅ์ ์ ํ์ํจ๋ค. ๊ทธ๋์ ์ฌ์ฉ ์๋ฃ๋ Connection๋ค์ close() ํด์ค์ผํ๋๋ฐ ๋ฒ๊ฑฐ๋กญ๋ค๋ ๋ฌธ์ ๊ฐ ์๋ค.
์ด๊ฒ์ ๋ณด์ํ๊ธฐ ์ํ Connection Pool(์ปค๋ฅ์ ํ) ์ด ํ์ํ์๋ค.
๋ฏธ๋ฆฌ ๋ง๋ค์ด์ง Connection Pool๋ฅผ ์ ์ํ ์ฌ์ฉ์์๊ฒ ๋์ฌํ๋ค.
์ฌ์ฉ์๊ฐ ๋ค ์ฌ์ฉํ๋ฉด ์์คํ ์ด Connection์ ํ์ํ๋ค.
๐ปConnection Pool ๋ผ์ด๋ธ๋ฌ๋ฆฌ
MyBatis๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ ์ธ๊ฐ์ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋์ Connection Pool ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ค์ ๋์ด ์์ด์ผํ๋ค.
1. Commos DBCP
DBCP๋ ์ผ๋ฐ์ ์ผ๋ก Jakarta Tomcat์์ ์ฌ์ฉ๋๋ฉฐ, ํนํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๊ธฐ ์ํด ํ์ค์ผ๋ก ์ฑํ๋์ด ์์ต๋๋ค. DBCP๋ JDBC ๋๋ผ์ด๋ฒ์ ํจ๊ป ์ฌ์ฉ๋์ด ์ปค๋ฅ์ ํ๋ง์ ๊ตฌํํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
2. Tomcat DBCP
3. HikariCP
์คํ๋ง๋ถํธ 2.0๋ถํฐ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ๋ค.
HikariCP๋ ํ๋์ ์ด๊ณ ๊ฒฝ๋ํ๋ ์๋ฐ์ฉ ์ปค๋ฅ์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํ๋ค. HikariCP๋ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ ๋น ๋ฅธ ์ปค๋ฅ์ ํ๋ ์๋๋ก ์ ๋ช ํ๋ฉฐ, ๋๋ถ๋ถ์ ํ๊ฒฝ์์ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ฐํํ๋ค. ํนํ, ๋๊ท๋ชจ ๋ฐ ๊ณ ํธ๋์ญ์ ํ๊ฒฝ์์์ ํจ์จ์ฑ์ ์ค์ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ง์ด ์ฌ์ฉ๋๋ค.
ํ์ฌ ๋ง์ด ์ฌ์ฉํ๋ HikariCP์ ๊ณ ์ ์ ์ธ Commos ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ๋ค.
Commos DBCP ์ฌ์ฉํ๊ธฐ
1. commos-dbcp ์์กด์ฑ ์ถ๊ฐ
pom.xml
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
2. ์ค์ ์ถ๊ฐ
WEB-INF > spring > root-context.xml
<!-- Commons DBCP -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="java1234"></property>
</bean>
3. ์ฐ๊ฒฐ ํ ์คํธ
package com.test.persistence;
import static org.junit.Assert.assertNotNull;
import java.sql.Connection;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class DBCPTest {
@Autowired
private DataSource dataSource;
@Test
public void testConnection() {
assertNotNull(dataSource);
try {
Connection conn = dataSource.getConnection();
log.info(conn.isClosed());
} catch (Exception e) {
e.printStackTrace();
}
}
}
HikariCP ์ฌ์ฉํ๊ธฐ
1. ์์กด์ฑ ์ถ๊ฐ
pom.xml
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.4</version>
</dependency>
2. ์ค์ ์ถ๊ฐ
WEB-INF > spring > root-context.xml
<!-- ์ค์ ํ์ผ -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="java1234"></property>
</bean>
<!-- ์ค์ ํ์ผ ์์กด์ฃผ์
-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig"></constructor-arg>
</bean>
์ค์ ํ์ผ ์์กด ์ฃผ์ ๋ถ๋ถ์์ class์ HikariDataSource ๋ ์ปค๋ฅ์ ์ ์๋์ผ๋ก ์ฐ๊ฒฐํด์ค๋ค๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. destroy-method๋ ์์ ํด์ ์ต์ ์ผ๋ก close() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ฐ์ดํฐ ์์ค๊ฐ ์๋ฉธ๋ ๋ ์ปค๋ฅ์ ํ์ ์ ๋ฆฌํ๋๋ก ํ๋ค.
๐ปMyBatis ์ฌ์ฉํ๊ธฐ
์์กด์ฑ ์ถ๊ฐ - pom.xml
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
(DB๊ด๋ จ)์ค์ ์ถ๊ฐ - root-context.xml
<!-- ํ๊ฒฝ์ค์ -->
<bean id="sessionfactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath*:mapper/*.xml"></property>
</bean>
<!-- ํ๊ฒฝ์ค์ ์์กด์ฃผ์
-->
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sessionfactory"></constructor-arg>
</bean>
<ํ๊ฒฝ์ค์ >
sessionfactory: SqlSessionFactory์ ๋น์ ์ ์ํ๋ค. SqlSessionFactory๋ MyBatis์์ ์ธ์ ์ ์์ฑํ๋ ๊ณต์ฅ ์ญํ ์ ํ๋ค.
dataSource: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ค์ ํ๋ค. ์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ HikariCP๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ dataSource ๋น์ ์ฐธ์กฐํ๊ฒ ๋๋ค.
mapperLocations: MyBatis ๋งคํผ ํ์ผ์ ์์น๋ฅผ ์ง์ ํ๋ค. ๋งคํผ ํ์ผ์ SQL ์ฟผ๋ฆฌ์ ์๋ฐ ๊ฐ์ฒด ๊ฐ์ ๋งคํ์ ๋ด๋นํ๋ค.
classpath*:mapper/*.xml : classpath๋ ๋ฃจํธ ํด๋์ 4๊ฐ์ง ํด๋๋ฅผ ์๋ฏธํ๋ค. ๊ทธ ์ค์์ mapper ํด๋๋ฅผ ์ฐพ์ .xml ํ์ผ์ ์ฐพ๋๋ค.
<ํ๊ฒฝ์ค์ ์์กด์ฃผ์ >
SqlSessionTemplate: MyBatis์์ ์ ๊ณตํ๋ ์ธ์
๊ด๋ฆฌ๋ฅผ ์ํ ํ
ํ๋ฆฟ์ด๋ค. ์ด๋ฅผ ํตํด ์ธ์
์ ์์ฑํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ๊ฐ์ํํ ์ ์๋ค.
sessionfactory: ์์ ์ค์ ํ sessionfactory ๋น์ ์ฐธ์กฐํ์ฌ SqlSessionTemplate์ ์์ฑํ๋ค.
์ฐ๊ฒฐ ํ ์คํธ
package com.test.persistence;
import static org.junit.Assert.assertNotNull;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class MapperTest {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Test
public void testQuery() {
assertNotNull(sqlSessionFactory);
}
}
๐ปController ํ์ผ์ 'S' ๋งํฌ๊ฐ ์๋ค๋ฉด
Spring์ด ์ค์บํ๋ ํ์ผ์๋ S๋งํฌ๊ฐ ๋ถ๋๋ฐ S๋งํฌ๊ฐ ์๋ ํ์ผ๋ค์ด ์กด์ฌํ ๋ ์๋ค. ์ด๋ด ๋๋ ์ค์บํ ์ ์๋๋ก ํจํค์ง ๊ฒฝ๋ก๋ฅผ ๋ฑ๋กํด์ค์ผํ๋ค.
์๋ ์ฌ์ง ๊ฐ์ ๊ฒฝ์ฐ์๋ com.test.mybatis๋ ์ค์บ ์์ญ์ ํฌํจ๋์ด ์์ง๋ง, com.test.controller ํจ์งํค๋ ์ค์บ ์์ญ์ผ๋ก ์ค์ ์ ํด์ฃผ์ง ์์ MyBatisController.java ํ์ผ์ S ๋งํฌ๊ฐ ์๋ค.
์ค์บ ํด๋ ๊ด๋ฆฌ๋ servlet-context.xml์์ ๊ด๋ฆฌํ๋ค.
servlet-context.xml
<context:component-scan base-package="com.test.controller" />
Spring ์ ๋ฑ๋กํ ํจํค์ง์ ๊ฒฝ๋ก๋ฅผ ์ ๋ ฅํ๋ค.
๊ทธ๋ฌ๋ฉด ๋ฑ๋กํ ํจํค์ง ๋ด๋ถ์ @Controller ์ด๋ ธํ ์ด์ ์ ์ธ์ํ ์ ์๊ฒ๋๋ค.
๐ป์ ๊ธฐ์ ๊ด๊ณ
Controller, SqlSessionTemplate, SqlSessionFactoryBean, DataSource, ๊ทธ๋ฆฌ๊ณ HikariConfig ๋ ์ ๊ธฐ์ ์ผ๋ก ์ด์ด์ ธ์๋ค.
Controller๊ฐ ์์ฒญ์ ๋ฐ์์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํด DAOImpl, SqlSessionTemplate์ ์ฌ์ฉํ๋ค. SqlSessionTemplate์ SqlSessionFactoryBean์ ์ฌ์ฉํ์ฌ DataSource๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๊ณ , ์ด DataSource๋ HikariConfig๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋๋ค.
๊ฐ์์ ์ญํ
Controller
Controller๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ ์ ์ ํ ๋น์ฆ๋์ค ๋ก์ง์ ํธ์ถํ๋ ์ญํ ์ ๋ด๋นํ๋ค.
์ฃผ๋ก ์ฌ์ฉ์์ ์
๋ ฅ์ ๋ฐ์์ ๋น์ฆ๋์ค ๋ก์ง์ ์คํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ทฐ์ ์ ๋ฌํ์ฌ ํ๋ฉด์ ํ์ํ๋ค.
SqlSessionTemplate
SqlSessionTemplate์ MyBatis์ SqlSession์ ๊ตฌํํ ํด๋์ค๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ๋ด๋นํ๋ค.
SqlSession์ SQL ๋งคํ์ ์คํํ๋๋ฐ ์ฌ์ฉ๋๋ฉฐ, SqlSessionTemplate์ ์ด๋ฅผ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํด์ค๋ค.
SqlSessionFactoryBean
SqlSessionFactoryBean์ MyBatis์์ ์ฌ์ฉํ๋ SqlSessionFactory๋ฅผ ์์ฑํ๋๋ฐ ํ์ํ ์ค์ ์ ์ ๊ณตํ๋ค.
SqlSessionFactory๋ MyBatis์ ํต์ฌ์ด๋ฉฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ ๋ฐ SQL ๋ฌธ์ ์คํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
DataSource
DataSource๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ๋ง์ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์ด๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. SqlSessionFactoryBean์ ์ด DataSource๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๋ค.
HikariConfig
HikariConfig๋ HikariCP ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์
ํ์ ์ค์ ์ ๋ด๋นํ๋ ํด๋์ค์ด๋ค.
HikariCP๋ ๋์ ์ฑ๋ฅ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์
ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํจ๋ค. HikariConfig์์ ์ค์ ๋ ์ ๋ณด๋ DataSource๋ฅผ ์์ฑํ ๋ ์ฌ์ฉ๋๋ค.