๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

์Šคํ”„๋ง JDBC ํ”„๋กœ๊ทธ๋ž˜๋ฐ - MyBatis ์—ฐ๋™

by Leica 2020. 4. 28.
๋ฐ˜์‘ํ˜•

์Šคํ”„๋ง JDBC ํ”„๋กœ๊ทธ๋ž˜๋ฐ - MyBatis ์—ฐ๋™

์ด ๊ธ€์—์„œ๋Š” Oracle DB 11g๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

๋‹ค๋ฅธ DB๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

 

MyBatis

- Spring JDBC ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์‰ฝ๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

- Mapper์˜ ์—ญํ• ์„ ํ™•์žฅํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฌธ ์ž‘์„ฑ์„ ๋ชจ๋‘ Mapper์—์„œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•œ๋‹ค.


์˜์กด์„ฑ ์ถ”๊ฐ€

Spring JDBC, Oracle JDBC ๋“œ๋ผ์ด๋ฒ„, Apache Commons DBCP์™€ MyBatis ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

<!-- Spring JDBC -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>5.1.9.RELEASE</version>
</dependency>

<!-- Oracle JDBC Driver -->
<dependency>
	<groupId>com.oracle</groupId>
	<artifactId>ojdbc6</artifactId>
	<version>11.2.0.3</version>
</dependency>

<!-- Apache Commons DBCP -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-dbcp2</artifactId>
	<version>2.7.0</version>
</dependency>

<!-- MyBatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.2</version>
</dependency>

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>2.0.2</version>
</dependency>

MyBatis ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด 2๊ฐœ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. mybatis-spring์€ MyBatis์™€ Spring์„ ์—ฐ๋™ํ• ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

 

Oracle DB๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Oracle JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

<repository>
	<id>oracle</id>
	<name>ORACLE JDBC Repository</name>
	<url>http://code.lds.org/nexus/content/groups/main-repo</url>
</repository>

 

ํ…Œ์ด๋ธ” ๊ตฌ์กฐ

๋Œ€์ƒ ํ…Œ์ด๋ธ”์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

create table jdbc_table(
int_data number not null,
str_data varchar2(500) not null
);

 

Mapper ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜

public interface MapperInterface {

}

Mapper ์ธํ„ฐํŽ˜์ด์Šค๋Š” DAO ๋Œ€์‹  ์‚ฌ์šฉ๋˜๋ฉฐ ์—ฌ๊ธฐ์— MyBatis์˜ @Select, @Insert, @Update, @Delete ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ DB ์—ฐ๋™์— ํ•„์š”ํ•œ ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•  ๊ฒƒ์ด๋‹ค.

 

DataSource, SqlSessionFactory, Mapper ๋นˆ ์ •์˜

์Šคํ”„๋ง ๋นˆ ์„ค์ • ํด๋ž˜์Šค์—์„œ DataSource, SqlSessionFactory, Mapper ๋นˆ์„ ์ •์˜ํ•œ๋‹ค.

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperFactoryBean;

@Configuration
@ComponentScan
public class BeanConfigClass {
	
	// data source
	@Bean
	public BasicDataSource dataSource() {
		BasicDataSource source = new BasicDataSource();
		source.setDriverClassName("oracle.jdbc.OracleDriver");
		source.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
		source.setUsername("scott");
		source.setPassword("1234");
		
		return source;
	}
	
	// SqlSessionFactory
	@Bean
	public SqlSessionFactory factory(BasicDataSource source) throws Exception{
		SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
		factoryBean.setDataSource(source);
		SqlSessionFactory factory = factoryBean.getObject();
		
		return factory;
	}
	
	// Mapper
	@Bean
	public MapperFactoryBean<MapperInterface> test_mapper(SqlSessionFactory factory) throws Exception{
		MapperFactoryBean<MapperInterface> factoryBean = new MapperFactoryBean<MapperInterface>(MapperInterface.class);
		factoryBean.setSqlSessionFactory(factory);
		
		return factoryBean;
	}
}

SqlSessionFactory ๋นˆ์€ ๋ฉ”์†Œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ BasicDataSource๋ฅผ ์ฃผ์ž…๋ฐ›๊ณ  MapperFactoryBean์€ SqlSessionFactory๋ฅผ ์ฃผ์ž…๋ฐ›๋Š”๋‹ค.

MapperFactoryBean์˜ ์ œ๋„ค๋ฆญ ํƒ€์ž…์œผ๋กœ ์ด์ „์— ์ •์˜ํ•œ Mapper ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง€์ •ํ•œ๋‹ค.

๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ๋ฒ•์€ ์œ„ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค.

 

VO ํด๋ž˜์Šค

@Component
@Scope("prototype")
public class JdbcBean {
	
	private int int_data;
	private String str_data;
	
	public int getInt_data() {
		return int_data;
	}
	public void setInt_data(int int_data) {
		this.int_data = int_data;
	}
	public String getStr_data() {
		return str_data;
	}
	public void setStr_data(String str_data) {
		this.str_data = str_data;
	}
}

ํ…Œ์ด๋ธ” ๊ตฌ์กฐ์™€ ๋™์ผํ•œ VO ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

Component๋ฅผ ๋ถ™์—ฌ VOํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  scope๋Š” prototype์œผ๋กœ ํ•œ๋‹ค.

์ปฌ๋Ÿผ๊ณผ ๋งคํ•‘๋˜๋Š” ํ•„๋“œ๋ฅผ ์„ ์–ธํ• ๋•Œ ์ปฌ๋Ÿผ๋ช…๊ณผ ํ•„๋“œ๋ช…์„ ๋™์ผํ•˜๊ฒŒ ํ•˜๋Š”๊ฒŒ ์„ค์ •์ด ์ค„์–ด ์ฝ”๋”ฉํ•˜๊ธฐ ํŽธํ•˜๋‹ค.

 

Insert, Select, Update, Delete ๊ตฌํ˜„

MyBatis๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ๋ฌธ์„ Mapper ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜ํ•œ๋‹ค.

 

1) Insert

import org.apache.ibatis.annotations.Insert;

public interface MapperInterface {

	@Insert("insert into jdbc_table (int_data, str_data) values (#{int_data}, #{str_data})")
	void insert_data(JdbcBean bean);
}

MyBatis์˜ @Insert ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ insert๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

#{}์— ํ”„๋กœํผํ‹ฐ๋ช…์„ ์จ์„œ ๊ฐ’์„ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

public static void main(String[] args) {

	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
	
	MapperInterface mapper = ctx.getBean("test_mapper", MapperInterface.class);
	
	// insert
	JdbcBean bean2 = new JdbcBean();
	bean2.setInt_data(100);
	bean2.setStr_data("๋ฌธ์ž์—ด100");
	mapper.insert_data(bean2);

	JdbcBean bean3 = new JdbcBean();
	bean3.setInt_data(200);
	bean3.setStr_data("๋ฌธ์ž์—ด200");
	mapper.insert_data(bean3);
	
	ctx.close();
}	

์‚ฌ์šฉ ์‹œ์—๋Š” ์ •์˜ํ•œ Mapper ๋นˆ์„ Mapper ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ ๋ฐ›์•„์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค.

 

2) Select

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;

public interface MapperInterface {

	@Insert("insert into jdbc_table (int_data, str_data) values (#{int_data}, #{str_data})")
	void insert_data(JdbcBean bean);
    
	/*
	@Results({
		@Result(column = "int_data", property = "int_data"),
		@Result(column = "str_data", property = "str_data")
	})
	*/
	@Select("select int_data, str_data from jdbc_table")
	List<JdbcBean> select_data();
}

MyBatis์˜ @Select ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ select๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

์ปฌ๋Ÿผ๋ช…๊ณผ ํ”„๋กœํผํ‹ฐ๋ช…์ด ๋‹ค๋ฅด๋‹ค๋ฉด ์ฃผ์„์ฒ˜๋ฆฌํ•œ ์ฝ”๋“œ์™€ ๊ฐ™์ด @Results, @Result๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ฐ™์œผ๋ฉด ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

 

public static void main(String[] args) {

	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
	
	MapperInterface mapper = ctx.getBean("test_mapper", MapperInterface.class);
    
	// insert
	JdbcBean bean2 = new JdbcBean();
	bean2.setInt_data(100);
	bean2.setStr_data("๋ฌธ์ž์—ด100");
	mapper.insert_data(bean2);

	JdbcBean bean3 = new JdbcBean();
	bean3.setInt_data(200);
	bean3.setStr_data("๋ฌธ์ž์—ด200");
	mapper.insert_data(bean3);    
	
	// select
	List<JdbcBean> list1 = mapper.select_data();
	for(JdbcBean bean1 : list1) {
		System.out.printf("int_data : %d\n", bean1.getInt_data());
		System.out.printf("str_data : %s\n", bean1.getStr_data());
		System.out.println("--------------------------------------");
	}
	
	ctx.close();
}	

 

