๐ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์์ ๊ดํ ํ๊ฒฝ ์ค์ ์ ๋ณด๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ก, MyBatis ํ๊ฒฝ ์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉํ๋ค.
Environment environment = new Environment(*ํ๊ฒฝ ์ ๋ณด ์ด๋ฆ*
, *ํธ๋์ญ์
๋งค๋์ ์ข
๋ฅ*
, *์ปค๋ฅ์
ํ ์ฌ์ฉ ์ฌ๋ถ*);
Environment environment = new Environment("dev"
, new JdbcTransactionFactory()
, new PooledDataSource(DRIVER, URL, USER, PASSWORD));
๐ก ํ๊ฒฝ ์ค์ ์ ๋ณด Environment ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ฑํ MyBatis ์ค์ ๊ฐ์ฒด๋ก, DB ์ ์ ๊ด๋ จ ์ ๋ณด, mapper ๋ฑ๋ก, ๋ณ์นญ ๋ฑ๋ก ๋ฑ myBatis ์ ์ญ ์ค์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ค.
Configuration configuration = new Configuration(environment);
configuration.addMapper(Mapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
SqlSessionFactory
SqlSessionFactoryBuilder
SqlSessionFactory ์ธํฐํ์ด์ค ํ์ ์ ํ์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ ๋น๋ ์ญํ ์ ์ํํ๋ค.
build() ๋ฉ์๋๋ ์ค์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ Configuration ํ์ ์ ๊ฐ์ฒด ํน์ ์ธ๋ถ ์ค์ ํ์ผ๊ณผ ์ฐ๊ฒฐ๋ ์คํธ๋ฆผ์ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ๋ฉด SqlSessionFactory ์ธํฐํ์ด์ค ํ์ ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
SqlSessionFactoryBuilder ๋ฉ์๋
| method ๊ตฌ๋ถ | ์ค๋ช |
|---|---|
| build(InputStream) | config.xml ํ์ผ๋ง ๋ถ๋ฌ์ด |
| build(InputStream, String) | config.xml ํ์ผ๊ณผ ์ง์ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ถ๋ฌ์ด |
| build(InputStream, Properties) | config.xmlํ์ผ๊ณผ property ๋ก ์ค์ ํ ๋ด์ฉ์ผ๋ก ๋ถ๋ฌ์ด(โ${key}โ) |
| build(InputStream, String, Properties) | config.xml ํ์ผ๊ณผ ์ง์ ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค, properties ํ์ผ ๋ถ๋ฌ์ด |
| build(configuration) | configuration ๊ฐ์ฒด์ ์ค์ ํ ๋ด์ฉ์ ๋ถ๋ฌ์ด |
SqlSession sqlSession = sqlSessionFactory.openSession(false);
SqlSessionFactory์ openSession() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ SqlSession ์ธํฐํ์ด์ค ํ์ ์ ๊ฐ์ฒด๋ฅผ ๋ฐํ๋ฐ๋๋ค.
SqlSession์ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก(= Thread-safe ํ์ง ์์), ์ค๋ ๋๋ง๋ค ์์ฑํ์ฌ ๊ณต์ ๋์ง ์๋๋ก ํด์ผ ํ๋ค.
openSession() ๋ฉ์๋
boolean ํ์ ์ ์ธ์๋ก ์ ๋ฌํ๋๋ฐ, ์ด๋ Connection ์ธํฐํ์ด์ค ํ์ ๊ฐ์ฒด๋ก DML ์ํ ํ auto commit ์ฌ๋ถ์ ๋ํ ์ต์ ์ ์๋ฏธํ๋ค.
auto commit ์ต์ ์ false๋ก ์ง์ ํ์ฌ ํธ๋์ญ์ ์ ์ง์ ๊ด๋ฆฌํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
Mybatis SqlSessionFactory๋ฅผ ํตํด Session์ ์์ฑํ๋ openSession() ๋ฉ์๋๋ ์ฌ๋ฌ๊ฐ์ง ํ์์ผ๋ก ์ค๋ฒ๋ก๋ฉ ๋์ด์๋๋ฐ, ๊ทธ์ค ๋ํ์ ์ธ ๊ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
| method ๊ตฌ๋ถ | ์ค๋ช |
|---|---|
| openSession() | ๊ธฐ๋ณธ๊ฐ์ ํตํด SqlSession ์์ฑ |
| openSession(Boolean) | - SqlSession ์์ฑ ์ AutoCommit ์ฌ๋ถ ์ง์ - ๊ธฐ๋ณธ๊ฐ = true |
| openSession(Connection) | - ์ง์ ์์ฑํ Connection ๊ฐ์ฒด๋ฅผ ์ด์ฉํด SqlSession ์์ฑ - ๊ธฐ๋ณธ๊ฐ = X |
| openSession(ExecutorType) | - ์ฟผ๋ฆฌ ์คํ ์ PreparedStatement์ ์ฌ์ฌ์ฉ์ฌ๋ถ ์ค์ - ๊ธฐ๋ณธ๊ฐ = ExecutorType.SIMPLE |
SqlSession์ ์ฌ์ฉ ํ ๋ฐ๋์ close()ํ์ฌ ๋ฐ๋ฉํด์ผ ํ๋ค.
sqlSession.close();
mapper.xml์์ ์ ์ธํ ์ฟผ๋ฆฌ ๊ตฌ๋ฌธ์ SqlSession์์ ์คํํ๋ ๋ฉ์๋๋ ์ด 6๊ฐ์ง๋ก ์๋์ ๊ฐ๋ค.
| method๋ช | ์ค๋ช |
|---|---|
| Object selectOne(String mapper, Object param) | ํ๋์ ๊ฐ์ฒด๋ง์ ๋ฐ์ ๋ ์ฌ์ฉ |
| List<E> selectList(String mapper, Object param) | ๊ฒฐ๊ณผ์ ๋ํ ๊ฐ์ List๋ก ๋ฐ์ ๋ ์ฌ์ฉ |
| Map<K,V> selectMap(String mapper, Object param, String mapKey) | ๊ฒฐ๊ณผ์ ๋ํ ๊ฐ์ Map์ผ๋ก ๋ฐ์ ๋ ์ฌ์ฉ (๋ง์ง๋ง ์ธ์๋ก key๋ก ์ฌ์ฉ๋ ์ปฌ๋ผ ๋ช ์) |
| int insert(String mapper, Object param) | Database์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํ ๋ ์ฌ์ฉ |
| int update(String mapper, Object param) | Database์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ๋ ์ฌ์ฉ |
| int delete(String mapper, Object param) | Database์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ ๋ ์ฌ์ฉ |
(์ฐธ๊ณ ) https://mybatis.org/mybatis-3/getting-started.html
์ค์ ์ ๋ณด๋ฅผ ์์ฑํ๊ธฐ ์ํ mybatis-config.xml ํ์ผ์ ๋ฑ๋กํ๋ค.
xml ํ์ผ ์ต์๋จ์ ๋ค์๊ณผ ๊ฐ์ด xml ํ์์ ์ง์ ํ์ฌ ์ดํ์ ์ค์ ๋ด์ฉ์ด mybatis ์ค์ ์์ ์ ์ธํ๋ค.
<?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">
์ค์ ๋ด์ฉ ์๋ ์ต์์ ํ๊ทธ์ธ <configuration>์ ์์ฑํ๊ณ ๋ด๋ถ์ ํ์ํ ์ค์ ์ ์ ๋ณด๋ฅผ ์์ฑํ๋ค.
<?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">
<configuration>
. . .
</configuration>
์ค์ ํ์ผ์์ ๊ณตํต์ ์ธ ์์ฑ์ ์ ์ํ๊ฑฐ๋ ์ธ๋ถ ํ์ผ์์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ํ๊ทธ์ด๋ค.
์ธ๋ถ ํ๋กํผํฐ ํ์ผ์ resource ํ์์ ๊ฒฝ๋ก๋ฅผ ๊ธฐ์ ํ๋ฉด ๋๋ค.
<properties> ํ๊ทธ ์์ชฝ์ <property> ํ๊ทธ๋ฅผ ์์ฑํ์ฌ properties ํ์ผ์ ๊ฐ์ ์ค์ ํ ์ ์๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ
<properties resource = โ*๊ฒฝ๋ก+ํ์ผ๋ช
.properties*โ>
<property name=โ*key๋ช
*โ value=โ*์ค์ ๊ฐ*โ>
</properties>
SqlSessionFactory ๊ฐ์ฒด๊ฐ SqlSession ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋, ์์ฑํ ๊ฐ์ฒด์ ํน์ฑ์ ์ค์ ํ๋ค.
settings ์๋ฆฌ๋จผํธ์ ํ์ ์๋ฆฌ๋จผํธ๋ค์ ๋๋ถ๋ถ ๋ํดํธ๊ฐ์ ๊ฐ์ง๋ฉฐ, ํน๋ณํ ๊ฒฝ์ฐ๊ฐ ์๋๋ฉด ๋ํดํธ๊ฐ์ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ๋ค.
์ฌ์ฉ ์์
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<setting>ํ๊ทธ์ ํ์ ์๋ฆฌ๋จผํธ๋ ๋ค์ 11๊ฐ์ง์ด๋ค.
| ์๋ฆฌ๋จผํธ ํ๊ทธ | ์ค๋ช |
|---|---|
| <cacheEnabled> | ์บ์ ์ฌ์ฉ ์ฌ๋ถ ์ค์ (๊ธฐ๋ณธ๊ฐ: true) |
| <lazyLodingEnabled> | ๋ฐ์ดํฐ๋ฅผ ํ์ ์์ ์ ๊ฐ์ ธ์ ๋์ํ๊ฒ ํ๋ ์ต์ (์ฑ๋ฅ๊ฐ์ / ๊ธฐ๋ณธ๊ฐ: true) |
| <aggressiveLazyLoding> | ๋ฆ์ ๋ก๋ฉ ํ์ฑํ/๋นํ์ฑํ ์ต์ (๊ธฐ๋ณธ๊ฐ: true) |
| <multipleResultSetEnabled> | ํ ๊ฐ์ ๊ตฌ๋ฌธ์์ ์ฌ๋ฌ ๊ฐ์ ๊ฒฐ๊ณผ ์ ์ ๋ํ ํ์ฉ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ์ต์ (๋ฏธ์ง์ ๋๋ผ์ด๋ฒ๋ ์์ / ๊ธฐ๋ณธ๊ฐ: true) |
| <useColumnLabel> | ์ปฌ๋ผ ์ด๋ฆ ๋์ ์ปฌ๋ผ ๋ผ๋ฒจ ์ฌ์ฉ ์ฌ๋ถ ์ค์ (๋๋ผ์ด๋ฒ๋ง๋ค ๊ธฐ๋ณธ๊ฐ ๋ค๋ฆ / ๊ธฐ๋ณธ๊ฐ: true) |
| <useGeneratedKeys> | ์์ฑํค ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ (๊ธฐ๋ณธ๊ฐ: false) |
| <autoMappingBehavior> | ์กฐํ ๊ฒฐ๊ณผ ์๋ ๋งคํ ์ค์ (๊ธฐ๋ณธ๊ฐ: PARTIAL) โป mapper ํ๊ทธ์ ๋์ผํ ์ค์ ์ด์ง๋ง, ์ฌ๊ธฐ์๋ ์ ์ญ ์ค์ ์ ํจ |
| <defaultExecutorType> | - Statement๋ฅผ ์ฌ์ฌ์ฉํ์ง ์๋ ์ค์ ์ธ SIMPLE (= ๊ธฐ๋ณธ๊ฐ) - PreparedStatement ์ฌ์ฌ์ฉ์ REUSE - ์ผ๊ด์ฒ๋ฆฌ ํ๋ BATCH |
| <defaultStatementTimeout> | ํ์์์์ ๋ํ ์์์ ์ด ๋จ์ ์ ์ญ ์ค์ (๊ธฐ๋ณธ๊ฐ: JDBC ๋๋ผ์ด๋ฒ ์์ฒด ์ค์ ๊ฐ) |
| <mapUnderscoreToCamelCase> | DB์ ์ธ๋๋ฐ๋ฅผ ์ด์ฉํ ๋ค์ด๋ฐ ๊ท์น๊ณผ ์๋ฐ์ ๋ํ๋ด ํํ์์ ์ฌ์ฉํด ์๋ ๋งคํํ ์ง์ ๋ํ ์ต์ (๊ธฐ๋ณธ๊ฐ: false) |
| <localCacheScope> | - ์บ์ ์ ์ฅ ๋ฒ์๋ฅผ SqlSession์ผ๋ก ํ ๋ SESSION (= ๊ธฐ๋ณธ๊ฐ) - ๊ตฌ๋ฌธ๋ณ๋ก ์บ์ํ ๋๋ STATEMENT๋ฅผ ์ ํ |
MyBatis์์ ์ฌ์ฉํ ์๋ฃํ์ ๋ณ์นญ์ ์ ์ธํ๋ค.
๋งคํผ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ๋ ResultType์ด๋ parameter ์์ฑ์ ํํด๋์ค๋ช ์ผ๋ก ์ฌ์ฉํด์ผ ํ๋ ํด๋์ค์ ๋ณ์นญ์ ๋ฑ๋กํ์ฌ ๊ฐ๋ตํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์ฌ์ฉ ์์
<typeAliases>
<typeAlias type="member.model.vo.Member" alias="Member" />
</typeAliases>
Mybatis ๋ด์ฅ ๋ณ์นญ ์ฐธ๊ณ (for parameterType / resultType)

MyBatis์์ ์ฐ๋ํ Database ์ ๋ณด๋ฅผ ๋ฑ๋กํ๋ค.
<environments>ํ๊ทธ๋ ์ฌ๋ฌ ๊ฐ์ <environment>ํ๊ทธ๋ฅผ ํฌํจํ ์ ์์ผ๋ฉฐ, default ์์ฑ์ผ๋ก ๊ธฐ๋ณธ ์ฌ์ฉํ ํ๊ฒฝ ์ค์ ์ ์ง์ ํ ์ ์๋ค.
<environment>ํ๊ทธ ๋ด๋ถ์์ ์ฌ์ฉํ๋ ํ๊ทธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<transactionManager> : ํธ๋์ญ์ ๋งค๋์ ๋ฅผ JDBC ํน์ MANAGED๋ก ์ค์ ํ ์ ์๋ค.
<dataSource> : ์์ฑ์ผ๋ก ์ปค๋ฅ์ ํ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ POOLED์ UNPOOLED๋ก ์ค์ ํ ์ ์๋ค.
์ค์ ๊ฐ๋ฅํ type ์ค JNDI๋ ์๋๋ฐ, ์ด๋ MyBatis์์ Connection ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๊ด๋ฆฌํ์ง ์๊ณ Web Application์ ์ค์ ์ ๋ฐ๋ฅด๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค.
(์ฐธ๊ณ ) POOLED ์ UNPOOLED
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๋ DataSource์ ํ์ ์ ํฌ๊ฒ POOLED์ UNPOOLED๋ก ๋๋ ์ ์๋๋ฐ, ๊ทธ ์ฐจ์ด๋ ๋ค์๊ณผ ๊ฐ๋ค.
| ๊ตฌ๋ถ | POOLED | UNPOOLED |
|---|---|---|
| ํน์ง | ์ต์ด Connection ๊ฐ์ฒด ์์ฑ ์ ํด๋น ์ ๋ณด๋ฅผ pool ์์ญ์ ์ ์ฅํด ๋๊ณ ์ดํ Connection ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ด๋ฅผ ์ฌ์ฌ์ฉํ๋ค. | Connection ๊ฐ์ฒด๋ฅผ ๋ณ๋๋ก ์ ์ฅํ์ง ์๊ณ , ํธ์ถ ์๋ง๋ค ๋งค๋ฒ ์์ฑํ์ฌ ์ฌ์ฉํ๋ค. |
| ์ฅ์ | - Connection ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ์ ๊ตฌ์ถํ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด ๋จ์ถ๋๋ค. | - Connection ์ฐ๊ฒฐ์ด ๋ง์ง ์์ ์ฝ๋๋ฅผ ์์ฑํ ๋ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค. |
| ๋จ์ | - ๋จ์ํ ๋ก์ง์ ์ํํ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ์๋ ์ค์ ํด์ผ ํ ์ ๋ณด๊ฐ ๋ง๋ค. | - ๋งค๋ฒ ์๋ก์ด Connection ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฏ๋ก ์๋๊ฐ ์๋์ ์ผ๋ก ๋๋ฆฌ๋ค. |
<property> : <dataSource>ํ๊ทธ ๋ด๋ถ์ ์์ฑ๋๋ฉฐ, <properties>ํ๊ทธ๋ฅผ ํตํด ๋ถ๋ฌ์จ ํ์ผ์ ๊ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ณด๋ฅผ ์ค์ ํ๋ค.
<dataSource>
<property name=โ*๋ช
์นญ*โ value=โ${*properties์ ์ค์ ๋ key๋ช
*}โ />
<property name=โ*๋ช
์นญ*โ value=โ${*properties์ ์ค์ ๋ key๋ช
*}โ />
</dataSource>์ฌ์ฉ ์์
<properties>ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/menu" />
<property name="username" value="sahmyook" />
<property name="password" value="sahmyook" />
</dataSource>
</environment>
</environments>
<properties>ํ๊ทธ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ
<properties resource="config/connection-info.properties"/>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
์ฌ์ฉํ๊ณ ์ ํ๋ ์ฟผ๋ฆฌ๊ฐ ์ ์๋ mapper ํ์ผ์ ๋ฑ๋กํ๋ค.
์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋ค ๊ฐ์ง๊ฐ ์์ง๋ง ํ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ํต์ผํ์ฌ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค.
<mapper resource=""> : (์๋๊ฒฝ๋ก) ํด๋์คํจ์ค์ ์์นํ xml ๋งคํผ ํ์ผ ์ง์ <mapper url=""> : (์ ๋๊ฒฝ๋ก) URL์ ์ฌ์ฉํ xml ๋งคํผ ํ์ผ ์ง์ <mapper class=""> : ๋งคํผ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ์ธํฐํ์ด์ค ์์น ์ง์ <package name=""> : ํจํค์ง ์ง์ ์ผ๋ก ํจํค์ง ๋ด ์๋์ผ๋ก ๋งคํผ ๊ฒ์์ฌ์ฉ ์์
<mappers>
<mapper resource="member/model/mapper/member-mapper.xml"/>
<mapper resource="notice/model/mapper/notice-mapper.xml" />
<mapper resource="board/model/mapper/board-mapper.xml" />
</mappers>
Mapper mapper = sqlSession.getMapper(Mapper.class);
java.util.Date date = mapper.selectSysdate();
@Results
@Results(id="menuResultMap", value = {
@Result(id = true, property = "code", column = "MENU_CODE"),
@Result(property = "name", column = "MENU_NAME"),
@Result(property = "price", column = "MENU_PRICE"),
@Result(property = "categoryCode", column = "CATEGORY_CODE"),
@Result(property = "orderableStatus", column = "ORDERABLE_STATUS"),
})
@Select
์กฐํ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ฉฐ, @Results๋ฅผ ๋ฐ๋ก ์์ ์์ฑํด ๋ฐํ ํ์ ์ ์ง์ ํ๊ฑฐ๋ @ResultMap ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํด ์ฌ์ฌ์ฉํ๋๋ก ์ง์ ํ๋ค.
์ฌ์ฉ ์์
@Select("SELECT \n" +
" MENU_CODE\n" +
" , MENU_NAME\n" +
" , MENU_PRICE\n" +
" , CATEGORY_CODE\n" +
" , ORDERABLE_STATUS\n" +
" FROM TBL_MENU\n" +
" WHERE ORDERABLE_STATUS = 'Y'\n" +
" AND MENU_CODE = #{ code }")
@ResultMap("menuResultMap")
MenuDTO selectMenuByCode(int code);
@Insert, @Update, @Delete
๊ฐ๊ฐ ์ฝ์ , ์์ , ์ญ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ฉฐ ๋ฐํ ํ์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ์ด ์ํ๋ ๋ก์ฐ ๊ฐฏ์๋ฅผ ๋ด์ ์ ์ํ์ด๋ค.
@Insert ์ฌ์ฉ ์์
@Insert("INSERT\n" +
" INTO TBL_MENU\n" +
"(\n" +
" MENU_NAME\n" +
", MENU_PRICE\n" +
", CATEGORY_CODE\n" +
", ORDERABLE_STATUS\n" +
")\n" +
"VALUES\n" +
"(\n" +
" #{ name }\n" +
", #{ price }\n" +
", #{ categoryCode }\n" +
", 'Y'\n" +
")")
int insertMenu(MenuDTO menu);
@Update ์ฌ์ฉ ์์
@Update("UPDATE\n" +
" TBL_MENU\n" +
" SET MENU_NAME = #{ name }\n" +
" , MENU_PRICE = #{ price }\n" +
" , CATEGORY_CODE = #{ categoryCode }\n" +
" WHERE MENU_CODE = #{ code }")
int updateMenu(MenuDTO menu);
@Delete ์ฌ์ฉ ์์
@Delete("DELETE\n" +
" FROM TBL_MENU\n" +
" WHERE MENU_CODE = #{ code }")
int deleteMenu(int code);
๐ก mapper.xml์๋ ์ฌ์ฉํ๊ณ ์ ํ๋ ์ฟผ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ก ๋ฐ์ ๊ฐ์ฒด(= resultMap)๋ฅผ ์ ์ธํ ์ ์๋ค.
xml ํ์ผ ์ต์๋จ์ ๋ค์๊ณผ ๊ฐ์ด xml ํ์์ ์ง์ ํ์ฌ ์ดํ์ ์ค์ ๋ด์ฉ์ด MyBatis Mapper ์ค์ ์์ ์ ์ธํ๋ค.
<?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 ์์ฑ์ ๊ธฐ์ ํ๋ค.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-[//mybatis.org//DTD](https://mybatis.org//DTD) Mapper 3.0//EN" "[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="Member">
. . .
</mapper>
์ดํ ์์ฑ์ด ํ์ํ CRUD ๋ฐ resultMap ์ค์ ๋ฑ์ ํ๊ทธ๋ฅผ <mapper> ํ๊ทธ ์๋๋ก ์์ฑํ๋ค.
DB์์ ์กฐํํ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ ์ํ๋ ๊ฐ์ฒด์ ํ๋์ ๋ด์ ๋ฐํํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ๋ค.
ํด๋น ํ๊ทธ์ id ์์ฑ์ ํด๋น resultMap์ ๊ตฌ๋ถํ๋ ๋ช ์นญ์ด๊ณ , type ์์ฑ์ ๋์ ๊ฐ์ฒด์ ํ๋๋ฅผ ๊ฐ์ง ํด๋์ค์ ํํด๋์ค๋ช ์ ์์ฑํ๋ค. (๋จ, MyBatis ์ค์ ์ ๋ณ์นญ(typeAlias)์ ์ง์ ํ์ผ๋ฉด ๋ณ์นญ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.)
<resultMap>ํ๊ทธ์ ์์ฑ์ ๋ค์ ํ์ ๊ฐ๋ค.
| ์์ฑ๋ช | ์ค๋ช |
|---|---|
| id | ๋งคํ ๊ตฌ๋ฌธ์์ ๊ฒฐ๊ณผ ๋งคํ์ ์ฌ์ฉํ ๋ ๊ตฌ๋ถํ๊ธฐ ์ํ ID |
| type | ๊ฒฐ๊ณผ ๋งคํ์ ์ ์ฉํ๋ ๋์ ๊ฐ์ฒด ํ์ (= ๋งคํ ๊ตฌ๋ฌธ์ ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ Java ํ์ ์ง์ ) |
| extends | ๊ธฐ์กด์ ์ ์๋ ๋งคํ ๊ฒฐ๊ณผ๋ฅผ ์์๋ฐ์ ์ถ๊ฐ์ ์ธ ๋งคํ ์ ๋ณด๋ก ํ์ฅํ ๋ ์ฌ์ฉ |
| autoMapping | - ๊ฒฐ๊ณผ ๋งคํ์ ์๋ ๋งคํ์ ํ ๊ฒ์ธ์ง๋ฅผ ๊ฒฐ์ (๊ธฐ๋ณธ๊ฐ: PARTIAL) - NONE, PARTIAL, FULL์ ์ธ ๊ฐ์ง ์ต์ ์ค์ ๊ฐ๋ฅ - auto ๋งคํ ์ค์ ์ ๋์ผํ ์ปฌ๋ผ๋ช ์ด ์์ผ๋ฉด ์ํ์ฑ์ ๊ฐ์ง๋ฏ๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์์ ํจ |
<resultMap> ํ๊ทธ์ ํ์ ์๋ฆฌ๋จผํธ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
resultMap์ type ์์ฑ์ ์ค์ ๋ก ๊ตฌํํด ๋์ ์๋ฐ POJO ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
์ฌ์ฉ ์์
<resultMap id="resultMember" type="Member">
<id property="userId" column="USER_ID" />
<result property="password" column="PASSWORD" />
<result property="userName" column="USER_NAME" />
. . .
</resultMap>
SQL ์กฐํ ๊ตฌ๋ฌธ์ ์์ฑํ ๋ ์ฐ์ธ๋ค.
์ฟผ๋ฆฌid์ ๋ฐํํ ํ์ ์ ์ค์ ํ๊ณ ํ๊ทธ ๋ด๋ถ์ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ๋ค.
โป ํ๊ทธ ๋ด๋ถ์ ์์ฑํ ์ฟผ๋ฆฌ๋ฌธ ๋์๋ ์ธ๋ฏธ์ฝ๋ก ์ ์์ฑํ์ง ์๋๋ค.
resultMap ์์ฑ : ๋งคํผ ํ์ผ์์ ๋ฏธ๋ฆฌ ์ค์ ํ resultMap์ ๋ฆฌํด ํ์ ์ผ๋ก ์ด์ฉํ๋ ๊ฒฝ์ฐ์ ์์ฑํ๋ค.
resultType ์์ฑ : ์ด๋ฏธ ์ ์๋์ด ์๋ ๊ฐ์ฒด ํ์ ์ ๋ฆฌํด ํ์ ์ผ๋ก ์ด์ฉํ๋ ๊ฒฝ์ฐ์ ์์ฑํ๋ค.
ํ๋ผ๋ฏธํฐ๋ #{ field } ๋๋ ${ field } ํํ๋ก ๊ธฐ์ ํ๋ฉฐ PreparedStatement์ ?(=placeholder)์ ์ญํ ์ ํ๋ค.
์ฌ์ฉ ์์
<select id="memberInfo" parameterType="string" resultMap="resultMember">
SELECT * FROM MEMBER WHERE ID = #{ userid }
</select>
<select> ํ๊ทธ์ ์ฃผ์ ์์ฑ
| ์์ฑ๋ช | ๋ด์ฉ |
|---|---|
| id | ๊ตฌ๋ฌธ์ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉ๋ ์ ์๋ namespace ๋ด ์ ์ผํ ๊ตฌ๋ถ์ |
| parameterType | ๊ตฌ๋ฌธ์ ์ ๋ฌ๋ ํ๋ผ๋ฏธํฐ์ ํด๋์ค๋ช (ํจํค์ง ๊ฒฝ๋ก ํฌํจ)์ด๋ ๋ณ์นญ |
| resultType | - return ๋๋ ํ์
์ ํจํค์ง ๊ฒฝ๋ก๋ฅผ ํฌํจํ ์ ์ฒด ํด๋์ค๋ช
์ด๋ ๋ณ์นญ - collection์ธ ๊ฒฝ์ฐ list, arraylist๋ก ์ค์ ๊ฐ๋ฅ |
| resultMap | ์ฌ์ฉํ resultMap์ id |
| flushCache | - true ์ค์ ํ๋ฉด ๊ตฌ๋ฌธ ํธ์ถ ์๋ง๋ค ๋ก์ปฌ, 2nd ๋ ๋ฒจ cache๊ฐ ์ง์์ง(flush) - ๊ธฐ๋ณธ๊ฐ = false |
| useCache | - true ์ค์ ํ๋ฉด ๊ตฌ๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ 2nd ๋ ๋ฒจ cache์ ์ ์ฅ - ๊ธฐ๋ณธ๊ฐ = true |
| timeout | - ์์ธ ๋ฐ์ ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ฒญ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ต๋ ์๊ฐ ์ค์ - ๋๋ผ์ด๋ฒ์ ๋ฐ๋ผ ์ง์ํ์ง ์์ ์ ์์ |
| statementType | - MyBatis์๊ฒ ์ฌ์ฉํ๊ฒ ํ Statement ์ ํ ๊ฐ๋ฅ (STATEMENT, PREPARED, CALLABLE ์ค ํ๋) (Statement, PreparedStatement, CallableStatement ์ฌ์ฉํ๊ฒ ํ๋ ๊ฒ) - ๊ธฐ๋ณธ๊ฐ = PreparedStatement |
| fetchSize | ์ง์ ๋ ์ ๋งํผ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ฒ ํ๋ ๋๋ผ์ด๋ฒ ํํธ ํํ์ ๊ฐ (๋ํดํธ: ์ค์ ์ํจ) |
| resultSetType | - ResultSet์ ์ปค์ ์ด๋ ๋ฐฉํฅ์ ์ง์ (๊ธฐ๋ณธ๊ฐ: FORWARD_ONLY) - FORWARD_ONLY, SCROLL_SENSITIVE, SCROLL_INSENCITIVE ์ค ํ๋๋ก ์ค์ (1) FORWARD_ONLY : ์ปค์๊ฐ ์์ผ๋ก๋ง ์ด๋ (2) SCROLL_SENSITIVE : ์ปค์๊ฐ ์๋ค๋ก ์ด๋ ๋ฐ ResultSet ๊ฐ์ฒด ์์ฑ ํ ์ถ๊ฐ ๋ฐ ์ญ์ ๋ ๋ฐ์ดํฐ๋ ๋ณผ ์ ์์ (3) SCROLL_INSENSITIVE : ์ปค์๊ฐ ์๋ค๋ก ์ด๋ํ ์ ์์ง๋ง ResultSet ๊ฐ์ฒด ์์ฑ ํ ์ถ๊ฐ ๋ฐ ์ญ์ ๋ ๋ฐ์ดํฐ๋ ๋ณผ ์ ์์ |
| databaseId | - ์ค์ ๋ databaseIdProvider๊ฐ ์์ผ๋ฉด databaseId ์์ฑ์ด ์๋ ๋ชจ๋ ๊ตฌ๋ฌธ์ ๋ก๋ํ๊ฑฐ๋ ์ผ์นํ๋ databaseId์ ํจ๊ป ๋ก๋ํจ - ๊ฐ์ ๊ตฌ๋ฌธ์์ databaseId๊ฐ ์๊ฑฐ๋ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ชจ๋ ์๋ค๋ฉด ๋ค์ ๋์จ ๊ฒ ๋ฌด์ |
๋ฐ์ดํฐ ์ฝ์ , ์์ , ์ญ์ ์์ ์ ์ํํ INSERT, UPDATE, DELETE ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ๋ ํ๊ทธ๋ก, ํ๊ทธ์ ์ค์ ์ด ๋์ผํ๋ค.
ํ๋ผ๋ฏธํฐ๋ก ๊ฐ์ฒด ํ์ ์ ๋ฐ๋ ๊ฒฝ์ฐ, ํด๋น ๊ฐ์ฒด์ ํ๋๋ช ์ผ๋ก ๋ฐ์ธ๋ฉํ์ฌ ์ฌ์ฉํ๋ค.
์ธ ๊ฐ์ ํ๊ทธ ๋ชจ๋ resultType์ด _int๋ก ๊ธฐ๋ณธ ์ค์ ๋์ด ์์ด, ์ํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ํ์ผ๋ก ๋ฐํํ๋ฏ๋ก ์์ฑํ์ง ์์๋ ๋ฌด๋ฐฉํ๋ค.
<insert> ์ฌ์ฉ ์์
<insert id="insertMember" parameterType="Member" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="true" timeout="20">
INSERT INTO MEMBER
VALUES(#{id}, #{passwd}, #{name}, #{email}, #{gender}, #{age}, #{phone}, #{address}, DEFAULT)
</insert>
<update> ์ฌ์ฉ ์์
<update id="updateMember" parameterType="Member" flushCache="true" statementType="PREPARED" timeout="20">
UPDATE MEMBER
SET PASSWD = #{passwd},
EMAIL = #{email},
AGE = #{age},
PHONE = #{phone},
ADDRESS = #{address}
WHERE ID = #{id}
</update>
<delete> ์ฌ์ฉ ์์
<delete id="deleteMember" parameterType="string" flushCache="true" statementType="PREPARED" timeout="20">
DELETE FROM MEMBER WHERE ID = #{userid}
</delete>
<insert>, <update>, <delete> ํ๊ทธ์ ์ฃผ์ ์์ฑ
| ์์ฑ๋ช | ๋ด์ฉ |
|---|---|
| id | ๊ตฌ๋ฌธ์ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉ๋ ์ ์๋ namespace ๋ด ์ ์ผํ ๊ตฌ๋ถ์ |
| parameterType | ๊ตฌ๋ฌธ์ ์ ๋ฌ๋ ํ๋ผ๋ฏธํฐ์ ํด๋์ค๋ช (ํจํค์ง ๊ฒฝ๋ก ํฌํจ)์ด๋ ๋ณ์นญ |
| flushCache | - true๋ก ์ค์ ํ๋ฉด ๊ตฌ๋ฌธ ํธ์ถ ์๋ง๋ค ์บ์ ์ญ์ (flush) - ๊ธฐ๋ณธ๊ฐ = false |
| timeout | - ์์ธ ๋ฐ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ฒญ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ต๋ ์๊ฐ ์ค์ - ๋๋ผ์ด๋ฒ์ ๋ฐ๋ผ ์ง์ํ์ง ์์ ์ ์์ |
| statementType | - JDBC ๊ตฌ๋ฌธ ํ์
์ ์ง์ (๊ธฐ๋ณธ๊ฐ: PREPARED) - STATEMENT, PREPARED, CALLABLE ์ค ํ๋ ์ฌ์ฉ ๊ฐ๋ฅ |
| useGeneratedKeys | - insert, update ์๋ง ์ ์ฉ - ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ด๋ถ์ ์ผ๋ก ์์ฑํ ํค(์: MySQL๋๋ SQL Server์ ์๋ ์ฆ๊ฐ ํ๋)๋ฅผ ๋ฐ๋ JDBC getGeneratedKeys method๋ฅผ ์ฌ์ฉํ๋๋ก ์ค์ - ๊ธฐ๋ณธ๊ฐ = false |
| keyProperty | - insert, update ์๋ง ์ ์ฉ - getGeneratedKeys method๋ insert ๊ตฌ๋ฌธ์ selectKeyํ๊ทธ์ ์ค์ - select๋ฌธ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ property ์ง์ - ์ค์ ํ์ง ์๋ ๊ฒ์ด default - ์ฌ๋ฌ ์ปฌ๋ผ์ ์ฌ์ฉํ๋ค๋ฉด property๋ช ์ ์ฝค๋ง๋ฅผ ๊ตฌ๋ถ์๋ก ๋์ด ๊ฐ๋ฅ |
| keyColumn | - insert ์๋ง ์ ์ฉ - ์์ฑ ํค๋ฅผ ๊ฐ์ง ํ ์ด๋ธ์ ์ปฌ๋ผ๋ช ์ค์ (ํค ์ปฌ๋ผ์ด ํ ์ด๋ธ์ ์ฒซ ๋ฒ์งธ ํ์ด ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์๋ง ํ์) |
๋ ํ๊ทธ ๋ชจ๋ ์บ์๋ฅผ ์ค์ ํ๋ ์ญํ ์ ํ๋ค.
โ Cache๋
- ๋ฐ์ดํฐ๋ ๊ฐ์ ๋ฏธ๋ฆฌ ๋ณต์ฌํด ๋์ ์์ ์ฅ์์ด๋ค.
- ์บ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ณต์ฌํด ๋์ผ๋ฉด ๊ณ์ฐ์ด๋ ์ ๊ทผ ์๊ฐ ์์ด ๋ ๋น ๋ฅธ ์๋๋ก ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๋ค.
์บ์์ ๊ธฐ๋ณธ(default) ์ค์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
์บ์ ์ฌ์ฉ ์์
<cache eviction="LRU" flushInterval="1000" size="512" readOnly="true"/>
<cache>ํ๊ทธ์ ์์ฑ
| ์์ฑ๋ช | ์ค๋ช |
|---|---|
| eviction | - ์บ์ ์๊ณ ๋ฆฌ์ฆ์ ์ข
๋ฅ (๊ธฐ๋ณธ๊ฐ: LRU) - FIFO, SOFT, WEAK๋ก ์ค์ ๊ฐ๋ฅ |
| flushInterval | - ์ค์ ๋ ์บ์์ ์ ์ง ์๊ฐ์ ์์์ ๋ฐ๋ฆฌ์ด ๋จ์๋ก ์ค์ |
| size | - ์บ์์ ์ ์ฅํ ๊ฐ์ฒด์ ์๋ฅผ ์ง์ (๊ธฐ๋ณธ๊ฐ: 1024) |
| readonly | ์ฝ๊ธฐ์ ์ฉ ์ค์ ์ผ๋ก ์บ์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ถ๊ฐํ๊ฒ ํจ |
์บ์์ ์ ์ฝ ์ฌํญ
๊ธฐ๋ณธ์ ์ผ๋ก ๋ก์ปฌ ์์ญ์ด๋ฏ๋ก ์๋ฒ๋ฅผ ์ฌ๋ฌ ๋ ๋๋ ๊ฒฝ์ฐ ์บ์ ๋ด์ฉ์ด ์๋ก ๋ค๋ฅผ ์ ์๋ค.
์บ์์ ํ์ด๋จธ ์ค์ ์ ๊ฐ๋ฅํ ๋ฐ๋ฉด ์ค์ผ์ฅด๋ง์ ๋ถ๊ฐ๋ฅํ๋ค.
<sql> ์์ฑ
<sql id="columns">
MENU_CODE
, MENU_NAME
, MENU_PRICE
, CATEGORY_CODE
, ORDERABLE_STATUS
</sql>
<sql> ํ์ฉ
<select id="selectSqlTest" resultMap="menuResultMap2">
SELECT
<include refid="columns"/>
FROM TBL_MENU A
WHERE A.ORDERABLE_STATUS = 'Y'
</select>
๋์์ด ๋ง์ด ๋์ต๋๋ค!