Spring

[Spring] MyBatis ์™€ Spring ์—ฐ๋™ํ•˜๊ธฐ(2) : DBCP ์‚ฌ์šฉํ•˜๊ธฐ

developer of the night sky 2023. 11. 27. 21:29

๐Ÿ”ป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 ํŒŒ์ผ์„ ์ฐพ๋Š”๋‹ค.

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๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.