3) Update

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Update;

public interface MapperInterface {

	@Insert("insert into jdbc_table (int_data, str_data) values (#{int_data}, #{str_data})")
	void insert_data(JdbcBean bean);
    
	/*
	@Results({
		@Result(column = "int_data", property = "int_data"),
		@Result(column = "str_data", property = "str_data")
	})
	*/
	@Select("select int_data, str_data from jdbc_table")
	List<JdbcBean> select_data();
    
	@Update("update jdbc_table set str_data = #{str_data} where int_data = #{int_data}")
	void update_data(JdbcBean bean);    
}

MyBatis์˜ @Update ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ update๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

 

public static void main(String[] args) {

	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
	
	MapperInterface mapper = ctx.getBean("test_mapper", MapperInterface.class);
    
	// insert
	JdbcBean bean2 = new JdbcBean();
	bean2.setInt_data(100);
	bean2.setStr_data("๋ฌธ์ž์—ด100");
	mapper.insert_data(bean2);

	JdbcBean bean3 = new JdbcBean();
	bean3.setInt_data(200);
	bean3.setStr_data("๋ฌธ์ž์—ด200");
	mapper.insert_data(bean3);    
	
	// select
	List<JdbcBean> list1 = mapper.select_data();
	for(JdbcBean bean1 : list1) {
		System.out.printf("int_data : %d\n", bean1.getInt_data());
		System.out.printf("str_data : %s\n", bean1.getStr_data());
		System.out.println("--------------------------------------");
	}
    
	// update
	JdbcBean bean4 = new JdbcBean();
	bean4.setInt_data(100);
	bean4.setStr_data("๋ฌธ์ž์—ด300");
	mapper.update_data(bean4);    
	
	ctx.close();
}	

 

4) Delete

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.Delete;

public interface MapperInterface {

	@Insert("insert into jdbc_table (int_data, str_data) values (#{int_data}, #{str_data})")
	void insert_data(JdbcBean bean);
    
	/*
	@Results({
		@Result(column = "int_data", property = "int_data"),
		@Result(column = "str_data", property = "str_data")
	})
	*/
	@Select("select int_data, str_data from jdbc_table")
	List<JdbcBean> select_data();
    
	@Update("update jdbc_table set str_data = #{str_data} where int_data = #{int_data}")
	void update_data(JdbcBean bean);    

	@Delete("delete from jdbc_table where int_data = #{abc}")
	void delete_data(int int_data);
}

MyBatis์˜ @Delete ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ delete๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋‹ฌ๋ฆฌ ํ•œ ๊ฐœ์˜ ๊ธฐ๋ณธ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” #{}์— ์•„๋ฌด ์ด๋ฆ„์ด๋‚˜ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„ delete ์ถ”์ƒ ๋ฉ”์†Œ๋“œ์—์„œ๋„ int ํƒ€์ž…์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ int_data๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ฐ›์ง€๋งŒ #{abc}๋กœ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ์žˆ๋‹ค.

 

public static void main(String[] args) {

	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
	
	MapperInterface mapper = ctx.getBean("test_mapper", MapperInterface.class);
    
	// insert
	JdbcBean bean2 = new JdbcBean();
	bean2.setInt_data(100);
	bean2.setStr_data("๋ฌธ์ž์—ด100");
	mapper.insert_data(bean2);

	JdbcBean bean3 = new JdbcBean();
	bean3.setInt_data(200);
	bean3.setStr_data("๋ฌธ์ž์—ด200");
	mapper.insert_data(bean3);    
	
	// select
	List<JdbcBean> list1 = mapper.select_data();
	for(JdbcBean bean1 : list1) {
		System.out.printf("int_data : %d\n", bean1.getInt_data());
		System.out.printf("str_data : %s\n", bean1.getStr_data());
		System.out.println("--------------------------------------");
	}
    
	// update
	JdbcBean bean4 = new JdbcBean();
	bean4.setInt_data(100);
	bean4.setStr_data("๋ฌธ์ž์—ด300");
	mapper.update_data(bean4); 
    
	// delete
	mapper.delete_data(100);    
	
	ctx.close();
}	

 

๊ด€๋ จ ๊ธ€

- ์Šคํ”„๋ง JDBC ํ”„๋กœ๊ทธ๋ž˜๋ฐ - JdbcTemplate

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€