์คํ๋ง 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
๋๊ธ