2021. 1. 21. 23:57ใ๐ป ๊ฐ๋ฐ/Spring
MyBatis ํ๋ ์์ํฌ ํน์ง
- ๊ฐ๋จํ ์๋ฐ์ฝ๋๋ง์ผ๋ก DB ์ฐ๋์ ์ฒ๋ฆฌํ๋ค
- SQL ๋ช ๋ น์ด๋ฅผ ์๋ฐ ์ฝ๋์์ ๋ถ๋ฆฌํ์ฌ XML ํ์ผ์ ๋ฐ๋ก ๊ด๋ฆฌํ ์ ์๋ค
์์ ๋๊ฐ์ง ํน์ง์ด MyBatis์ ๊ฐ์ฅ ์ค์ํ ํน์ง์ด๋ฉฐ, ๊ธฐ์กด์ ์ฌ์ฉํ๋ JDBC ๊ธฐ๋ฐ์ DB์ฐ๋ ๋ฐฉ๋ฒ๋ณด๋ค ํจ์ฌ ๊ฐํธํ๋ค.
ํ๋ก์ ํธ ์์ฑ
Mybatis๋ฅผ ์ฌ์ฉํด ๊ฐ๋จํ SQL์ฟผ๋ฆฌ๋ฌธ์ ํ ์คํธํด๋ณด์.
๊ฐ๋ฐํ๊ฒฝ
DBMS: Oracle Database 11g Express Edition Release 11.2.0.2.0
WEB Server: apache-tomcat-8.5.61 8
Language: Java EE 8
Framework: Spring 5.2.12.Release
1. MyBatis๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
๋ค์์ pom.xml์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ถ๊ฐํ๊ธฐ์ํด ์์ฑํ ์ฝ๋์ด๋ค.
<!-- pom.xml -->
<properties>
<spring.version>5.2.12.RELEASE</spring.version>
</properties>
<!-- MyBatis ๋ผ์ด๋ธ๋ฌ๋ฆฌ -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.7.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.7.0</version>
</dependency>
- spring-orm : ์คํ๋ง๊ณผ Mybatis๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- mybatis : Mybatis๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- mybatis-spring : mybatis์ ์คํ๋ง์ ์ฐ๋์ํค๊ธฐ ์ํ ๋ชจ๋
- ojdbc8 : ์ค๋ผํด์ฌ์ฉ์ํด ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- commons-dbcp2 : ๋ฐ์ดํฐ์์ค ์ฌ์ฉํ๊ธฐ ์ํด ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (ํฐ์บฃ์์ connection pool์ ์ด์ฉํ ์ ์๋๋ก ์ํ์น์์ ์ ๊ณต)
2. SQL Mapper XMLํ์ผ ์์ฑ
<!-- MembersMapper.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="exam.spring.board.dao.MembersMapper">
<select id="getMember" resultType="exam.spring.board.dto.Member">
select id, name, password, email, join_date from members where id = #{id}
</select>
<insert id="addMember" parameterType="exam.spring.board.dto.Member">
insert into members (id, name, password, email, join_date) values(#{id}, #{name}, #{password}, #{email}, sysdate)
</insert>
</mapper>
์ด SQL Mapper XMLํ์ผ์ Mybatis์์ ๊ฐ์ฅ ์ค์ํ ํ์ผ์ด๋ค. XML ํ์ผ์์ DB์ฐ๋์ ํ์ํ SQL๋ช ๋ น์ด๋ค์ด ์ ์ฅ๋๋ค. SQL Mapper ํ์ผ์ <mapper>๋ฅผ ๋ฃจํธ ์๋ฆฌ๋จผํธ๋ก ์ฌ์ฉํ๊ณ <insert>, <update>, <delete>, <select> ์๋ฆฌ๋จผํธ๋ฅผ ์ด์ฉํด์ ํ์ํ sql๊ตฌ๋ฌธ์ ๋ฑ๋กํ๋ค.
์ฟผ๋ฆฌ๋ฌธ์ ๋ณด๋ฉด id ์์ฑ๊ฐ์ด ์๋๋ฐ ์ด ๊ฐ์ด ํด๋น ์ฟผ๋ฆฌ๋ฌธ์ ์ด๋ฆ์ด๋ค.
3. MyBatis ํ๊ฒฝ์ค์ ํ์ผ ์์ฑํ๊ธฐ
<!-- configuration.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
XML ๋ฌธ์์ ์ ํจ์ฑ ์ฒดํฌ๋ฅผ ์ํด ํ์ํ ์ฝ๋์ด๋ค.
4. SqlSession ๊ฐ์ฒด ์์ฑํ๊ธฐ
// MyBatisConfig.java
import java.io.IOException;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(
basePackages="exam.spring.board.dao",
sqlSessionFactoryRef="sqlSessionFactoryBean"
)
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource, ApplicationContext applicationContext) throws IOException {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/configuration.xml"));
factoryBean.setMapperLocations(applicationContext.getResources("classpath:mybatis/mappers/MembersMapper.xml"));
// mappers/**/*.xml -> mappers ์ดํ xml ํ์ฅ์๋ฅผ ๊ฐ๋ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๋ถ๋ฌ์ต๋๋ค
return factoryBean;
}
}
SqlSessionFactoryBean ๊ฐ์ฒด๊ฐ ์ค์ง์ ์ธ ๋งคํ์ ์ํํ๋ ๊ฐ์ฒด์ด๋ค.
=> ์ด ๋ถ๋ถ์ด ํต์ฌ์ฝ๋์ธ๋ฐ, SqlSessionFactoryBean๋ ์์ ๊ฐ์ด 3๊ฐ์ง ์ ๋ณด๋ฅผ ๋ฑ๋ก์ํจ๋ค.
- DataSource ์ ๋ณด (์ค์ ๊ด๋ จ๋ ํ์ผ์ config ํจํค์ง์ ๋ฐ๋ก ์์ฑํด์ฃผ์๋ค)
- MyBatis ์ค์ ์ ๋ณด
- Mapper ์ค์ ์ ๋ณด → ์ด๊ณณ์ SQL๋ฌธ์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ฒจ์ ธ ์๋ค
5. DataSource ์ ๋ณด ๋ฑ๋ก
๋ค์์ DB์ปค๋ฅ์ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋ DataSource์ด๋ค.
// ApplicationConfig.java
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
@Configuration
@ComponentScan(basePackages = {"exam.spring.board.dao","exam.spring.board.service"})
@Import({MyBatisConfig.class})
public class ApplicationConfig {
@Bean
public DataSource dataSource() {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(oracle.jdbc.driver.OracleDriver.class);
dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
dataSource.setUsername("master");
dataSource.setPassword("1004");
return dataSource;
}
}
Mybatis๋ ํน์ DBMS๋ก๋ถํฐ ์ปค๋ฅ์ ์ ํ๋ํ๊ณ DB์ฐ๋์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ฐ๋์ DataSource ์ ๋ณด๊ฐ ํ์ํ๋ค.
6. DAO & DTO ํด๋์ค ์์ฑ
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋์ ์ฒ๋ฆฌํ DTO์ DAOํด๋์ค๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค.
์์ Mapper ์ค์ ํ์ผ์์ ๋ฑ๋กํ ์ฟผ๋ฆฌ๋ฌธ์ id ์์ฑ๊ฐ์ ๋ฉ์๋๋ก ์ฌ์ฉํ๋ค.
// MemberMapper.java
package exam.spring.board.dao;
import org.apache.ibatis.annotations.Mapper;
import exam.spring.board.dto.Member;
@Mapper
public interface MembersMapper {
public Member getMember(String id);
public void addMember(Member member);
}
๋ค์์ ๋ฐ์ดํฐ ์ ์ก์ ์ฒ๋ฆฌํ DTO๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒ์ด๋ค.
XMLํ์ผ์ ์ ์ฅ๋ SQL ๋ช ๋ น์ด์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ๋ค์ ์ ๋ฌํ๊ณ ์คํ๊ฒฐ๊ณผ๋ฅผ ๋งคํํ๋ค.
// Member.java
public class Member {
private String id;
private String name;
private String password;
private String email;
private String joinDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
...
@Override
public String toString() {
return "Member [id=" + id + ", name=" + name + ", password=" + password + ", email=" + email + ", joinDate="
+ joinDate + "]";
}
}
7. ํ ์คํธ ํด๋ผ์ด์ธํธ ์์ฑ ๋ฐ ์คํ
๋ค์์ DAOํด๋์ค์ ๋ฉ์๋๋ฅผ ํ ์คํธํ๋ ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ์ด๋ค.
DAO ํ์ผ๊ณผ ๋์ผํ ํจํค์ง ๊ฒฝ๋ก๋ก ์ค์ ํด์ ํ ์คํธํด๋ณธ๋ค.
mybatis ์ฐ๊ฒฐ ํ ์คํธ๋ฅผ ์ํด jUnit์ ์ฌ์ฉํ์ผ๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ด junit ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ถ๋ฌ์์ผํ๋ค.
<!-- junit -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
- junit : junit์ ์๋ฐ์ฉ ๋จ์ ํ ์คํธ ์์ฑ์ ์ํ ์ฐ์ ํ์ค ํ๋ ์์ํฌ๋ค.
- spring-test : ์คํ๋ง์ Mybatis๊ฐ ์ ์์ ์ผ๋ก ์ฐ๋๋์๋์ง ํ์ธํ๋ ์ฉ๋
์ฟผ๋ฆฌ๋ฌธ์์ insert๊ตฌ๋ฌธ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด๋ณด์
// MembersMapperTest.java
package exam.spring.board.dao;
import org.junit.Assert;
...
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import exam.spring.board.config.ApplicationConfig;
import exam.spring.board.dto.Member;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ApplicationConfig.class})
public class MembersMapperTest {
@Autowired
MembersMapper membersMapper;
@Test
public void addMember() throws Exception{
Member testMember = new Member();
testMember.setId("test");
testMember.setName("ํ
์คํธ");
testMember.setPassword("test");
testMember.setEmail("test@test.com");
membersMapper.addMember(testMember);
Assert.assertNotNull(membersMapper.getMember("test"));
}
}
8. ์คํ๊ฒฐ๊ณผ
์ ์ฒด ์์ค์ฝ๋
https://github.com/jiyoung-dev/TIL/tree/master/Spring/MVCmodel
'๐ป ๊ฐ๋ฐ > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] ์คํ๋ง MVC๋ชจ๋ธ ์์ - Controller์ View์ฐ๊ฒฐ (0) | 2021.01.20 |
---|---|
[Spring] MVC ๋ชจ๋ธ ๊ฐ๋ ์ ๋ฆฌ (0) | 2021.01.20 |