Ibatis
- 1. Data Mapper
(a.k.a SQL Maps)
Version 2.0
๊ฐ๋ฐ์ ๊ฐ์ด๋
2006๋
3์ 11์ผ
๋ฒ์ญ : ์ด๋๊ตญ(fromm0@gmail.com)
์คํ ๋ฐ ์ค์ญ์ ์ ๋ฉ์ผ์ฃผ์๋ก ๋ณด๋ด์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.
1
- 2. ์๊ฐ
iBATIS Data Mapper ํ๋ ์์ํฌ๋ ๋น์ ์ด ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ ๋ ํ์ํ ์๋ฐ์ฝ๋๋ฅผ ํ์ ํ๊ฒ ์ค์ผ์ ์๋๋ก
๋์์ค๊ฒ์ด๋ค. iBATIS๋ ๊ฐ๋จํ XML์์ ์๋ฅผ ์ฌ์ฉํด์ ๊ฐ๋จํ๊ฒ ์๋ฐ๋น์ฆ๋ฅผ SQL statement์ ๋งตํ์ํจ๋ค. ๊ฐ๋จํจ
(Simplicity)์ด๋ ๋ค๋ฅธ ํ๋ ์์ํฌ์ ๊ฐ์ฒด๊ด๊ณ๋งตํํด์ ๋นํด iBATIS์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ด๋ค. iBATIS Data Mapper๋ฅผ ์ฌ์ฉํ๊ธฐ
์ํด์ ๋น์ ์ ์๋ฐ๋น์ฆ์ XML ๊ทธ๋ฆฌ๊ณ SQL์ ์น์ํ ํ์๊ฐ ์๋ค. ์ฌ๊ธฐ์ ๋ฐฐ์์ผ ํ ๊ฒ๋ ๊ฑฐ์ ์๊ณ ํ
์ด๋ธ์ ์กฐ์ธํ๊ฑฐ๋ ๋ณต
์กํ ์ฟผ๋ฆฌ๋ฌธ์ ์ํํ๊ธฐ ์ํด ํ์ํ ๋ณต์กํ ์คํค๋ง๋ ์๋ค. Data Mapper๋ฅผ ์ฌ์ฉํ๋ฉด ๋น์ ์ ์ค์ SQL๋ฌธ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ฐ
์ง์ ์๋ค.
Data Mapper (com.ibatis.sqlmap.*)
๊ฐ๋
iBATIS Data Mapper API๋ ํ๋ก๊ทธ๋๋จธ์๊ฒ ์๋ฐ๋น์ฆ ๊ฐ์ฒด๋ฅผ PreparedStatementํ๋ผ๋ฏธํฐ์ ResultSets์ผ๋ก ์ฝ๊ฒ ๋งตํํ ์
์๋๋ก ํ๋ค. Data Mapper์ ๊ธฐ๋ณธ์ ์ธ ์๊ฐ์ ๊ฐ๋จํจ(simple)์ด๋ค. ์ด๋ ์๋ฐ์ฝ๋์ 20%๋ฅผ ์ฌ์ฉํ์ฌ JDBC๊ธฐ๋ฅ์ 80%๋ฅผ
์ ๊ณตํ๋ ๊ฐ๋จํ ํ๋ ์์ํฌ๋ผ๋ ๋ป์ด๋ค.
์ด๊ฒ์ ์ด๋ป๊ฒ ์๋ํ๋๊ฐ.?
Data Mapper๋ ์๋ฐ๋น์ฆ, Map๊ตฌํ, ์์๋ํผํ์
(String, Integerโฆ) ๊ทธ๋ฆฌ๊ณ SQL๋ฌธ์ ์ํ XML๋ฌธ์๋ฅผ ๋งตํํ๊ธฐ ์
ํ XML์์ ์๋ฅผ ์ฌ์ฉํ๋ ๋งค์ฐ ๊ฐ๋จํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํ๋ค. ๋ค์์ ์๋ช
์ฃผ๊ธฐ์ ๋ํ ๋์ ๋ ๋ฒจ์ ์์ ์ด๋ค.
1) ํ๋ผ๋ฏธํฐ(์๋ฐ๋น์ฆ, Map ๋๋ ์์๋ํผ)๋ก์จ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ค. ํ๋ผ๋ฏธํฐ ๊ฐ์ฒด๋ update๋ฌธ๋ด์ ์
๋ ฅ๊ฐ์ ์
ํ
ํ
๊ธฐ ์ํด ์ฌ์ฉ๋๊ฑฐ๋ ์ฟผ๋ฆฌ๋ฌธ์ where์ ์ ์
ํ
ํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ค.
2) ๋งตํ๋ statement์ ์คํํ๋ค. ์ด ๋จ๊ณ๋ ๋ง๋ฒ์ด ์ผ์ด๋๋๊ณณ์ด๋ค. Data Mapperํ๋ ์์ํฌ๋
PreparedStatement ์ธ์คํด์ค๋ฅผ ์์ฑํ ๊ฒ์ด๊ณ ์ ๊ณต๋ ํ๋ผ๋ฏธํฐ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ํ๋ผ๋ฏธํฐ๋ฅผ ์
ํ
ํ๋ค. ๊ทธ๋ฆฌ
๊ณ statement๋ฅผ ์คํํ๊ณ ResultSet์ผ๋ก๋ถํฐ ๊ฒฐ๊ณผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
3) update์ ๊ฒฝ์ฐ์ ์ํฅ์ ๋ฏธ์น rows์ ์ซ์๋ฅผ ๋ฐํํ๋ค. ์กฐํ๋ฌธ์ผ๊ฒฝ์ฐ์ ํ ๊ฐ(single)์ ๊ฐ์ฒด ๋๋ ์ปฌ๋ ์
๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค. ํ๋ผ๋ฏธํฐ์ฒ๋ผ ๊ฒฐ๊ณผ ๊ฐ์ฒด๋ ์๋ฐ๋น์ฆ, Map ์์ํ์
๋ํผ๋๋ XML์ด ๋ ์ ์๋ค.
๋ฐ์ ๋ค์ด์ด๊ทธ๋จ์ ์์ ๋ ๊ฒ์ ์ค๋ช
ํ๋ค.
2
- 3. ์ค์น
iBATIS Data Mapper ํ๋ ์์ํฌ ์ค์น๋ ๊ฐ๋จํ๊ฒ ํด๋์คํจ์ค์ ํ์ํ JARํ์ผ์ ๋๋ฉด ๋๋ค. ์ด๊ฒ์ JVM์์์ ์ ์๋ ํด
๋์คํจ์ค์ ๋๊ฑฐ๋ ์น์ ํ๋ฆฌ์ผ์ด์
์ /WEB-INF/lib์ ๋์๋ ์๋ค. ์๋ฐ ํด๋์คํจ์ค์ ๋ํด์๋ ๋ค์์ ์์์ ์ฐธ์กฐํ๋ผ.
http://java.sun.com/j2se/1.4/docs/tooldocs/win32/classpath.html
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html
http://java.sun.com/j2se/1.4.2/docs/
iBATIS๋ ๋ค์์ JARํ์ผ์ ๊ฐ์ง๋ค.
ํ์ผ๋ช
์์ธ์ค๋ช
ํ์์ฌ๋ถ
ibatis-common.jar iBATIS Common Utilities YES
ibatis-sqlmap.jar iBATIS Data Mapper Framework YES
ibatis-dao.jar iBATIS Data Access Objects NO
Framework.
JAR ํ์ผ๊ณผ ์์กด์ฑ
ํ๋ ์์ํฌ๊ฐ ๋๋ฌด ๋ง์ ์์กด์ฑ์ ๊ฐ์ง๋ค๋ฉด ์ด๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์
์ด๋ ๋ค๋ฅธ ํ๋ ์์ํฌ์ ํตํฉ๋๊ธฐ ํ๋ค๊ฒ ๋ง๋ ๋ค. 2.0์ ์ค
์ํ ํต์ฌ์ฌํญ์ ์์กด์ฑ๊ด๋ฆฌ์ ์ ๊ฑฐ์ ์ค์ ์ ๋์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ง์ฝ ๋น์ ์ด jdk1.4๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ค์ ์์กด์ ์ธ ๊ฒ์
Jakarta Commons Logging ํ๋ ์์ํฌ๋ฟ์ด๋ค. ์ด ์ถ๊ฐ์ ์ธ JARํ์ผ์ ๋ฐฐํฌํ์ /lib/optional๋๋ ํ ๋ฆฌ์์ ์ฐพ์์ ์๋ค. ๊ทธ๋ค
์ ๊ธฐ๋ฅ์ ์ํด ๋ถ๋ฅ๋๋ค. ๋ค์์ ์ถ๊ฐ์ ์ธ ํจํค์ง๋ฅผ ์ฌ์ฉํ ๋ ํ์ํ ๊ฒ๋ค์ ๋ชฉ๋ก์ด๋ค.
Description When to Use Directories
JDBC 2.0 Extensions
http://java.sun.com/products/jdbc/download.html
๋ง์ฝ์ ๋น์ ์ด JDK1.4๋ณด๋ค ํ์ ๋ฒ์ ์ ์ฌ
Legacy JDK ์ฉํ๊ณ ๋น์ ์ ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ๊ฐ ์ด๋ฐ JTA 1.0.1a
http://java.sun.com/products/jta/
Support JARํ์ผ์ ์ ๊ณตํ์ง ์๋๋ค๋ฉด ๋น์ ์ ์ด๋ฐ
Xerces 2.4.0
์ต์
ํจํค์ง๊ฐ ํ์ํ ๊ฒ์ด๋ค. http://xml.apache.org/xerces2-j/
๋น์ ์ด iBATIS์ ์์ ๋ฒ์ DAO(1.x)ํ๋ iBATIS DAO 1.3.1
์์ํฌ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ฑฐ๋ SQL Maps(1.x) http://sourceforge.net/projects/ibatisdb/
iBATIS Backward
์ ์์ ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด ์ด ๋๋ ํ
Compatibility
๋ฆฌ์ JARํ์ผ์ ๊ฐ๋จํ ํฌํจ์ํด์ผ๋ก์จ ๊ณ
์ ์์
์ ํ ์ ์๋ค.
Runtime ๋ง์ฝ ๋น์ ์ด ๋ฆ์(lazy) ๋ก๋ฉ๊ณผ ์ฑ๋ฅ์ ๋ CGLIB 2.0
Bytecode ํด ๊ณ ๋ คํ๊ธฐ ์ํ CGLIB2.0 bytecode ๊ฐ์ http://cglib.sf.net
Enhancement ์ ์ฌ์ฉํ๊ธธ ์ํ๋ค๋ฉด
DataSource ๋น์ ์ด Jakarta DBCP Connection pool์ DBCP 1.1
Implementation ์ฌ์ฉํ๊ธธ ์ํ๋ค๋ฉด http://jakarta.apache.org/commons/dbcp/
Distributed ์ค์์ง์ค์ ์ด๊ฑฐ๋ ๋ถ์ฐ ์บ์ ์ง์์ ์ํ OSCache 2.0.1
Caching OSCache๋ฅผ ์ฌ์ฉํ๊ธธ ์ํ๋ค๋ฉด http://www.opensymphony.com/oscache/
Logging Solution Log4J ๋ก๊น
์ ์ฌ์ฉํ๊ธธ ์ํ๋ค๋ฉด Log4J 1.2.8
http://logging.apache.org/log4j/docs/
1.x ์์ ์
๊ทธ๋ ์ด๋ํ๊ธฐ
๋น์ ์ ์
๊ทธ๋ ์ด๋ ํ ๊ฒ์ธ๊ฐ.?
๋ง์ฝ ๋น์ ์ด ์
๊ทธ๋ ์ด๋๋ฅผ ์๋ํ๋ค๋ฉด ๊ฒฐ์ ํ ์ ์๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ค. ์ฌ๊ธฐ์ ๋ช๊ฐ์ง ์
๊ทธ๋ ์ด๋ ์ ์ฐจ๊ฐ ์๋ค.
3
- 4. 1. ๋ฒ์ 2.0์ 1.x๋ฆด๋ฆฌ์ฆ์ ๊ฑฐ์ ์๋ฒฝํ ํธ์์ฑ์ ๊ฐ์ง๋๋ก ์ ์ง๋์๋ค. ๊ทธ๋์ ๋ช๋ช ์ฌ๋๋ค์๊ฒ๋ ๋จ์ํ JARํ์ผ๋ง
๊ต์ฒดํ๋๊ฒ์ผ๋ก ์ถฉ๋ถํ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์ต์ํ์ ์ด๋์ ๋ฐ์์ํค์ง๋ง ๊ฐ์ฅ ๊ฐ๋จํ๋ค. ๋น์ ์ ๋น์ ์ XMLํ์ผ์ด๋
์๋ฐ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค. ๋ช๋ช ๋ชจ์๋๋๊ฒ๋ค์ด ๋ฐ๊ฒฌ๋ ์ง๋ ๋ชจ๋ฅธ๋ค.
2. ๋๋ฒ์งธ๋ ๋น์ ์ XMLํ์ผ์ 2.0์คํ์ ์ ํฉํ๋๋ก ๋ณ๊ฒฝํ๋๊ฒ์ด๋ค. ํ์ง๋ง ์ด๋ 1.x ์๋ฐ API๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
์ ์ ํธํ์ฑ์ด์๋ด ์์ ํ ํด๊ฒฐ๋ฒ์ ๋งตํํ์ผ ์ฌ์ด์ ๋ฐ์ํ๋ค. Ant์์
์ ๋น์ ์ ์ํด XMLํ์ผ์ ๋ณํํ๊ธฐ ์ํด์
ํ๋ ์์ํฌ์ ํฌํจ๋๋ค.
3. ์ธ๋ฒ์งธ ์ต์
์ ๋น์ ์ XMLํ์ผ๊ณผ ์๋ฐ์ฝ๋๋ฅผ ๋ณํํ๋ ๊ฒ์ด๋ค. ์๋ฐ์ฝ๋๋ฅผ ๋ณํํ๊ธฐ ์ํ ํด์ ์๋ค. ๊ทธ๋์ ์ด๊ฒ
์ ์์ผ๋ก ์ง์ ํด์ผ ํ๋ค.
4. ๋ง์ง๋ง ์ต์
์ ์ ์ฒด๋ฅผ ์
๊ทธ๋ ์ด๋ ํ์ง ์๋๊ฒ์ด๋ค. ๋ง์ฝ์ ๋น์ ์ด ์ด๋ ต๋ค๊ณ ๋๋๋ค๋ฉด 1.x๋ฆด๋ฆฌ์ฆ์์ ์์คํ
์ด ์
๋ํ๋ ๊ฒ์ ๋๋ ค์ํ์ง ๋ง๋ผ. ๋น์ ์ ์ค๋๋ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ทธ๋๋ก ๋๋๋ ๊ฒ์ ๋์ ์๊ฐ์ด ์๋๋ค. ๋ง์ฝ์ ์ค๋
๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ธ์์ ์ธ ๋ฉด์์ ์ ๋๋ก ๋ฆฌํฉํ ๋ง๋์ด ์๋ค๋ฉด ๋น์ ์ SQL Maps๋ฅผ ์
๊ทธ๋ ์ด๋ ์ ํ ์ ์์๊ฒ์ด
๋ค.
1.x์์ 2.x์ผ๋ก XML์ค์ ํ์ผ ๋ณํํ๊ธฐ
2.0ํ๋ ์์ํฌ๋ Ant๋น๋์์คํ
์ ํตํด ์ํ๋๋ XML๋ฌธ์ ๋ณํ๊ธฐ๋ฅผ ํฌํจํ๋ค. ๋น์ ์ XML๋ฌธ์๋ฅผ ๋ณํํ๋ ๊ฒ์ 1.x์ฝ๋๊ฐ
์๋์ค์ ์๋์ผ๋ก ์ค๋๋ XMLํ์ผ์ ๋ณํํ๋ ๊ฒ์ฒ๋ผ ์ต์
์ ์ด๋ค. ์ฌ์ ํ ๋น์ ์ด ์
๊ทธ๋ ์ด๋๋ฅผ ํจ์ผ๋ก์จ ํธ์ํ๊ฒ ๋น์ ์
ํ์ผ์ ๋ณํํ๋ ๊ฒ์ด ์ข์ ์๊ฐ์ด๋ค. ๋น์ ์ ๋ค์ ์ ์ ํธํ์ ์ธ ์ด์๋ฅผ ๊ฒฝํํ ๊ฒ์ด๊ณ ์๋ก์ด ๊ธฐ๋ฅ์ค ๋ช ๊ฐ์ ์ฅ์ ์ ์ป์์
์์๊ฒ์ด๋ค(๋น๋ก ๋น์ ์ด 1.x์๋ฐ API์ ์ฌ์ฉํ๋๋ผ๋.).
Ant์์
์ ๋น์ ์ build.xmlํ์ผ๋ด์ ๋ค์๊ณผ ๋น์ทํ๊ฒ ๋ณด์ผ๊ฒ์ด๋ค.
<taskdef name="convertSqlMaps"
classname="com.ibatis.db.sqlmap.upgrade.ConvertTask"
classpathref="classpath"/>
<target name="convert">
<convertSqlMaps todir="D:/targetDirectory/" overwrite="true">
<fileset dir="D/sourceDirectory/">
<include name="**/maps/*.xml"/>
</fileset>
</convertSqlMaps>
</target>
๋น์ ์ด ๋ณด๋๊ฒ์ฒ๋ผ ์ด๊ฒ์ Ant ๋ณต์ฌ ์์
๊ณผ ๊ฑฐ์ ๊ฐ๊ณ ์ฌ์ค ์ด๊ฒ์ Ant๋ณต์ฌ ์์
์ ํ์ฅํ๊ฒ์ด๋ค. ๊ทธ๋์ ๋น์ ์ ๋ณต์ฌํ๋
์์
์ ํ๋ ์ด๋ค๊ฒ๋ ํ ์ ์๋ค.
JAR ํ์ผ๋ค: ์์ ๊ฒ์ ๋นผ๋ด๊ณ ์๊ฒ์ ๋ฃ์.
์
๊ทธ๋ ์ด๋๋ฅผ ํ ๋ ์กด์ฌํ๋(์์ ์) iBATISํ์ผ๊ณผ ์์กด์ ์ธ ๊ฒ๋ค์ ๋ชจ๋ ์ง์ฐ๊ณ ์ ํ์ผ์ ๋์ฒดํ๋๊ฒ์ด ์ข์ ์๊ฐ์ด๋ค.
์ฌ์ ํ ํ์ํ ๋น์ ์ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋๋ ํ๋ ์์ํฌ๋ฅผ ๋ชจ๋ ์ง์ฐ์ง ์๋๋ก ์ฃผ์ํด๋ผ. JARํ์ผ์ ๋๋ถ๋ถ์ ๋น์ ํ๊ฒฝ์
์์กด์ ์ด๋ค. JARํ์ผ๊ณผ ์์กด์ ์ธ๊ฒ์ ๋ํด์๋ ์์์ ์์ ๋ ๊ฒ์ ๋ณด์๋ผ.
๋ค์์ ํ
์ด๋ธ์ ์์ ํ์ผ๊ณผ ์ ํ์ผ์ ๋ชฉ๋กํ ํ๋ค.
Old Files New Files
4
- 5. ibatis-common.jar (ํ์)
ibatis-db.jar ibatis-sqlmap.jar (ํ์)
1.2.9b ๋ฒ์ ์์๋ถํฐ ์ด ํ์ผ์ ๋ค์์ 3๊ฐ์ ํ์ผ๋ก ibatis-dao.jar (DAOํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋๊ฒ์ ๋ฐ
๋ถ๋ฆฌ๋์๋ค. ๋ผ ์ต์
)
ibatis-common.jar
ibatis-dao.jar
ibatis-sqlmap.jar
commons-logging-1-0-3.jar (ํ์)
commons-logging.jar commons-collections-2-1.jar (์ต์
)
commons-logging-api.jar commons-dbcp-1-1.jar (์ต์
)
commons-collections.jar commons-pool-1-1.jar (์ต์
)
commons-dbcp.jar oscache-2-0-1.jar (์ต์
)
commons-pool.jar jta-1-0-1a.jar (์ต์
)
oscache.jar jdbc2_0-stdext.jar (์ต์
)
jta.jar xercesImpl-2-4-0.jar (์ต์
)
jdbc2_0-stdext.jar xmlParserAPIs-2-4-0.jar (์ต์
)
xercesImpl.jar xalan-2-5-2.jar (์ต์
)
xmlParserAPIs.jar log4j-1.2.8.jar (์ต์
)
jdom.jar cglib-full-2-0-rc2.jar (์ต์
)
์ด ๊ฐ์ด๋์ ๋๋จธ์ง๋ ๋น์ ์ด SQL Maps๋ฅผ ์ฌ์ฉํ๋๊ฒ์ ๋ํด ์๊ฐํ ๊ฒ์ด๋ค.
SQL Map XML์ค์ ํ์ผ
(http://ibatis.apache.org/dtd/sql-map-config-2.dtd)
SQL Maps๋ ๋ฐ์ดํฐ์์ค, ๋ฐ์ดํฐ ๋งตํผ์ ๋ํ ์ค์ , ์ฐ๋ ๋ ๊ด๋ฆฌ์ ๊ฐ์ SQL Maps์ ๋ค๋ฅธ ์ต์
์ ๋ํ ์ค์ ์ ์ ๊ณตํ๋ ์ค
์์ง์ค์ ์ธ XML์ค์ ํ์ผ์ ์ฌ์ฉํด์ ์ค์ ๋๋ค. ๋ค์์ SQL Maps์ค์ ํ์ผ์ ์์ด๋ค.
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<!--๋ค์์ ์ ํํ XMLํค๋๋ฅผ ์ํ ํ์๊ฐ์ด๋ค. -->
<sqlMapConfig>
<!--์ฌ๊ธฐ์ ๋ช
์๋ ํ์ผ๋ด ํ๋ผํผํฐ(name=value)๋ ์ด ์ค์ ํ์ผ๋ด ๊ณ ์ ์(placeholder)์ ์ํด ์ฌ์ฉ๋ ์ ์๋ค. (์ด๋ฅผํ
๋ฉด. โ${driver}โ. ์ด ํ์ผ์ ํด๋์คํจ์ค์ ์๋์ ์ด๊ณ ์ ํ์ ์ธ ์ฌํญ์ด๋ค. -->
<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />
<!--์ด ์
ํ
์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ํธ๋์ญ์
๊ด๋ฆฌ๋ฅผ ํ๋ฉฐ SqlMapClient์ค์ ์์ธ๋ฅผ ์ ์ดํ๋ค. ์ด๊ฒ๋ค์ ๋ชจ๋ ์ ํ์ ์ด๋ค. -->
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="128"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>
5
- 6. <!--๊ธด ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ํฌํจํ ํด๋์ค๋ช
์ ์ํ ์ข๋ ์งง์ ์ด๋ฆ์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ณ์นญ์ ํ์ดํํ๋ค. -->
<typeAlias alias="order" type="testdomain.Order"/>
<!--SimpleDataSource ๋ฅผ ์ด์ฉํ SQL Map๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๋ฐ์ดํฐ์์ค ์ค์ .
์ ์์์ผ๋ก ๋ถํฐ ํ๋ผํผํฐ ์ฌ์ฉ์ ์ฃผ์ํ . -->
<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<property name="JDBC.DefaultAutoCommit" value="true" />
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan" value="1"/>
<property name="Pool.PingConnectionsNotUsedFor" value="1"/>
</dataSource>
</transactionManager>
<!--์ด SQL map์ ์ํด ๋ก๋๋๋ ๋ชจ๋ SQL Mapํ์ผ์ ์ธ์ํ๋ค. ๊ฒฝ๋ก๋ ํด๋์คํจ์ค์ ์๋์ ์ด๋ค. -->
<sqlMap resource="examples/sqlmap/maps/Person.xml" />
</sqlMapConfig>
์ด ๋ฌธ์์ ๋ค์ ๋ถ๋ถ์ SQL Maps์ค์ ํ์ผ์ ๋ค์ํ ๋ถ๋ถ์ ๋
ผ์ํ๋ค.
<properties> ์์
SQL Maps์ SQL Maps XML์ค์ ํ์ผ๊ณผ ํจ๊ป ์ํ๋ ํ์ค์ ์ธ ์๋ฐ ์์ฑํ์ผ(name=value)์ ์ง์ ํ๋ ํ๋์ <properties>
์์๋ฅผ ๊ฐ์ง ์ ์๋ค. ๊ทธ๋ ๊ฒ ํจ์ผ๋ก์จ ์์ฑํ์ผ๋ด์ ๊ฐ๊ฐ์ ์ด๋ฆ์ง์ด์ง ๊ฐ๋ค์ SQL Maps์ค์ ํ์ผ๋ด์ ์ฐธ์กฐ๋ ์ ์๋ ๋ณ์
๊ฐ ๋ ์ ์๊ณ ๋ชจ๋ SQL Maps๋ ๋ด๋ถ์์ ์ฐธ์กฐ๋๋ค. ์๋ฅผ ๋ค๋ฉด ์์ฑํ์ผ์ด ๋ค์์ ํฌํจํ๋ค๋ฉด
driver=org.hsqldb.jdbcDriver
๊ทธ๋ฌ๋ฉด SQL Maps์ค์ ํ์ผ๋๋ ์ค์ ๋ฌธ์์ ์ํด ์ฐธ์กฐ๋๋ ๊ฐ๊ฐ์ SQL Maps๋ ${driver} ํํ๋ก ์ฌ์ฉ๊ฐ๋ฅํ๊ณ
org.hsqldb.jdbcDriver๋ผ๋ ๊ฐ์ด ์ฐธ์กฐ๋๋ค. ์๋ฅผ ๋ค๋ฉด
<property name="JDBC.Driver" value="${driver}"/>
์ด๊ฒ์ ๋น๋๋๊ฑฐ๋ ํ
์คํธ ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์น๋๋ ๋์ ํธ๋ฆฌํ๊ฒ ๋๋ค. ์ด๊ฒ์ ๋ค์ค ํ๊ฒฝ์ด๋ ์ค์ ํ์ผ์ ์ํ ์๋ํํด์ ์ฌ์ฉํ
๋ ๋น์ ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฝ๊ฒ ์ธ์ํ๋๋ก ํ๋ค. ํ๋ผํผํฐ๋ ํด๋์คํจ์ค๋ ์ด๋ค ์ ํจํ URL๋ก๋ถํฐ ๋ก๋๋ ์ ์๋ค. ์๋ฅผ ๋ค
๋ฉด ๊ณ ์ ๋ ํ์ผ๊ฒฝ๋ก๋ฅผ ์ํด ๋ค์์ฒ๋ผ ์ฌ์ฉํ๋ค.
<properties url=โfile:///c:/config/my.propertiesโ />
<settings> ์์
<settings> ์์๋ XMLํ์ผ์ ๋น๋ํ๋ SqlMapClient ์ธ์คํด์ค๋ฅผ ์ํด ๋ค์ํ ์ต์
๊ณผ ์ต์ ํ๋ฅผ ์ค์ ํ๋๋ก ํ๋ค. setting์
์์ ๊ทธ๊ฒ์ ๋ชจ๋ ์์ฑ๊ฐ์ ๋ชจ๋ ์ต์
์ ์ด๋ค. ์ ๊ณต๋๋ ์์ฑ๊ฐ๊ณผ ๊ทธ๊ฒ๋ค์ ๋ค์ํ ํ์๋ ๋ค์์ ํ
์ด๋ธ์์ ์์ ๋๋ค.
maxRequests ์ด๊ฒ์ ํ๊บผ๋ฒ์ SQL๋ฌธ์ ์ํํ ์ ์๋ ์ฐ๋ ๋์ ์์ด๋ค. ์
ํ
๊ฐ๋ณด๋ค ๋ง
6
- 7. ์ ์ฐ๋ ๋๋ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ์ํ์ ์๋ฃํ ๋๊น์ง ๋ธ๋ก๋๋ค. ๋ค๋ฅธ DBMS๋
๋ค๋ฅธ ์ ํ์ ๊ฐ์ง๋ค. ์ด๊ฒ์ ์ต์ํ 10๊ฐ์ maxTransactions์ด๊ณ ์ธ์ ๋
maxSessions๊ณผ maxTransactions๋ณด๋ค ํฌ๋ค. ์ข
์ข
๋์์์ฒญ๊ฐ์ ์ต๋์น๋ฅผ
์ค์ด๋ฉด ์ฑ๋ฅํฅ์์ ๋ณด์ฌ์ค๋ค.
์:
maxRequests=โ256โ
Default: 512
maxSessions ์ด๊ฒ์ ์ฃผ์ด์ง ์๊ฐ๋์ ํ์ฑ๋ ์ ์๋ ์ธ์
์ ์์ด๋ค. ์ธ์
์ ๋ช
์์ ์ผ๋ก
์ฃผ์ด์ง์๋ ์๊ณ ํ๋ก๊ทธ๋จ์ ์ผ๋ก ์์ฒญ๋ ์๋ ์๊ณ ์ฐ๋ ๋๊ฐ SqlMapClient
์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ ๋๋ง๋ค ์๋์ ์ผ๋ก ์์ฑ๋ ์๋ ์๋ค. ์ด๊ฒ์ ์ธ์ ๋
maxTransaction๋ณด๋ค ๊ฐ๊ฑฐ๋ ์ปค์ผ ํ๊ณ maxRequests๋ณด๋ค ์์์ผ ํ๋ค. ๋
์์ธ์
๊ฐ์ ์ต๋์น๋ฅผ ์ค์ด๋ฉด ์ ์ฒด์ ์ธ ๋ฉ๋ชจ๋ฆฌ์ฌ์ฉ๋์ ์ค์ผ์ ์๋ค.
์:
maxSessions=โ64โ
Default: 128
maxTransactions ์ด๊ฒ์ ํ๊บผ๋ฒ์ SqlMapClient.startTransaction()์ ๋ค์ด๊ฐ์ ์๋ ์ฐ๋ ๋
์ ์ต๋๊ฐฏ์์ด๋ค. ์
ํ
๊ฐ๋ณด๋ค ๋ง์ ์ฐ๋ ๋๋ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋์ฌ๋๊น์ง ๋ธ
๋ก๋๋ค. ๋ค๋ฅธ DBMS๋ ๋ค๋ฅธ ์ ํ์ ๊ฐ์ง๋ค. ์ด ๊ฐ์ ์ธ์ ๋ maxSessions๋ณด
๋ค ์๊ฑฐ๋ ๊ฐ์์ผ ํ๊ณ maxRequests๋ณด๋ค ์์์ผ ํ๋ค. ์ข
์ข
๋์ํธ๋์ญ์
์ ์ต๋์น๋ฅผ ์ค์ด๋ฉด ์ฑ๋ฅํฅ์์ ๋ณด์ฌ์ค๋ค.
์:
maxTransactions=โ16โ
Default: 32
cacheModelsEnabled ์ด ์
ํ
์ SqlMapClient ๋ฅผ ์ํ ๋ชจ๋ ์บ์ฌ๋ชจ๋ธ์ ๊ฐ๋ฅํ๊ฒ ํ๊ฑฐ๋ ๊ฐ๋ฅํ
์ง ์๊ฒ ํ๋ค. ์ด๊ฒ์ ๋๋ฒ๊น
์ ๋์์ด ๋๋ค.
์:
cacheModelsEnabled=โtrueโ
Default: true (enabled)
lazyLoadingEnabled ์ด ์
ํ
์ SqlMapClient ๋ฅผ ์ํ ๋ชจ๋ ๋ฆ์(lazy)๋ก๋ฉ์ ๊ฐ๋ฅํ๊ฒ ํ๊ฑฐ๋ ๊ฐ
๋ฅํ์ง ์๊ฒ ํ๋ค. ์ด๊ฒ์ ๋๋ฒ๊น
์ ๋์์ด ๋๋ค.
์:
lazyLoadingEnabled=โtrueโ
Default: true (enabled)
enhancementEnabled ์ด ์
ํ
์ ํฅ์๋ ๋ฆ์(lazy)๋ก๋ฉ์ฒ๋ผ ์ต์ ํ๋ ์๋ฐ๋น์ฆ ์์ฑ ์ ๊ทผ์ ์
ํด ๋ฐํ์์ ๋ฐ์ดํธ์ฝ๋ ํฅ์์ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
์:
enhancementEnabled=โtrueโ
Default: false (disabled)
useStatementNamespaces ์ด ์
ํ
์ ๊ฐ๋ฅํ๊ฒ ํ๋ฉด ๋น์ ์ sqlmap์ด๋ฆ๊ณผ statement์ด๋ฆ์ผ๋ก ๊ตฌ์ฑ๋
์ ์ฒด์ ์ธ ์ด๋ฆ(fully qualified name)์ผ๋ก ๋งตํ๋ statement๋ฅผ ์ฐธ์กฐํด์ผ ํ
๋ค.
์๋ฅผ ๋ค๋ฉด: queryForObject(โsqlMapName.statementNameโ);
์:
useStatementNamespaces=โfalseโ
Default: false (disabled)
<typeAlias> ์์
7
- 8. typeAlias ์์๋ ๊ธด ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ํฌํจํ ํด๋์ค๋ช
์ ์ฐธ์กฐํ๊ธฐ ์ํ ์งง์ ์ด๋ฆ์ ๋ช
์ํ๋๋ก ํ๋ค. ์๋ฅผ ๋ค๋ฉด
<typeAlias alias="shortname" type="com.long.class.path.Class"/>
SQL Maps์ค์ ํ์ผ์์ ์ฌ์ฉ๋๋ ๋ฏธ๋ฆฌ ์ ์๋ ๋ช๋ช alias๊ฐ ์๋ค. ๊ทธ๊ฒ๋ค์
Transaction Manager Aliases
JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
Data Source Factory Aliases
SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory
DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory
JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory
<transactionManager> ์์
1.0 ๋ณํ๋
ธํธ: SQL Maps 1.0์ ๋ค์ค์ ๋ฐ์ดํฐ์์ค ์ค์ ์ ํ๋ฝํ๋ค. ์ด๊ฒ์ ๋ค๋ฃจ๊ธฐ ์ด๋ ต๊ณ ๋ช๊ฐ์ง ๋์ ์์ ๋ฅผ ์๊ฐํ๋ค. ๊ทธ
๋ฌ๋ฏ๋ก 2.0์์๋ ์ค์ง ํ๋์ ๋ฐ์ดํฐ์์ค๋ง์ ํ๋ฝํ๋ค. ๋ค์ค์ ๋ฐฐ์น/์ค์ ์ ์ํด์๋ ์์คํ
์ ์ํด ๋ค๋ฅด๊ฒ ์ค์ ๋๊ฑฐ๋
SQL Maps๋ฅผ ๋น๋ํ ๋ ํ๋ผ๋ฏธํฐ์ฒ๋ผ ์ ๋ฌ๋๋ ๋ค์ค์์ฑํ์ผ์ด ์ถ์ฒ๋๋ค.
<transactionManager> ์์๋ ๋น์ ์ด SQL Maps๋ฅผ ์ํ ํธ๋์ญ์
๊ด๋ฆฌ๋ฅผ ์ค์ ํ๋๋ก ํ๋ค. type ์์ฑ๊ฐ์ ์ฌ์ฉํ๊ธฐ ์ํ
ํธ๋์ญ์
๊ด๋ฆฌ์๋ฅผ ํ์ํ๋ค. ๊ทธ ๊ฐ์ ํด๋์ค๋ช
์ด๊ฑฐ๋ ํ์
alias์ผ์ ์๋ค. 3๊ฐ์ ํธ๋์ญ์
๊ด๋ฆฌ์๋ JDBC, JTA ๊ทธ๋ฆฌ๊ณ
EXTERNAL ์ค์ ํ๋๋ก ํ์ํ ์ ์๋ค.
JDBC โ Connection commit()๊ณผ rollback()๋ฉ์๋๋ฅผ ํตํด ํธ๋์ญ์
๋ฅผ ์ ์ดํ๊ธฐ ์ํ JDBC๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
JTA โ ์ด ํธ๋์ญ์
๊ด๋ฆฌ์๋ SQL Maps๊ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ํธ๋์ญ์
์์์ ํฌํจํ๋ ๋์ฑ๋ ๋์ ๋ฒ์์ ํธ๋
์ญ์
์ ํฌํจํ๋๋ก ํ๋ JTA์ ์ญํธ๋์ญ์
๋ฅผ ์ฌ์ฉํ๋ค. ์ด ์ค์ ์ JNDI์์์ผ๋ก๋ถํฐ ์ฌ์ฉ์ ํธ๋์ญ์
์ ์์น์ํค๊ธฐ
์ํ UserTransaction ์์ฑ๊ฐ์ ์๊ตฌํ๋ค. JNDI๋ฐ์ดํฐ์์ค์์ ๋ ๋ค์์ ์ค์ ์์ ์์ ๋ณด๋ผ.
EXTERNAL โ ์ด๊ฒ์ ๋น์ ์์ ์ด ํธ๋์ญ์
์ ๊ด๋ฆฌํ๋๋ก ํ๋ค. ๋น์ ์ ์ฌ์ ํ ๋ฐ์ดํฐ์์ค๋ฅผ ์ค์ ํ ์ ์์ง๋ง ํ
๋ ์์ํฌ ์๋ช
์ฃผ๊ธฐ์ ๋ถ๋ถ์ฒ๋ผ ํธ๋์ญ์
์ด ์ปค๋ฐ๋๊ฑฐ๋ ๋กค๋ฐฑ๋์ง ์๋๋ค. ์ด๊ฒ์ ๋น์ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ถ๋ถ์ด ์ธ
๋ถ์ ์ผ๋ก SQL Maps ํธ๋์ญ์
์ ๊ด๋ฆฌํด์ผ ํ๋ค๋๊ฒ์ด๋ค. ์ด ์
ํ
์ ๋น-ํธ๋์ญ์
(์๋ฅผ ๋ค๋ฉด ์ฝ๊ธฐ์ ์ฉ) ๋ฐ์ดํฐ๋ฒ ์ด
์ค์ ์ ์ฉํ๋ค.
<dataSource> ์์
ํธ๋์ญ์
๊ด๋ฆฌ์ ์ค์ ์ ํฌํจ๋ ๋ถ๋ถ์ dataSource ์์์ด๊ณ SQL Maps๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๋ฐ์ดํฐ์์ค๋ฅผ ์ค์ ํ๊ธฐ ์ํ ์์ฑ
๊ฐ์ ์งํฉ์ด๋ค. ์ฌ๊ธฐ์ ํ๋ ์์ํฌ์์ ์ ๊ณต๋๋ 3๊ฐ์ง ๋ฐ์ดํฐ์์คํ์
์ด ์์ง๋ง ๋น์ ์ ๋น์ ๋ง์ ๋ฐ์ดํฐ์์ค๋ฅผ ์ฌ์ฉํ ์
๋ ์๋ค. ํฌํจ๋ DataSourceFactory๊ตฌํ์ ๋ค์์ ์์ธํ๊ฒ ๋
ผ์๊ฐ ๋ ๊ฒ์ด๊ณ ๊ฐ๊ฐ์ ์ํด ์ ๊ณต๋๋ ์ค์ ์ ์๋ ์์ ๋ฅผ ๋ณด
๋ผ.
SimpleDataSourceFactory
SimpleDataSource ๋ ๋ฐ์ดํฐ์์ค๋ฅผ ์ ๊ณตํ๋ ์ปจํ
์ด๋๊ฐ ์๋ ๊ฒฝ์ฐ์ connection์ ์ ๊ณตํ๊ธฐ ์ํด ๊ธฐ๋ณธ์ ์ผ๋ก
ํ๋ง(pooling) ๋ฐ์ดํฐ์์ค ๊ตฌํ์ ์ ๊ณตํ๋ค. ์ด๊ฒ์ iBATIS SimpleDataSource connectionํ๋ง์ ๊ธฐ์ด๋ก ํ๋ค.
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="org.postgresql.Driver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:postgresql://server:5432/dbname"/>
<property name="JDBC.Username" value="user"/>
<property name="JDBC.Password" value="password"/>
<!--OPTIONAL PROPERTIES BELOW -->
<property name="Pool.MaximumActiveConnections" value="10"/>
8
- 9. <property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="10000"/>
<property name="Pool.PingQuery" value="select * from dual"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan" value="0"/>
<property name="Pool.PingConnectionsNotUsedFor" value="0"/>
</dataSource>
</transactionManager>
DbcpDataSourceFactory
์ด ๊ตฌํ๋ฌผ์ DataSource API๋ฅผ ํตํด connectionํ๋ง์๋น์ค๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด Jakarta DBCP (Database
Connection Pool)์ ์ฌ์ฉํ๋ค. ์ด DataSource๋ ์ ํ๋ฆฌ์ผ์ด์
/์น ์ปจํ
์ด๋๊ฐ DataSource๊ตฌํ๋ฌผ์ ์ ๊ณตํ์ง ๋ชป
ํ๊ฑฐ๋ ๋น์ ์ด standalone์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ๋ํ ๋ ์ด์์ ์ด๋ค. DbcpDataSourceFactory ๋ฅผ ์ํด ๋ช
์ํด์ผ ํ
๋ ์ค์ ํ๋ผ๋ฏธํฐ์ ์์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<transactionManager type="JDBC">
<dataSource type="DBCP">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<!--OPTIONAL PROPERTIES BELOW -->
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumWait" value="60000"/>
<!--Use of the validation query can be problematic. If you have difficulty, try without it. -->
<property name="Pool.ValidationQuery" value="select * from ACCOUNT"/>
<property name="Pool.LogAbandoned" value="false"/>
<property name="Pool.RemoveAbandoned" value="false"/>
<property name="Pool.RemoveAbandonedTimeout" value="50000"/>
<property name="Driver.DriverSpecificProperty" value="SomeValue"/>
</datasource>
</transactionManager>
JndiDataSourceFactory
์ด ๊ตฌํ๋ฌผ์ ์ ํ๋ฆฌ์ผ์ด์
์ปจํ
์ด๋๋ด JNDI์ปจํ
์คํธ๋ก๋ถํฐ DataSource๊ตฌํ๋ฌผ์ ๊ฐ์ ธ์์ผ ํ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์ ํ์
์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ๋ฅผ ์ฌ์ฉ์ค์ด๊ณ ์ปจํ
์ด๋๊ด๋ฆฌ connection pool ๊ทธ๋ฆฌ๊ณ ์ ๊ณต๋๋ DataSource๊ตฌํ๋ฌผ์ด ์์ ๋
์ฌ์ฉํ๋ค. JDBC DataSource๊ตฌํ๋ฌผ์ ์ ๊ทผํ๊ธฐ ์ํ ํ์ค์ ์ธ ๋ฐฉ๋ฒ์ JNDI์ปจํ
์คํธ๋ฅผ ํตํ๋๊ฒ์ด๋ค.
JndiDataSourceFactory ๋ JNDI๋ฅผ ํตํด DataSource์ ์ ๊ทผํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋ฐ์ดํฐ์์ค๋ด์ ๋ช
์๋์ด์ผ ํ๋
์ค์ ํ๋ผ๋ฏธํฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<transactionManager type="JDBC" >
<dataSource type="JNDI">
<property name="DBJndiContext"
value="java:comp/env/jdbc/jpetstore"/>
</dataSource>
</transactionManager>
์ ์ค์ ์ ์ผ๋ฐ์ ์ธ JDBCํธ๋์ญ์
๊ด๋ฆฌ์ง๋ง ์ปจํ
์ด๋๊ฐ ์์์ ๊ด๋ฆฌํ๋ค. ๋น์ ์ ๋ค์์ฒ๋ผ ์ ์ญ(global)ํธ๋์ญ
์
์ ์ค์ ํ๊ธธ ์ํ ์๋ ์๋ค.
<transactionManager type="JTA" >
<property name="UserTransaction" value="java:/ctx/con/UserTransaction"/>
<dataSource type="JNDI">
9
- 10. <property name="DBJndiContext"
value="java:comp/env/jdbc/jpetstore"/>
</dataSource>
</transactionManager>
UserTransaction ์ธ์คํด์ค๊ฐ ๋ฐ๊ฒฌ๋ ์ ์๋ JNDI์์น๋ฅผ ๊ฐ์งํค๋ UserTransaction ๊ฐ์ ์ฃผ์ํ๋ผ. ์ข๋ ๋์ ๋ฒ์
์ ํธ๋์ญ์
์ ๊ฐ์ง๋ SQL Maps๊ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํธ๋์ญ์
์์์ ํฌํจํ๊ธฐ ์ํด์๋ JTAํธ๋์ญ์
๊ด๋ฆฌ๊ฐ
์๊ตฌ๋๋ค.
<sqlMap> ์์
sqlMap ์์๋ ๋ช
์์ ์ผ๋ก SQL Map์ด๋ ๋ค๋ฅธ SQL Map์ค์ ํ์ผ์ ํฌํจํ ๋ ์ฌ์ฉํ๋ค. SqlMapClient์ธ์คํด์ค์ ์ํด ์ฌ
์ฉ๋๋ ๊ฐ๊ฐ์ SQL Map XMLํ์ผ์ ๋ฐ๋์ ์ ์ธ๋์ด์ผ ํ๋ค. SQL Map XMLํ์ผ์ ํด๋์คํจ์ค๋ URL๋ก๋ถํฐ ์คํธ๋ฆผ
(stream)์์์ฒ๋ผ ๋ก๋ ๋ ๊ฒ์ด๋ค. ๋น์ ์ SQL Maps๋ฅผ ๋ช
์ํด์ผ ํ๋ค. ๋ค์์ ๊ทธ์ ๋ํ ์์ด๋ค.
<!--CLASSPATH RESOURCES -->
<sqlMap resource="com/ibatis/examples/sql/Customer.xml" />
<sqlMap resource="com/ibatis/examples/sql/Account.xml" />
<sqlMap resource="com/ibatis/examples/sql/Product.xml" />
<!--URL RESOURCES -->
<sqlMap url="file:///c:/config/Customer.xml " />
<sqlMap url="file:///c:/config/Account.xml " />
<sqlMap url="file:///c:/config/Product.xml" />
๋ค์์ ๋ค์ํ ์น๊ฒฌ์ SQL Map XMLํ์ผ๋ค์ ๊ตฌ์กฐ์ ๋ํด์ ์์ ํ๋ค.
SQL Map XML ํ์ผ ( http://ibatis.apache.org/dtd/sql-
map-config-2.dtd)
์ ์์ ์์ ์ฐ๋ฆฌ๋ SQL Maps์ ๊ฐ์ฅ ๊ฐ๋จํ ํํ๋ฅผ ๋ณด์๋ค. SQL Map๋ฌธ์ ๊ตฌ์กฐ๋ด์ ์ฌ์ฉ๊ฐ๋ฅํ ๋ค๋ฅธ ์ต์
์ด ์๋ค. ์ข
๋ ๋ง์ ๊ธฐ๋ฅ์ ๊ฐ์ง๋ mapped statement์ ์์ ์ด๋ค.
<sqlMap id=โProductโ>
<cacheModel id=โproductCacheโ type=โLRUโ>
<flushInterval hours=โ24โ/>
<property name=โsizeโ value=โ1000โ />
</cacheModel>
<typeAlias alias=โproductโ type=โcom.ibatis.example.Productโ />
<parameterMap id=โproductParamโ class=โproductโ>
<parameter property=โidโ/>
</parameterMap>
<resultMap id=โproductResultโ class=โproductโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
</resultMap>
<select id=โgetProductโ parameterMap=โproductParamโ
resultMap=โproductResultโ cacheModel=โproduct-cacheโ>
select * from PRODUCT where PRD_ID = ?
</select>
</sqlMap>
10
- 11. ๋๋ฌด ๋ง์๊ฐ.? ๋น๋ก ํ๋ ์์ํฌ๊ฐ ๋น์ ์ ์ํด ๋ง์ ๊ฒ์ ํ๋๋ผ๋ ๊ฐ๋จํ select statement๋ฅผ ์ํด ๋๋ฌด ๋ง์ ์ถ๊ฐ์ ์ธ
์์
์ ํ๋๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ๊ฑฑ์ ํ์ง ๋ง๋ผ ๋ค์์ ์์ ๊ฒ์ ์ถ์๋ฒ์ ์ด๋ค.
<sqlMap id=โProductโ>
<select id=โgetProductโ parameterClass=โ com.ibatis.example.Productโ
resultClass=โcom.ibatis.example.Productโ>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #id#
</select>
</sqlMap>
์ง๊ธ SQL Map์ ํ์์ ์ธ ์ธก๋ฉด์์ ๋ณด๋ฉด ์ด statement๋ ์ ํํ๊ฒ ๊ฐ์ง๋ ์๋ค. ์ฆ ๋ช๊ฐ์ง ๋ค๋ฅธ์ ์ ๊ฐ์ง๋ค. ๋จผ์ ํ์์
statement๋ ์บ์ฌ๋ฅผ ๋ช
์ํ์ง ์์์ ๋งค๋ฒ์ ์์ฒญ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์ ์์ฒญํ๋ค. ๋๋ฒ์งธ ํ์์ statement๋ ์ฝ๊ฐ์ ๋ถํ
๋ฅผ ์ผ๊ธฐํ ์ ์๋ ํ๋ ์์ํฌ์ ์๋๋งตํ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค. ์ด์จ๋ ๋๊ฐ์ง statement ๋ชจ๋ ์๋ฐ์ฝ๋๋ก๋ถํฐ ์ ํํ๊ฒ ๊ฐ์ ๋ฐฉ
๋ฒ์ผ๋ก ์๋ํ์ง ์์๊ฒ์ด๋ค ๊ทธ๋ฆฌ๊ณ ๋น์ ์ ์ฒซ๋ฒ์งธ ์ข๋ ๊ฐ๋จํ ์๋ฃจ์
์ผ๋ก ์์ํ ๊ฒ์ด๊ณ ๋์ค์๋ ํ์ํ๋ฉด ์ข๋ ํฅ์๋ ๋งต
ํ์ผ๋ก ์ฎ๊ฒจ๊ฐ๊ฒ์ด๋ค. ๊ฐ์ฅ ๊ฐ๋จํ ์๋ฃจ์
์ด ๋ง์ ๊ฒฝ์ฐ์ ๊ฐ์ฅ ์ข์ ์ฐ์ต์ด๋ค.
ํ๋์ SQL Map XML ํ์ผ์ ๋ง์ ์บ์ฌ ๋ชจ๋ธ, ํ๋ผ๋ฏธํฐ ๋งตํ, result๋งตํ ๊ทธ๋ฆฌ๊ณ statement๋ฅผ ํฌํจํ ์ ์๋ค. ๋น์ ์
์ ํ๋ฆฌ์ผ์ด์
์ ์ํด statement์ maps๋ฅผ ์ ์คํ๊ฒ ๊ตฌ์ฑํ๋ผ.
๋งตํ๋(Mapped) Statements
SQL Maps ๊ฐ๋
์ ๋งตํ๋ statement์ ์ง์คํ๋ค. ๋งตํ๋ statement๋ ์ด๋ ํ SQL๋ฌธ์ ์ฌ์ฉํ ์๋ ์๊ณ ํ๋ผ๋ฏธํฐ maps(input)
๊ณผ result maps(output)๋ฅผ ๊ฐ์ง์ ์๋ค. ๋ง์ฝ ๊ฐ๋จํ ๊ฒฝ์ฐ๋ผ๋ฉด ๋งตํ๋ statement๋ ํ๋ผ๋ฏธํฐ์ result๋ฅผ ์ํ ํด๋์ค๋ก ์ง์ ์ค
์ ํ ์ ์๋ค. ๋งตํ๋ statement๋ ๋ฉ๋ชจ๋ฆฌ๋ด์ ์์ฐ๋ results๋ฅผ ์บ์ํ๊ธฐ ์ํด ์บ์ฌ ๋ชจ๋ธ์ ์ฌ์ฉํ๋๋ก ์ค์ ํ ์๋ ์๋ค.
<statement id=โstatementNameโ
[parameterClass=โsome.class.Nameโ]
[resultClass=โsome.class.Nameโ]
[parameterMap=โnameOfParameterMapโ]
[resultMap=โnameOfResultMapโ]
[cacheModel=โnameOfCacheโ]
>
select * from PRODUCT where PRD_ID = [?|#propertyName#]
order by [$simpleDynamic$]
</statement>
์ statement์์ [๊ดํธ] ๋ถ๋ถ์ ์ต์
์ด๊ณ ๋ช๋ช์ ๊ฒฝ์ฐ์๋ง ํผํฉํ ํ์๊ฐ ์๋ค.
<statement id=โinsertTestProductโ >
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (1, โShih Tzuโ)
</statement>
์ ์์ ๋ ๋ช
๋ฐฑํ๊ฒ ๋ฐ์ํ ๊บผ ๊ฐ์ง๋ ์๋ค. ์ด์จ๋ ์ด๊ฒ์ ๋น์ ์ด ์์์ SQL ๋ฌธ์ ์คํํ๊ธฐ ์ํด SQL Mapํ๋ ์์ํฌ๋ฅผ ์ฌ
์ฉํ๋ค๋ฉด ์ ์ฉํ ์ ์๋ค. ์ด์จ๋ ์ด๊ฒ์ ํ๋ผ๋ฏธํฐ Maps ์ Result Maps์ ์ฌ์ฉํ๋ ์๋ฐ๋น์ฆ ๋งตํ๊ธฐ๋ฅ์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ
ํ ๊ฒ์ด๋ค. ๋ค์์ ๋ค์ํ ์น์
์ ๊ตฌ์กฐ์ ์์ฑ, ๊ทธ๋ค์ด ์ด๋ป๊ฒ ๋งตํ๋ statement์ ์ํฅ์ ๋ผ์น๋์ง ์์ ํ๋ค.
Statement ํ์
<statement> ์์๋ ์ด๋ค ํ์
์ SQL ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ ์ผ๋ฐ์ ์ธ โcatch allโ statement์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ด๊ฒ์ ์ข๋ ๋ค
์ํ ํน์ฑ์ statement์์์ค ํ๋๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ข์ ์๊ฐ์ด๋ค. ์ข๋ ๋ค์ํ ํน์ฑ์ ์์๋ ์ข๋ ์ง๊ด์ ์ธ XML DTD๋ฅผ
์ ๊ณตํ๊ณ ๋๋๋ก ์ผ๋ฐ์ ์ธ <statement>์์๊ฐ ์ ๊ณตํ์ง ์๋ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋ค์์ ํ
์ด๋ธ์ statement์์
11
- 12. ์ ๊ทธ๋ค์ด ์ง์ํ๋ ์์ฑ๊ณผ ๊ธฐ๋ฅ์ ๋ชฉ๋กํ ํ๋ค.
Statement ์์ ์์ฑ ํ์ ์์ ๋ฉ์๋
<statement> id ๋ชจ๋ ๋์ ์์ insert
parameterClass update
resultClass delete
parameterMap ๋ชจ๋ ์ฟผ๋ฆฌ ๋ฉ์๋
resultMap
cacheModel
resultSetType
fetchSize
xmlResultName
remapResults
<insert> id ๋ชจ๋ ๋์ ์์ insert
parameterClass <selectKey> update
parameterMap delete
<update> id ๋ชจ๋ ๋์ ์์ insert
parameterClass update
parameterMap delete
<delete> id ๋ชจ๋ ๋์ ์์ insert
parameterClass update
parameterMap delete
<select> id ๋ชจ๋ ๋์ ์์ ๋ชจ๋ ์ฟผ๋ฆฌ ๋ฉ์๋
parameterClass
resultClass
parameterMap
resultMap
cacheModel
resultSetType
fetchSize
xmlResultName
remapResults
<procedure> id ๋ชจ๋ ๋์ ์์ insert
parameterClass update
resultClass delete
parameterMap ๋ชจ๋ ์ฟผ๋ฆฌ ๋ฉ์๋
resultMap
cacheModel
xmlResultName
remapResults
The SQL
SQL ์ map์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ ์ฐจ์งํ๋ค. ์ด๊ฒ์ ๋น์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ JDBC๋๋ผ์ด๋ฒ์ ์ ํฉํ ์ด๋ค SQL์ด ๋ ์ ์๋ค.
๋น์ ์ ๊ฐ๋ฅํ ์ด๋ค ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ณ ๋น์ ์ ๋๋ผ์ด๋ฒ๊ฐ ์ง์ํ๋ ํ ๋ค์ค statement์ ์ ๋ฌํ ์๋ ์๋ค. ๋น์ ์ด ํ๋
์ ๋ฌธ์์์ SQL๊ณผ XML์ ํผํฉํ๊ธฐ ๋๋ฌธ์ ํน์๋ฌธ์์ ์ถฉ๋์ด ์ ์ฌ์ ์ผ๋ก ์กด์ฌํ๋ค. ๋๋ถ๋ถ์ ๊ณตํต์ ์ธ ๊ฒ์ greater-than
๊ณผ less-than ๋ฌธ์๋ค์ด๋ค.(<>). ์ด๊ฒ๋ค์ SQL๋ฌธ์์ ๊ณตํต์ ์ผ๋ก ์๊ตฌ๋๊ณ XML์์๋ ์์ฝ์ด์ด๋ค. ๋น์ ์ SQL๋ฌธ์ ๋ค์ด๊ฐ ํ
์๊ฐ ์๋ ํน์ XML๋ฌธ์๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋จํ ํด๊ฒฐ๋ฒ์ด ์๋ค. ํ์ค์ ์ธ XML CDATA ์น์
์ ์ฌ์ฉํจ์ผ๋ก์จ ํน์๋ฌธ์์ ์ด
๋ค๊ฒ๋ ํ์ฑ๋์ง ์๊ณ ๋ฌธ์ ๋ ํด๊ฒฐ๋๋ค. ์๋ฅผ ๋ค๋ฉด
<statement id="getPersonsByAge" parameterClass=โintโ resultClass="examples.domain.Person">
<![CDATA[
SELECT *
FROM PERSON
WHERE AGE > #value#
]]>
</statement>
12
- 13. ์๋ ์์ฑ ํค
๋ง์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ
์ ๊ธฐ๋ณธํค(primay key)ํ๋์ ์๋์์ฑ์ ์ง์ํ๋ค. ์ด RDBMS์ ๊ธฐ๋ฅ์ ์ข
์ข
ํน์ ์
์ฒด์
์ข
์๋๋ค. SQL Map์ <insert>์์์ <selectKey>๋ฅผ ํตํด ์๋์์ฑํค๋ฅผ ์ง์ํ๋ค. ์ ์์ฑํค(pre-generated - ์ด๋ฅผ ํ
๋ฉด ์ค
๋ผํด)๊ณผ ํ์์ฑํค(post-generated - ์ด๋ฅผ ํ
๋ฉด MS-SQL ์๋ฒ) ๋ชจ๋ ์ง์ํ๋ค. ์ฌ๊ธฐ์ ๊ทธ ์์ ๊ฐ ์๋ค.
<!โOracle SEQUENCE Example -->
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
<selectKey resultClass="int">
SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
</selectKey>
insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)
values (#id#,#description#)
</insert>
<!โ Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
insert into PRODUCT (PRD_DESCRIPTION) values (#description#)
<selectKey resultClass="int">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
์ ์ฅ ํ๋ก์์
์ ์ฅ ํ๋ก์์ ๋ <procedure> statement์์๋ฅผ ํตํด ์ง์๋๋ค. ์ ์ฅ ํ๋ก์์ ๋ฅผ ์ถ๋ ฅ๋ฌผ ํ๋ผ๋ฏธํฐ์ ํจ๊ป ์ด๋ป๊ฒ ์ฌ์ฉํ
๋์ง ๋ค์ ์์ ์์ ๋ณด์ฌ์ค๋ค.
<parameterMap id="swapParameters" class="map" >
<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String"
mode="INOUT"/>
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters" >
{call swap_email_address (?, ?)}
</procedure>
์์ฒ๋ผ ํ๋ก์์ ๋ฅผ ํธ์ถํ๋ ๊ฒ์ ํ๋ผ๋ฏธํฐ ๊ฐ์ฒด(map)๋ด์์ ๋๊ฐ์ ์นผ๋ผ์ฌ์ด์ ๋๊ฐ์ ์ด๋ฉ์ผ์ฃผ์๋ฅผ ๊ต์ฒดํ๋๊ฒ์ด๋ค. ํ
๋ผ๋ฏธํฐ ๊ฐ์ฒด๋ ํ๋ผ๋ฏธํฐ ๋งตํ์ mode์์ฑ๊ฐ์ด โINOUTโ๋๋ โOUTโ์ผ ๊ฒฝ์ฐ์๋ง ๋ณ๊ฒฝ๋๋ค. ๋ค๋ฅธ ๊ฒฝ์ฐ๋ผ๋ฉด ๋ณ๊ฒฝ๋์ง ์๊ณ ๋จ๋
๋ค. ๋ช
๋ฐฑํ ๋ถ๋ณ์ ํ๋ผ๋ฏธํฐ ๊ฐ์ฒด(์ด๋ฅผ ํ
๋ฉด String)๋ ๋ณ๊ฒฝํ ์ ์๋ค.
์ฃผ์! ์ธ์ ๋ ํ์ค์ ์ธ JDBC์ ์ฅ ํ๋ก์์ ๋ฅผ ์ฌ์ฉํ๋๋ก ํ๋ผ. ์ข๋ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ณด๊ธฐ ์ํด์๋ JDBC CallableStatement๋ฌธ
์๋ฅผ ๋ณด๋ผ.
parameterClass
parameterClass ์์ฑ๊ฐ์ ์๋ฐํด๋์ค์ ์ ์ฒด๊ฒฝ๋ก๋ฅผ ํฌํจ(์๋ฅผ ๋ค๋ฉด ํจํค์ง๋ฅผ ํฌํจํ)ํ ์ด๋ฆ์ด๋ค. parameterClass ์์ฑ์ ์ต
์
์ด์ง๋ง ์ฌ์ฉ์ด ๊ต์ฅํ ์ถ์ฒ๋๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ ํ๋ ์์ํฌ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋งํผ statement์ ์ ๋ฌํ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์
ํํ๋๋ฐ ์ฌ์ฉ๋๋ค. ๋ง์ฝ ๋น์ ์ด parameterMap์ ์ฌ์ฉํ๋ค๋ฉด parameterClass์์ฑ์ ์ฌ์ฉํ ํ์๊ฐ ์๋ค. ์๋ฅผ ๋ค๋ฉด ๋น์ ์ด
ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ๊ธฐ ์ํ โexamples.domain.Productโ ํ์
์ ๊ฐ์ฒด๋ฅผ ํ๋ฝํ๊ธธ ์ํ๋ค๋ฉด ๋น์ ์ ๋ค์์ฒ๋ผ ํ ์ ์์๊ฒ์ด๋ค.
<statement id=โstatementNameโ parameterClass=โ examples.domain.Productโ>
13
- 14. insert into PRODUCT values (#id#, #description#, #price#)
</statement>
์ค์: ๋น๋ก ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ํ ์ต์
์ด์ง๋ง ์ด๊ฒ์ ์ธ์ ๋ ํ๋ผ๋ฏธํฐ ํด๋์ค๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋งค์ฐ ์ถ์ฒ๋๋ ์ฌํญ
์ด๋ค(๋ฌผ๋ก ์๊ตฌ๋๋ ํ๋ผ๋ฏธํฐ๊ฐ ์๋๋ผ๋). ํ๋ ์์ํฌ๊ฐ ๋จผ์ ํ์
์ ์๋ค๋ฉด ์ค์ค๋ก ์ต์ ํ๋ฅ๋ ฅ์ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋น์ ์
ํด๋์ค๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ์ข๋ ๋์ ์ฑ๋ฅ์ ๋ฌ์ฑํ ์ ์๋ค.
๋ช
์๋ parameterClass ์์ด ์ ํธํ๋ ์์ฑ(get/set๋ฉ์๋)์ ๊ฐ์ง๋ ์๋ฐ๋น์ฆ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์๊ฒ์ด๊ณ ์ด๋ ์์น์์
๋งค์ฐ ์ ์ฉํ๋ค.
parameterMap
parameterMap ์์ฑ๊ฐ์ ๋ช
์๋(๋ฐ์ ๊ฒฝ์ฐ์ฒ๋ผ) parameterMap์์์ ์ด๋ฆ์ด๋ค. parameterMap์์ฑ์ parameterClass ์์ฑ
๊ณผ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ์ ์ด์ต์ด ๋๋๋ก ์ฌ์ฉ๋๋ค. XML์ ๊น๋ํจ๊ณผ ์ผ๊ด์ฑ์ด ๋น์ ์ ๊ฑฑ์ ์ด๊ฑฐ๋ ๋น์ ์ด ์ข๋ ์์ธํ
parameterMap(์ด๋ฅผ ํ
๋ฉด ์ ์ฅํ๋ก์์ )์ด ํ์ํ๋ค๋ฉด ์ด๊ฒ์ ์ข์ ์ ๊ทผ๋ฒ์ด๋ค.
์ฃผ์! ๋์ ์ผ๋ก ๋งตํ๋ statement๋ ๋จ์ง ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ง ์ง์ํ๊ณ ํ๋ผ๋ฏธํฐ map๊ณผ๋ ์๋ํ์ง ์๋๋ค.
parameterMap์ ์๊ฐ์ JDBC PreparedStatement์ ๊ฐ ํ ํฐ๊ณผ ๋งค์น๋๋ ์ ๋ ฌ๋ ํ๋ผ๋ฏธํฐ ๋ชฉ๋ก์ ๋ช
์ํ๋ค.
์๋ฅผ๋ค๋ฉด:
<parameterMap id=โinsert-product-paramโ class=โcom.domain.Productโ>
<parameter property=โidโ/>
<parameter property=โdescriptionโ/>
</parameterMap>
<statement id=โinsertProductโ parameterMap=โinsert-product-paramโ>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
์์ ์์ ์์, ํ๋ผ๋ฏธํฐ map์ SQL๋ฌธ์์ ๊ฐํ ํฐ(โ?โ)์ ๋งค์น๋๊ณ ์ ๋ ฌ๋๋ ๋๊ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ ํ๋ค. ๊ทธ๋์ ์ฒซ๋ฒ์งธ
โ?โ๋ โidโ ์์ฑ๊ฐ์ ๋์ฒด๋๊ณ ๋๋ฒ์งธ๋ โdescriptionโ ์์ฑ๊ฐ์ ๋์ฒด๋๋ค. ํ๋ผ๋ฏธํฐ map๊ณผ ๊ทธ๋ค์ ์ต์
์ ์ด ๋ฌธ์ ๋์ค์ ์ข
๋ ๋ค์ํ๊ฒ ์์ ๋ ๊ฒ์ด๋ค.
์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ์ ๋น ๋ฅธ ์ธ๊ธ
์ด ๋ฌธ์์ ๋์ค์ ์ ๊ณต๋๋ ์ข๋ ์์ธํ๋ ์ค๋ช
์๋ ๋ถ๊ตฌํ๊ณ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ์ ๋ํ ๋น ๋ฅธ ์ธ๊ธ์ ํ๋ค. ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋
๋งตํ๋ statement๋ด๋ถ์์ ์ฌ์ฉ๋ ์ ์๋ค. ์๋ฅผ ๋ค๋ฉด :
<statement id=โinsertProductโ >
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id#, #description#);
</statement>
์ ์์ ์์ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ #id# ์ #description# ์ด๋ค. ๊ฐ๊ฐ์ statementํ๋ผ๋ฏธํฐ๋ฅผ ๋์ฒดํ๋ ์๋ฐ๋น์ฆ ์์ฑ์ ํํํ
๋ค. Productํด๋์ค๋ ํฌํจ๋ ํ๋ผํผํฐ ํ ํฐ์ด ์์นํด ์๋ statement๋ด์ ์์นํ๋ ๊ฐ์ ์ํด ์ฝ๊ฒ ๋๋ id ์ description ํ
๋ผํผํฐ์ ๊ฐ์ง๋ค. id=5 ์ description=โdogโ ๋ฅผ ๊ฐ์ง๋ Product๋ฅผ ๋๊ฒจ๋ฐ์ statement๋ ๋ค์์ฒ๋ผ ์ํ๋๋ค.
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (5, โdogโ);
resultClass
resultClass์์ฑ๊ฐ์ ์๋ฐํด๋์ค์ ์ ์ฒด๊ฒฝ๋ก๋ฅผ ํฌํจ(์๋ฅผ ๋ค๋ฉด ํจํค์ง๋ฅผ ํฌํจํ)ํ ์ด๋ฆ์ด๋ค. resultClass์์ฑ์ ์ฐ๋ฆฌ์๊ฒ
ResultSetMetaData์ ๊ธฐ๋ฐํ JDBC ResultSet์ ์๋๋งตํ๋๋ ํด๋์ค๋ฅผ ๋ช
์ํ๋๋ก ํ๋ค. ์๋ฐ๋น์ฆ์ ํ๋ผํผํฐ์ ResultSet์
์นผ๋ผ์ด ๋งค์น๋ ๋๋ง๋ค ํ๋ผํผํฐ๋ ์นผ๋ผ๊ฐ๊ณผ ํจ๊ป ์์ฑ๋๋ค. ์ด๊ฒ์ ๋งค์ฐ ์งง๊ณ ๋ฌ์ฝคํ๊ฒ ๋งตํ๋ statement๋ฅผ ์ฟผ๋ฆฌํ๋ค. ์๋ฅผ
14
- 15. ๋ค๋ฉด :
<statement id="getPerson" parameterClass=โintโ resultClass="examples.domain.Person">
SELECT
PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</statement>
์์ ์์ ์์ Personํด๋์ค๋ id, firstName, lastName, birthDate, weightInKilograms, heightInMeters๋ฅผ ํฌํจํ๋ ํ๋ผํผํฐ
๋ฅผ ๊ฐ์ง๋ค. ์นผ๋ผ๋ณ์นญ๊ณผ ํจ๊ป ๋์๋๋ ๊ฐ๊ฐ์ SQL select๋ฌธ์ ์ํด ์์ ๋๋ค. ์นผ๋ผ๋ณ์นญ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์นผ๋ผ์ด๋ฆ์ด ๋งค์น๋์ง
์์๋๋ง ์๊ตฌ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ ์๊ตฌ๋์ง ์๋๋ค. ์คํ๋์์๋ Person๊ฐ์ฒด๋ ํ๋ผํผํฐ์ด๋ฆ๊ณผ ์นผ๋ผ๋ช
์ ๊ธฐ๋ฐํด์ ์ด๊ธฐํ
๋๊ธฐ ์ํด ๋งตํ๋๋ result set์ผ๋ก๋ถํฐ ์ด๊ธฐํ๋๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
resultClass์ผ๋ก ์๋๋งตํํ๋๋ฐ๋ ๋ช ๊ฐ์ง ์ ํ์ ์ด ์๋ค. ์ถ๋ ฅ์นผ๋ผ์ ํ์
์ ๋ช
์ํ๋ ๋ฐฉ๋ฒ์ ์๋ค. ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ์๋์
์ผ๋ก ๋ก๋ํ๋๋ฐฉ๋ฒ์ด ์๊ณ ResultSetMetaData์ ์ ๊ทผํ๋๋ฐ ํ์ํ ์ ๊ทผ๋ฒ๋ด์์ ํ์ฐฎ์ ์ฑ๋ฅ๊ฒฐ๊ณผ๊ฐ ์๋ค. ์ด ์ ํ์ ๋ชจ๋
๋ ๋ช
์์ ์ธ resultMap๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๊ทน๋ณตํ ์ ์๋ค. Result maps๋ ์ด ๋ฌธ์ ๋์ค์ ์ข๋ ์์ธํ๊ฒ ๋ค๋ฃจ์ด์ง๊ฒ์ด๋ค.
resultMap
resultMapํ๋ผํผํฐ๋ ์ข๋ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๊ณ ์ดํดํ๊ธฐ ์ํด ๊ฐ์ฅ ์ค์ํ ์์ฑ์ค์ ํ๋์ด๋ค. ์ด resultMap์์ฑ๊ฐ์
๋ช
์๋ resultMap์์์ ์ด๋ฆ์ด๋ค. resultMap์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋น์ ์๊ฒ result set์ผ๋ก๋ถํฐ ๋ฐ์ดํฐ์ ์นผ๋ผ์ ๋งตํ๋
๋ ํ๋ผํผํฐ๋ฅผ ์ด๋ป๊ฒ ๊บผ๋ด๋์ง ์ ์ดํ๋๋ก ํ๋ค. resultClass์์ฑ์ ์ฌ์ฉํ๋ ์๋๋งตํ์ ๊ทผ๋ฒ๊ณผ๋ ๋ฌ๋ฆฌ resultMap๋ ๋น
์ ์๊ฒ ์นผ๋ผํ์
์ ๋ช
์ํ๊ณ null๊ฐ์ ๋์ฒด ๊ทธ๋ฆฌ๊ณ ๋ณตํฉ ํ๋ผํผํฐ๋งตํ(๋ค๋ฅธ ์๋ฐ๋น์ฆ, Collections ๊ทธ๋ฆฌ๊ณ ์์ํ์
๋ํผ)
์ ํ๋ฝํ๋ค.
resultMap ๊ตฌ์กฐ์ ๋ชจ๋ ์์ธ์ ๋ณด๋ ์ด ๋ฌธ์ ๋์ค์ ์ค๋ช
๋๋ค. ํ์ง๋ง ๋ค์์ ์์ ๋ resultMap๊ฐ ์ด๋ป๊ฒ statement์ ๊ด๋ จ
๋์๋์ง ๋ณด์ฌ์ค๋ค.
<resultMap id=โget-product-resultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
</resultMap>
<statement id=โgetProductโ resultMap=โget-product-resultโ>
select * from PRODUCT
</statement>
์ ์์ ์์ SQL์ฟผ๋ฆฌ๋ก๋ถํฐ ResultSet์ resultMap์ ์๋ฅผ ์ฌ์ฉํด์ Product์ธ์คํด์ค์ ๋งตํํ ๊ฒ์ด๋ค. resultMap์ โidโํ
๋ผํผํฐ๊ฐ โPRD_IDโ์นผ๋ผ๊ณผ โPRD_DESCRIPTIONโ์นผ๋ผ์ ์ํด ์์ฑ๋๋ โdescriptionโํ๋ผํผํฐ์ ์ํด ์์ฑ๋ ๊ฒ์ด๋ค. โselect
*โ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ง์๋๋ค๋ ๊ฒ์ ์ฃผ์ํ๋ผ. ResultSet๋ด ๋ฐํ์นผ๋ผ ๋ชจ๋์ ๋งตํํ ํ์๋ ์๋ค.
cacheModel
cacheModel์์ฑ๊ฐ์ ์ ์๋ cacheModel์์์ ์ด๋ฆ์ด๋ค. cacheModel์ ์ฟผ๋ฆฌ๊ฐ ๋งตํ๋ statement๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์บ์ฌ๋ฅผ
์์ ํ๋๋ฐ ์ฌ์ฉ๋๋ค. ๊ฐ๊ฐ์ ์ฟผ๋ฆฌ๋งตํ statement๋ ๋ค๋ฅธ cacheModel์ด๋ ๊ฐ์๊ฒ์ ์ฌ์ฉํ ์ ์๋ค. cacheModel์์์ ๊ทธ๊ฒ
์ ์์ฑ์ ๋ํ ๋ชจ๋ ์์ธ์ค๋ช
์ ๋์ค์ ์ธ๊ธ๋๋ค. ๋ค์ ์์ ๋ ์ด๋ป๊ฒ statement์ ๊ด๋ จ๋๋์ง ๋ณด์ฌ์ค๋ค.
<cacheModel id="product-cache" imlementation="LRU">
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
15
- 16. <property name=โsizeโ value=โ1000โ />
</cacheModel>
<statement id=โgetProductListโ parameterClass=โintโ cacheModel=โproduct-cacheโ>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
์ ์์ ์์ ์บ์ฌ๋ WEAK์ฐธ์กฐํ์
์ ์ฌ์ฉํ๋ products๋ฅผ ์ํด ์ ์๋๊ณ 24์๊ฐ๋ง๋ค ๋๋ ๊ด๋ จ๋ update๋ฌธ์ด ์ํ๋ ๋
๋ง๋ค ์ง์์ง๋ค(flush) .
xmlResultName
mapping result๋ฅผ XML๋ฌธ์๋ก ์ง์ ์ ์ผ๋ก ๋ง๋ค ๋ xmlResultName์ ๊ฐ์ XML๋ฌธ์์ ๊ฐ์ฅ ์์ ์์์ ์ด๋ฆ์ด ๋ ๊ฒ์ด๋ค. ์
๋ฅผ ๋ค๋ฉด :
<select id="getPerson" parameterClass=โintโ resultClass="xml" xmlResultName=โpersonโ>
SELECT
PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON WHERE PER_ID = #value#
</select>
์ select statement๋ ๋ค์ ๊ตฌ์กฐ์ XML๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒ์ด๋ค.
<person>
<id>1</id>
<firstName>Clinton</firstName>
<lastName>Begin</lastName>
<birthDate>1900-01-01</birthDate>
<weightInKilograms>89</weightInKilograms>
<heightInMeters>1.77</heightInMeters>
</person>
remapResults
remapResults ์์ฑ์ <statement>, <select>, ๊ทธ๋ฆฌ๊ณ <procedure> ์์ ์ฌ์ฉ๊ฐ๋ฅํ๋ค. ์ด๊ฒ์ ์ ํ์ ์ธ ์์ฑ์ด๊ณ ๋ํดํธ๋
false์ด๋ค.
remapResults์์ฑ์ ์ฟผ๋ฆฌ๊ฐ ๋ฐํ ์นผ๋ผ์ ๋ค์ํ ์ธํธ๋ฅผ ๊ฐ์ง๋ true์
ํ
๋์ด์ผ๋ง ํ๋ค. ๋ค์ ์ฟผ๋ฆฌ๋ฅผ ๋ณด์.
SELECT $fieldList$
FROM table
์ด์ ์์ ์์ ์นผ๋ผ์ ๋ชฉ๋ก์ ํ
์ด๋ธ์ด ์ธ์ ๋ ๊ฐ๋๋ผ๋ ๋์ ์ด๋ค.
SELECT *
FROM $sometable$
์ด์ ์์ ์์ ํ
์ด๋ธ์ ๋ค๋ฅผ์ ์๋ค. Select์ ์ * ์ฌ์ฉ๋๋ฌธ์, ๊ฒฐ๊ณผ์ ์ธ ์นผ๋ผ์ด๋ฆ์ ๋ค๋ฅผ์ ์๋ค. ๋์ ์์๋ ํ๋์ ์ฟผ๋ฆฌ
์ํ์์ ๋ค์ ์ํ๊น์ง ๋ณ๊ฒฝํ๊ธฐ ์ํ ๋ชฉ๋ก์ ์ผ๊ธฐํ ์์๋ค.
resultset๋ฉํ๋ฐ์ดํ๋ฅผ ์๊ณ /ํ๋จํ๊ธฐ ์ํ ์ค๋ฒํค๋๊ฐ ๋ช
๋ฐฑํ์ง ์๊ธฐ ๋๋ฌธ์, iBATIS๋ ๋ง์ง๋ง ์ฟผ๋ฆฌ ์ํ์ ๋ฐํ๋ ๊ฒ๋ง์ ๊ธฐ
์ตํ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์ ์์ ์ ๋น์ทํ ์ํฉ์์ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํจ๋ค.
16
- 17. ๋ง์ฝ ๋ฐํ ์นผ๋ผ์ด ๋ณ๊ฒฝ๋๋ค๋ฉด, remapResults๋ฅผ true๋ก ์
ํ
ํ๋ผ. ๊ทธ๋ ์ง ์๋ค๋ฉด ๋ฉํ๋ฐ์ดํ ๊ฒ์์ ์ค๋ฒํค๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด
remapResults๋ฅผ false๋ก ์
ํ
ํ๋ผ.
resultSetType
SQL๊ตฌ๋ฌธ์ resultSetType์ ๋ช
์ํ๊ธฐ ์ํด, ๋ค์์ ์ฌ์ฉํ ์ ์๋ค.
โข FORWARD_ONLY: ์ปค์๋ ์์ชฝ์ผ๋ก๋ง ์ด๋ํ๋ค.
โข SCROLL_INSENSITIVE: ์ปค์๋ ์คํฌ๋กค๊ฐ๋ฅํ์ง๋ง ๋ค๋ฅธ๊ฒ์ ์ํ ๋ณ๊ฒฝ์๋ ๋๊ฐ ๋ฏผ๊ฐํ์ง ์๋ค.
โข SCROLL_SENSITIVE: ์ปค์๋ ์คํฌ๋กค๊ฐ๋ฅํ๊ณ ๋ค๋ฅธ๊ฒ์ ์ํ ๋ณ๊ฒฝ์ ๋๊ฐ ๋ฏผ๊ฐํ๋ค.
resultSetType์ ๋๊ฐ ์๊ตฌ๋์ง ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ก ๋ค๋ฅธ JDBC๋๋ผ์ด๋ฒ๋ ๊ฐ์ resultSetType์
ํ
์ ์ฌ์ฉํ๋๋ผ๋ ๋ค๋ฅด๊ฒ ํ
๋ํ ๊ฒ์ด๋ค. (์ด๋ฅผํ
๋ฉด. Oracle์ SCROLL_SENSITIVE๋ฅผ ์ง์ํ์ง ์๋๋ค.).
fetchSize
SQL๊ตฌ๋ฌธ์ fetchSize๋ฅผ ์
ํ
ํ๋ ๊ฒ์ ์ํ๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ JDBC๋๋ผ์ด๋ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ๋ก์ ์๋ณต์ ์ค์ด๊ธฐ ์ํด
prefetching ํํธ๋ฅผ ์ ๊ณตํ๋ค.
ํ๋ผ๋ฏธํฐ Maps ์ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ
๋น์ ์ด ์์์ ๋ณธ๊ฒ์ฒ๋ผ parameterMap๋ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ฅผ statement์ ํ๋ผํผํฐ์ ๋งตํ์ํค๋ ์์
์ ์ํํ๋ค. ๋น
๋ก parameterMaps๊ฐ ์ธ๋ถํํ๋ด์ ๋๋ฌผ๊ฒ ๋ฐ์ํ๋๋ผ๋ ๊ทธ๊ฒ๋ค์ด ๋น์ ์๊ฒ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ฅผ ์ดํดํ๋๋ก ๋์์ค๋ค๋
๊ฒ์ ์ดํดํ๋ผ.
<parameterMap id=โparameterMapNameโ [class=โcom.domain.Productโ]>
<parameter property =โpropertyNameโ [jdbcType=โVARCHARโ] [javaType=โstringโ]
[nullValue=โNUMERICโ] [null=โ-9999999โ] [typeName=โ{REF or user-defined type}โ/>
<parameter โฆโฆ />
<parameter โฆโฆ />
</parameterMap>
[๊ดํธ]๋ด์ ๋ถ๋ถ์ ์ต์
์ด๋ค. parameterMap๋ ์ค์ค๋ก๋ statement๊ฐ ๊ทธ๊ฒ์ ์ฐธ์กฐํ ๋ ์ฌ์ฉํ๋ ๊ตฌ๋ถ์๋ก์จ ๋จ์ง id์์ฑ
๋ง ํ์ํ๋ค. Class์์ฑ์ ์ต์
์ด์ง๋ง ํฌ๊ฒ ์ฌ์ฉ์ด ์ถ์ฒ๋๋ ๊ฒ์ด๋ค. Statement์ parameterClass์์ฑ๊ณผ ์ ์ฌํ๊ฒ class์
์ฑ์ ํ๋ ์์ํฌ๊ฐ ์ฑ๋ฅ์ ์ํด ์์ง์ ์ต์ ํํ๋ ๊ฒ๋งํผ ๋ค์ด์ค๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฒดํฌํ๋๋ก ํ๋ค.
<parameter> ์์
parameterMap์ statement์ ํ๋ผ๋ฏธํฐ์ ์ง์ ๋งตํํ๋ ํ๋ผ๋ฏธํฐ๋งตํ์ ์ด๋ค ์ซ์๋ฅผ ํฌํจํ๋ค. ๋ค์์ ์ผ๋ถ ์น์
์
property ์์์ ์์ฑ์ ์์ ํ๋ค.
property
ํ๋ผ๋ฏธํฐ map์ property์์ฑ์ ๋งตํ๋ statement์ ์ ๋ฌ๋๋ ํ๋ผ๋ฏธํฐ๊ฐ์ฒด์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ(get๋ฉ์๋)์ ์ด๋ฆ์ด๋ค.
๊ทธ ์ด๋ฆ์ statement๋ด์ ํ์ํ ํ์์ ์์กดํ๋๊ฒ๋ณด๋ค ์ข๋ ์ฌ์ฉ๋ ์ ์๋ค.
jdbcType
jdbcType์์ฑ์ ์ด ํ๋ผํผํฐ์ ์ํด ์
ํ
๋๋ ํ๋ผ๋ฏธํฐ์ ์นผ๋ผํ์
์ ๋ช
์์ ์ผ๋ก ์ ์ํ๋๋ฐ ์ฌ์ฉ๋๋ค. ๋ช๋ช JDBC๋๋ผ์ด
๋ฒ๋ ๋ช
์์ ์ธ ๋๋ผ์ด๋ฒ ์นผ๋ผํ์
์ ๋ถ๋ฅด๋ ๊ฒ ์์ด ์ด๋ค ์๋์ ์ํด ์นผ๋ผ์ ํ์
์ ํ์ธํ ์ ์๋ค. ์ด๊ฒ์ ์๋ฒฝํ ์์ ๋
PreparedStatement.setNull(int parameterIndex, int sqlType) ๋ฉ์๋์ด๋ค. ์ด ๋ฉ์๋๋ ์ ์ํ๊ธฐ ์ํ ํ์
์ ์๊ตฌํ๋ค. ๋ช
๋ช ๋๋ผ์ด๋ฒ๋ ๊ฐ๋จํ๊ฒ Types.OTHER ๋๋ Types.NULL์ ๋ณด๋์ผ๋ก์จ ํจ์ถ๋๋ ํ์
์ ํ๋ฝํ๋ค. ์ด์จ๋ ํ์๋ ๋น์ผ๊ด์
์ด๊ณ ๋ช๋ช ๋๋ผ์ด๋ฒ๋ ์ ์๋๊ธฐ ์ํ ์ ํํ ํ์
์ ํ์๋กํ๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ๋ฅผ ์ํด์ SQL Maps API๋ parameterMapํ๋ผ
ํผํฐ ์์์ jdbcType ์์ฑ์ ์ฌ์ฉํ์ฌ ์ ์๋๊ธฐ ์ํ ํ์
์ ํ๋ฝํ๋ค.
์ด ์์ฑ์ ์นผ๋ผ์ด null์ด ๊ฐ๋ฅํ ๋(nullable)๋ง ์๊ตฌ๋๋ค. Type์์ฑ์ ์ฌ์ฉํ๋ ๋ค๋ฅธ ์ด์ ๋ ๋ช
์์ ์ผ๋ก dateํ์
์ ์ ์ํ
17
- 18. ๋ ๊ฒ์ด๋ค. ์๋ฐ๋ ๋จ์ง ํ๋์ Date๊ฐํ์
(java.util.Date)์ ๊ฐ์ง๋๋ฐ ๋ฐํด ๋๊ฐ์ SQL๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ง์, ๋๊ฐ ์ต์ 3๊ฐ
์ง ์ด์์ ํ์
์ ๊ฐ์ง๋ค. ๋น์ ์ ์นผ๋ผ ํ์
์ด DATE๋ DATETIME์ค์ ํ๋๋ก ๋ช
์์ ์ผ๋ก ์ ์ํ๊ธธ ๋ฐ๋์ง๋ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ด
๋ค.
jdbcType ์์ฑ์ JDBCํ์
ํด๋์ค๋ด ๋ณ์์ ๋งค์น๋๋ ์ด๋ค ๋ฌธ์์ด๊ฐ์ ์
ํ
๋ ์ ์๋ค. ๋น๋ก ์ด๊ฒ์ ๊ทธ๊ฒ๋ค์ค์ ์ด๋ค๊ฒ
์ ์
ํ
๋ ์ ์์ง๋ง ๋ช๋ช ํ์
์ ์ง์๋์ง ์๋๋ค(์ด๋ฅผ ํ
๋ฉด blobs). ์ด ๋ฌธ์์ ๋์ค ์น์
์์ ํ๋ ์์ํฌ์ ์ํด ์ง์๋
๋ ํ์
์ ๋ํด์ ์์ ํ๋ค.
์ฃผ์! ๋๋ถ๋ถ์ ๋๋ผ์ด๋ฒ๋ ๋จ์ง null์ด ๊ฐ๋ฅํ ์นผ๋ผ์ ์ํด ์ ์๋๋ ํ์
์ ํ์๋ก ํ๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๊ทธ๋ฐ ๋๋ผ์ด๋ฒ๋ฅผ ์ํด
๋น์ ์ null์ด ๊ฐ๋ฅํ ์นผ๋ผ์ ์ํด ํ์
์ ์ ์ํ ํ์๊ฐ ์๋ค.
์ฃผ์! ์ค๋ผํด ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ ๋ ๋น์ ์ ์ด๊ฒ์ ํ์
์ ์ ์ํ์ง ์๊ณ ์๋ ์นผ๋ผ์ null๊ฐ์ ๋ฃ์ ๋ โInvalid column typeโ
์๋ฌ๋ฅผ ๋ณด๊ฒ๋ ๊ฒ์ด๋ค.
javaType
javaType ์์ฑ์ ์
ํ
๋๊ธฐ ์ํ ํ๋ผ๋ฏธํฐ์ ์๋ฐ ํ๋ผํผํฐ๋ฅผ ๋ช
์์ ์ผ๋ก ์ ์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. ๋๊ฒ ์ด๊ฒ์ ๋ฆฌํ๋ ์
(reflection)์ ํตํด ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ก๋ถํฐ ํ์๋๋ค. ํ์ง๋ง Map๊ณผ XML๋งตํ ๊ฐ์ ํน์ ๋งตํ์ ํ๋ ์์ํฌ๋ฅผ ์ํ ํ์
์ ์ ๊ณตํ์ง ์๋๋ค. ๋ง์ฝ javaType๊ฐ ์
ํ
๋์ง ์๊ณ ํ๋ ์์ํฌ๋ ์ด๋คํ์
์ธ์ง ๊ตฌ๋ณํ ์ ์๋ค๋ฉด ํ์
์ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ๋
๊ฒ์ด๋ค.
typeName
typeName ์์ฑ์ REFํ์
์ด๋ ์ฌ์ฉ์ ์ ์ ํ์
์ ๋ช
์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
javadoc์ ๋ณด๋ฉด..
typeName ์์ฑ์ ์ฌ์ฉ์-์ ์๋ REF์ถ๋ ฅ ํ๋ผ๋ฏธํฐ๋ฅผ ์ํด ์ฌ์ฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด, ์ฌ์ฉ์-์ ์ ํ์
์ STRUCT, DISTINCT,
JAVA_OBJECT, ๊ทธ๋ฆฌ๊ณ ๋ช
๋ช
๋ ๋ฐฐ์ด ํ์
์ ํฌํจํ๋ค. ์ฌ์ฉ์-์ ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ํด, ํ๋ผ๋ฏธํฐ์ ์ ์ฒด ๊ฒฝ๋ก๊ฐ ํฌํจ๋ SQLํ์
๋ช
์ด ์ฃผ์ด์ง๋ค. ๋ฐ๋ฉด์ REFํ๋ผ๋ฏธํฐ๋ ์ฃผ์ด์ง ์ฐธ์กฐํ์
์ ์ ์ฒด ๊ฒฝ๋ก๊ฐ ํฌํจ๋ ํ์
๋ช
์ ์๊ตฌํ๋ค. JDBC๋๋ผ์ด๋ฒ๋ ํ์
์ฝ๋
๋ฅผ ํ์๋ก ํ์ง ์์ผ๋ฉฐ ํ์
๋ช
์ ๋ณด๋ ์ด๊ฒ์ ๋ฌด์ํ๋ค. ์ด์๊ฐ๋ฅํ๊ธฐ ์ํด, ์ ํ๋ฆฌ์ผ์ด์
์ ์ด๋ฌํ ์ฌ์ฉ์์ ์์ REFํ๋ผ๋ฏธ
ํฐ๋ฅผ ์ํ ๊ฐ์ ์ ๊ณตํด์ผ๋ง ํ๋ค. ๋น๋ก ์ด๊ฒ์ด ์ฌ์ฉ์-์ ์์ REFํ๋ผ๋ฏธํฐ๊ฐ ๋๋๋ผ๋, ์ด ์์ฑ์ JDBCํ์
์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฑ
๋กํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. ๋ง์ฝ ํ๋ผ๋ฏธํฐ๊ฐ ์ฌ์ฉ์-์ ์๋ REFํ์
์ ๊ฐ์ง์ง ์๋๋ค๋ฉด, typeNameํ๋ผ๋ฏธํฐ๋ฅผ ๋ฌด์๋๋ค.
nullValue
nullValue ์์ฑ์ ์ด๋ค ์ ํจํ ๊ฐ(ํ๋ผํผํฐ ํ์
์ ๊ธฐ์ด๋ก ํด์)์ ์
ํ
ํ ์ ์๋ค. null ์์ฑ์ null๊ฐ ๋์ฒด๋ฅผ ์ ์ํ๊ธฐ ์ํด ์ฌ
์ฉ๋๋ค. ์ด๊ฒ์ด ์๋ฏธํ๋ ๊ฒ์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ด์์ ๊ฒ์๋๋ ๊ฐ์ธ NULL์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ์ฌ์ง๊ฒ์ด๋ผ๋๊ฒ์ด๋ค(๋ค์ด
์ค๋ null๊ฐ ๋์ฒด์ ์๋ฐ๋ ํ์). ์ด๊ฒ์ ๋น์ ์๊ฒ null๊ฐ์ ์ง์ํ์ง ์๋ ํ์
(์ด๋ฅผ ํ
๋ฉด int, double, float๋ฑ๋ฑ)์ ์ํด ๋น์
์ ์ ํ๋ฆฌ์ผ์ด์
๋ด์ โmagicโ null ์ซ์๋ฅผ ์ฌ์ฉํ๋๋ก ํ๋ฝํ๋ค. ํ๋ผํผํฐ์ ๊ทธ๋ฐ ํ์
์ ์ ํฉํ null๊ฐ์ ํฌํจํ ๋ NULL์
๊ฐ ๋์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ์ฌ์ง๊ฒ์ด๋ค.
<parameterMap> ์์
๋ชจ๋ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ parameterMap์ ์์ ๊ฐ ๋ค์๊ณผ ๊ฐ๋ค.
<parameterMap id=โinsert-product-paramโ class=โcom.domain.Productโ>
<parameter property=โidโ jdbcType=โNUMERICโ javaType=โintโ nullValue=โ-9999999โ/>
<parameter property=โdescriptionโ jdbcType=โVARCHARโ nullValue=โNO_ENTRYโ/>
</parameterMap>
<statement id=โinsertProductโ parameterMap=โinsert-product-paramโ>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>
์ ์์ ์์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ์ธ id ์ description๋ ๋ชฉ๋กํ๋๋ ์์๋๋ก ๋งตํ๋ Statement ์ธ insertProduct ์ ํ๋ผ๋ฏธํฐ
์ ์ ์ฉ๋ ๊ฒ์ด๋ค. ๊ทธ๋์ id๋ ์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ(?)์ ์ ์ฉ๋๊ณ description ๋ ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ ์ ์ฉ๋๋ค. ๋ง์ฝ์ ์์๊ฐ ๋ฐ
18
- 19. ๋๋ผ๋ฉด XML์ ๋ค์์ฒ๋ผ ๋ณด์ผ๊ฒ์ด๋ค.
<parameterMap id=โinsert-product-paramโ class=โcom.domain.Productโ>
<parameter property=โdescriptionโ />
<parameter property=โidโ/>
</parameterMap>
<statement id=โinsertProductโ parameterMap=โinsert-product-paramโ>
insert into PRODUCT (PRD_DESCRIPTION, PRD_ID) values (?,?);
</statement>
์ฃผ์! Parameter Map ์ด๋ฆ์ ์ ์๋ SQL Map XMLํ์ผ์ ์์นํ๋ค. ๋น์ ์ SQL Map(<sqlMap> rootํ๊ทธ์ ์
ํ
๋)์ id์
ํจ๊ป ํ๋ผ๋ฏธํฐ Map์ id๋ฅผ ์์ ๋ถ์์ผ๋ก์จ ๋ค๋ฅธ SQL Map XMLํ์ผ๋ด์ ํ๋ผ๋ฏธํฐ Map์ ์ฐธ์กฐํ ์ ์๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค๋ฅธ ํ
์ผ๋ก๋ถํฐ ์์ ํ๋ผ๋ฏธํฐ map๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํด ์ฐธ์กฐํ๊ธฐ ์ํ ์ ์ฒด์ด๋ฆ์ โProduct.insert-product-paramโ์ด ๋ ๊ฒ์ด๋ค.
์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ Maps
๋งค์ฐ ์์ธํ ์ค๋ช
์๋ ๋ถ๊ตฌํ๊ณ parameterMaps์ ์ ์ธํ๊ธฐ ์ํ ์์ ๋ฌธ๋ฒ์ ๋งค์ฐ ์ฅํฉํ๋ค. ํ๋ผ๋ฏธํฐ Maps์ ์ํ ์ ์
(definition)์ ๊ฐ๋จํ๊ฒ ํ๊ณ ์ฝ๋๋ฅผ ์ค์ผ์ ์๋ ์ข๋ ๋ค์ํ ๋ฌธ๋ฒ์ด ์๋ค. ๊ทธ ๋์์ ์ธ ๋ฌธ๋ฒ์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ์ด๋ฆ์ ๋งต
ํ๋ statement์ ์ธ๋ผ์ธ์ํค๋ ๊ฒ์ด๋ค. ์ด๊ธฐ์ค์ ์ ์ํด ๋ช
์์ ์ผ๋ก ์ ์๋ parameterMap ์ด ์๋ ์ด๋ค ๋งตํ๋ statement
๋ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ฅผ ์ํด ํ์ฑ๋ ๊ฒ์ด๋ค. ์ด์ ์ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ตฌํํ ์์ (์ด๋ฅผ ํ
๋ฉด Product)๋ ๋ค์์ฒ๋ผ ๋ณด์ผ๊ฒ์ด
๋ค.
<statement id=โinsertProductโ parameterClass=โcom.domain.Productโ>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id#, #description#);
</statement>
ํ์
์ ์ ์ธํ๋ ๊ฒ์ ๋ค์์ ๋ฌธ๋ฒ์ ์ฌ์ฉํจ์ผ๋ก์จ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ก ํ ์ ์๋ค.
<statement id=โinsertProductโ parameterClass=โcom.domain.Productโ>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC#, #description:VARCHAR#);
</statement>
ํ์
์ ์ ์ธํ๋ ๊ฒ๊ณผ null๊ฐ ๋์ฒด๋ ๋ค์ ๋ฌธ๋ฒ์ ์ฌ์ฉํจ์ผ๋ก์จ ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ก ํ ์ ์๋ค.
<statement id=โinsertProductโ parameterClass=โcom.domain.Productโ>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);
</statement>
์ฃผ์! ์ธ๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ ๋ ๋น์ ์ ํ์
์ ์์์ด null๊ฐ ๋์ฒด๋ฅผ ๋ช
์ํ ์ ์๋ค. ๋น์ ์ ์์๋๋ก ํ์ฑํ๊ธฐ ์ํด ๋๋ค
๋ช
์ํด์ผ ํ๋ค.
์ฃผ์! Null๊ฐ์ ์์ ํ ํฌ๋ช
์ฑ์ ์ํ๋ค๋ฉด ๋น์ ์ ์ด ๋ฌธ์์ ๋์ค์ ์ค๋ช
๋๋๊ฒ์ฒ๋ผ ๋น์ ์ result maps๋ด์ null๊ฐ ๋์ฒด๋ฅผ
๋ฐ๋์ ๋ช
์ํด์ผ ํ๋ค.
์ฃผ์! ๋น์ ์ด ๋ง์ ์์ ํ์
์์ ์์ null๊ฐ ๋์ฒด๊ฐ ํ์ํ๋ค๋ฉด ๋น์ ์ ์ธ๋ถ์ ์ธ ๊ฒ์ ์ฌ์ฉํด์ ์ฝ๋๋ฅผ ์ ๋ฆฌํ ์ ์์ด
์ผ ํ ๊ฒ์ด๋ค.
์์ํ์
ํ๋ผ๋ฏธํฐ
ํ๋ผ๋ฏธํฐ์ฒ๋ผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ฐ๋น์ ์ฐ๋ ๊ฒ์ ์ธ์ ๋ ํ์ํ๊ณ ํธ๋ฆฌํ ๊ฒ์ ์๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์ ๋น์ ์ ์ง์ ์ ์ผ๋ก ํ
๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ๋๊ฒ์ฒ๋ผ ์์ํ์
๋ํผ๊ฐ์ฒด(String, Integer, Date๋ฑ๋ฑ)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํ์ํ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค๋ฉด :
19
- 20. <statement id=โinsertProductโ parameter=โjava.lang.Integerโ>
select * from PRODUCT where PRD_ID = #value#
</statement>
PRD_ID๊ฐ ์ซ์ ํ์
์ด๋ผ๊ณ ๊ฐ์ ํ์. ํธ์ถ์ด ๋์์ ๋ java.lang.Integer๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๋ ๋งตํ๋ statement๋ฅผ ๋ง๋ค๊ฒ
์ด๋ค. #value# ํ๋ผ๋ฏธํฐ๋ Integer์ธ์คํด์ค์ ๊ฐ์ผ๋ก ๋์ฒด๋ ๊ฒ์ด๋ค. โvalueโ๋ผ๋ ์ด๋ฆ์ ๊ฐ๋จํ ๋ฌธ๋ฒ(์ด๋ฅผ ํ
๋ฉด ๊ดํธ)์
์ ์์์ด๊ณ ๋ณ๋ช
์ด ๋ ์ ์๋ค. Result Map๋ result์ฒ๋ผ ์์ํ์
์ ์ ์ง์ํ๋ค. ํ๋ผ๋ฏธํฐ๋ก ์์ํ์
์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์
๋ํด์ ์ข๋ ๋ค์ํ ์ ๋ณด๋ฅผ ์ํด์๋ Result Map์น์
๊ณผ ํ๋ก๊ทธ๋๋ฐ SQL Maps(API)๋ฅผ ๋ณด๋ผ.
์์ ํ์
์ ์ข๋ ๊ฐ๊ฒฐํ ์ฝ๋๋ฅผ ์ํด์ ๋ณ์นญ๋๋ค. ์๋ฅผ ๋ค๋ฉด โintโ๋ โjava.lang.Integerโ๋์ ์ ์ฌ์ฉ๋ ์ ์๋ค. ๋ณ์นญ์ ์
๋์ โํ๋ผ๋ฏธํฐ Map๊ณผ result Map์ ์ํด ์ง์๋๋ ํ์
โ ์ด๋ผ๋ ์ ๋ชฉ์ ํ
์ด๋ธ์์ ์ด์ผ๊ธฐ ๋๋ค.
Map ํ์
ํ๋ผ๋ฏธํฐ
๋น์ ์ด ์๋ฐ๋น์ฆ ํด๋์ค๋ฅผ ์ฐ๋ ๊ฒ์ด ํ์ํ์ง ์๊ฑฐ๋ ํธ๋ฆฌํ์ง ์์ ์์น์ ์๊ณ ํ๋์ ์์ํ์
ํ๋ผ๋ฏธํฐ์ ์ฐ์ง๋ ์
๋๋ค๋ฉด ํ๋ผ๋ฏธํฐ๊ฐ์ฒด๋ก Map(์ด๋ฅผ ํ
๋ฉด HashMap, TreeMap)์ ์ฌ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค๋ฉด :
<statement id=โinsertProductโ parameterClass=โjava.util.Mapโ>
select * from PRODUCT
where PRD_CAT_ID = #catId#
and PRD_CODE = #code#
</statement>
๋งตํ๋ statement๊ตฌํ๋ด์์๋ ์ฐจ์ด์ ์ด ์๋ค๋ ๊ฒ์ ์๋ผ. ์์ ์์ ์์ ๋ง์ฝ Map์ธ์คํด์ค๊ฐ statement๋ฅผ ์ํ ํธ์ถ๋ก ์
๋ฌ๋์๋ค๋ฉด Map์ โcatIdโ ๊ณผ โcodeโ ๋ผ๋ ์ด๋ฆ์ ํค๋ฅผ ํฌํจํด์ผ๋ง ํ๋ค. ์ด ๊ฐ์ Integer๊ณผ String๊ณผ ๊ฐ์ ์ ํธ๋๋ ํ์
์ด ๋
๋ ๊ทธ๋ฐ ํค์ ์ํด ์ฐธ์กฐ๋๋ค. Result Map์ result์ฒ๋ผ Mapํ์
์ ์์ฃผ ์ ์ง์ํ๋ค. ํ๋ผ๋ฏธํฐ์ฒ๋ผ Mapํ์
์ ์ฌ์ฉํ๋๊ฒ์
๋ํ ์ข๋ ์์ธํ ์ ๋ณด๋ฅผ ์ํด์๋ result Map์น์
๊ณผ ํ๋ก๊ทธ๋๋ฐ SQL Map(API)๋ฅผ ๋ณด๋ผ.
Map ํ์
์ญ์ ์ข๋ ๊ฐ๊ฒฐํ ์ฝ๋๋ฅผ ์ํด ๋ณ์นญ๋๋ค. ์๋ฅผ ๋ค๋ฉด โmapโ๋ โjava.util.Mapโ์ ๋์ ํ ์ ์๋ค. ๋ณ์นญ์ ์๋์ โํ
๋ผ๋ฏธํฐ Map๊ณผ result Map์ ์ํด ์ง์๋๋ ํ์
โ ์ด๋ผ๋ ์ ๋ชฉ์ ํ
์ด๋ธ์์ ์ด์ผ๊ธฐ ๋๋ค.
Result Maps
Result maps๋ SQL Maps์ ๊ฐ์ฅ ์ค์ํ ์ปดํฌ๋ํธ์ด๋ค. resultMap๋ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ฅผ ๋งตํ๋ ์ฟผ๋ฆฌ statement๋ฅผ
์คํํจ์ผ๋ก์จ ์์ฐ๋ ResultSet์ ์นผ๋ผ์ ๋งตํ์ํค๋ ์ฑ
์์ ์ง๋ค. resultMap์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ธ๋ค.
<resultMap id=โresultMapNameโ class=โsome.domain.Classโ [extends=โparent-resultMapโ]>
<result property=โpropertyNameโ column=โCOLUMN_NAMEโ
[columnIndex=โ1โ] [javaType=โintโ] [jdbcType=โNUMERICโ]
[nullValue=โ-999999โ] [select=โsomeOtherStatementโ]
/>
<result โฆโฆ/>
<result โฆโฆ/>
<result โฆโฆ/>
</resultMap>
[๊ดํธ] ๋ถ๋ถ์ ์ต์
์ด๋ค. resultMap๋ ์ค์ค๋ก statement๊ฐ ๊ทธ๊ฒ์ ์ฐธ์กฐํ๊ธฐ ์ํด ์ฌ์ฉํ id์์ฑ์ ๊ฐ์ง๋ค. resultMap๋ ํด๋
์ค๋ ํ์
๋ณ์นญ์ ์ ์ฒด๊ฒฝ๋ก๋ฅผ ํฌํจํ ์ด๋ฆ์ธ class์์ฑ์ ๊ฐ์ง๋ค. ์ด ํด๋์ค๋ ์ด๊ฒ์ ํฌํจํ๋ result๋งตํ์ ๊ธฐ๋ฐํ์ฌ ์ด๊ธฐ
ํ๋๊ณ ์์ฑ๋ ๊ฒ์ด๋ค. Extends์์ฑ์ resultMap์ ๊ธฐ์ดํ ๋ค๋ฅธ resultMap์ ์ด๋ฆ์ ์ต์
์ ์ผ๋ก ์
ํ
ํ ์ ์๋ค. ์ด๊ฒ์ ์
์ resultMap์ ๋ชจ๋ ํ๋ผํผํฐ๊ฐ ํ์ resultMap์ ๋ถ๋ถ์ ํฌํจํ๋๊ฒ์ฒ๋ผ ์๋ฐ๋ด์์ ํด๋์ค๋ฅผ ํ์ฅํ๋๊ฒ๊ณผ ์ ์ฌํ๋ค. ์
์ resultMap์ ํ๋ผํผํฐ๋ ํ์ resultMapํ๋ผํผํฐ์ ๋ถ๋ชจ resultMap๊ฐ ์์ ์์์ ์ ์๋๊ธฐ ์ ์ ์ธ์ ๋ ์ถ๊ฐ๋๋ค. ์์/
ํ์ resultMap๋ฅผ ์ํ ํด๋์ค๋ ๊ฐ์ ๊ฒ์ ํ์๋ก ํ์ง ์์๋ฟ ์๋๋ผ ๋ชจ๋ ๊ฒ์ด ๊ด๋ จ๋ ํ์๋ ์๋ค.
resultMap ์ ์๋ฐ๋น์ฆ๋ฅผ ResultSet์ ์นผ๋ผ์ ๋งตํ์ํค๋ ์ด๋์ ๋์ ํ๋ผํผํฐ ๋งตํ์ ํฌํจํ ์ ์๋ค. ๊ทธ๋ฐ ํ๋ผํผํฐ ๋งตํ
์ ๋ฌธ์๋ด์์ ์ ์ํ๊ธฐ ์ํด ์ ์ฉ๋ ๊ฒ์ด๋ค. ๊ด๋ จ ํด๋์ค๋ ๊ฐ๊ฐ์ ํ๋ผํผํฐ, Map๋๋ XML์ ์ํ get/set๋ฉ์๋๋ฅผ ๊ฐ์ง
์๋ฐ๋น์ฆ์ ํธํ๋๋ ํด๋์ค์ฌ์ผ๋ง ํ๋ค.
20
- 21. ์ฃผ์! ์นผ๋ผ์ Result Map๋ด์์ ์ ์๋๊ธฐ ์ํด์ ๋ช
์์ ์ผ๋ก ์ฝ์๊ฒ์ด๋ค.
๋ค์์ ์น์
์ property์์์ ์์ฑ๋ค์ ์์ ํ๋ค.
property
result map์ property ์์ฑ์ ๋งตํ statement์ ์ํด ๋ฐํ๋๋ result๊ฐ์ฒด์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ(get๋ฉ์๋) ์ด๋ฆ์ด๋ค. ์ด๋ฆ
์ results๋ฅผ ์์ฑํ ๋ ํ์ํ ํ์์ ์์กด์ ์ธ ๊ฐ๋ณด๋ค ๋ ํฌ๊ฒ ์ฌ์ฉ๋ ์ ์๋ค.
column
column ์์ฑ๊ฐ์ ํ๋ผํผํฐ๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉ๋ ๊ฐ๋ค๋ก๋ถํฐ์ ResultSet๋ด์ ์นผ๋ผ์ ์ด๋ฆ์ด๋ค.
columnIndex
์ต์
์ ์ธ(์ต์ํ์) ์ฑ๋ฅํฅ์์ ์ํด์ columnIndex ์์ฑ๊ฐ์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉ๋ ๊ฐ์ผ๋ก๋ถํฐ์
ResultSet๋ด์ ์นผ๋ผ์ ์ธ๋ฑ์ค์ด๋ค. ์ด๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์
์ 99%์ ๋์ ํ์ํ์ง ์์๊ฒ์ด๊ณ ์ ์ง๋ฅผ ์ํ ๋
ธ๋ ฅ๊ณผ ์๋๋ฅผ ์
ํด ๊ฐ๋
์ฑ์ ํฌ์ํ๋ค. ๋ช๋ช JDBC๋๋ผ์ด๋ฒ๋ ๋ค๋ฅธ๊ฒ๋ค์ด ๋์ ์ผ๋ก ์๋๋ฅผ ์ฌ๋ ค์ฃผ๋ ๋์ ์ด๋ค ์ฑ๋ฅ์ด๋๋ ๊ตฌ์ฒดํํ์ง ์์
๊ฒ์ด๋ค.
jdbcType
jdbcType ์์ฑ์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ฅผ ์์ฑํ๋๋ฐ ์ฌ์ฉ๋๋ ResultSet ์นผ๋ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์นผ๋ผ ํ์
์ ๋ช
์์ ์ผ๋ก ์ ์
ํ๋๋ฐ ์ฌ์ฉ๋๋ค. ๋น๋ก result maps์ด null๊ฐ๊ณผ ํจ๊ป ๊ฐ์ ์ด๋ ค์์ ๊ฐ์ง์ง ์๋๋ค๊ณ ํ๋๋ผ๋ Dateํ๋ผํผํฐ์ฒ๋ผ ์ด๋ค ๋งตํ
ํ์
์ ์ํด ์ ์ฉํ ์ ์๋ ํ์
์ ์ ์ํ๋ค. ์๋ฐ๋ ์ค์ง ํ๋์ Date๊ฐ ํ์
์ ๊ฐ์ง๊ณ SQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ฌ๋ฌ๊ฐ์ง๋ฅผ
๊ฐ์ง๊ธฐ ๋๋ฌธ์ dates(๋๋ ๋ค๋ฅธํ์
)ํ์
์ ์ ํํ๊ฒ ์
ํ
ํ๋ ๊ฒ์ ํ์ ํ๋ ๋ช๋ช๊ฒฝ์ฐ์ ํ์ํ๊ฒ ๋ ๊ฒ์ด๋ค. ์ ์ฌํ๊ฒ๋
Stringํ์
์ VARCHAR, CHAR ๋๋ CLOB์ ์ํด ์์ฑ๋ ๊ฒ์ด๋ค. ๊ทธ๋์ ๊ทธ๋ฐ ๊ฒฝ์ฐ์ ํ์ํ ํ์
์ ์ ์ํ๋ผ.
javaType
javaType ์์ฑ์ ์
ํ
๋๋ ํ๋ผํผํฐ์ ์๋ฐํ๋ผํผํฐํ์
์ ๋ช
์์ ์ผ๋ก ์ ์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. ๋๊ฐ ์ด๊ฒ์ ๋ฆฌํ๋ ์
(reflection)์ ํตํด ์๋ฐ๋น์ฆ ํ๋ผํผํฐ๋ก๋ถํฐ ๋์ด๋ผ์ ์๋ค. ํ์ง๋ง Map์ XML๋งตํ๊ณผ ๊ฐ์ ๋งตํ์ ํ๋ ์์ํฌ๋ฅผ ์ํ ํ
์
์ ์ ๊ณตํ ์ ์๋ค. ๋ง์ฝ javaType๊ฐ ์
ํ
๋์ง ์๊ณ ํ๋ ์์ํฌ๊ฐ ๊ทธ ํ์
์ ๊ตฌ๋ถํ ์ ์๋ค๋ฉด ํ์
์ ๊ฐ์ฒด๋ก ๊ฐ์ ๋์ด ์ฒ
๋ฆฌ๋ ๊ฒ์ด๋ค.
nullValue
nullValue ์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ด์์ NULL๊ฐ์ ๋์ ํด์ ์ฌ์ฉ๋๊ธฐ ์ํ ๊ฐ์ ์ ์ํ๋ค. ๊ทธ๋์ ๋ง์ฝ ResultSet์ผ๋ก๋ถํฐ
NULL์ด ์ฝ์๋ค๋ฉด ์๋ฐ๋น ํ๋ผํผํฐ๋ NULL๋์ ์ nullValue์์ฑ์ ์ํด ์ ์๋ ๊ฐ์ ์
ํ
ํ ๊ฒ์ด๋ค. null ์์ฑ๊ฐ์ ์ด๋ ํ ๊ฐ
์ ๋ ์ ์์ง๋ง ํ๋ผํผํฐํ์
์ ์ํด์๋ ์ ์ ํด์ผ๋ง ํ๋ค.
๋ง์ฝ ๋น์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ NULL์ด ๊ฐ๋ฅํ ์นผ๋ผ์ ๊ฐ์ง๋ค๋ฉด ๋น์ ์ ๋น์ ์ ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ค์์ฒ๋ผ result map๋ด์
์ ๊ทธ๊ฒ์ ์ ์ํ ์ ์๋ ๋ณ์๊ฐ๊ณผ ํจ๊ป NULL์ ํ์ํ๊ธฐ๋ฅผ ์ํ๋ค.
<resultMap id=โget-product-resultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
<result property=โsubCodeโ column=โPRD_SUB_CODEโ nullValue=โ-999โ/>
</resultMap>
์ ์์ ์์ ๋ง์ฝ PRD_SUB_CODE์ด NULL๋ก ์ฝํ์ง๋ค๋ฉด subCode ํ๋ผํผํฐ๋ -999๋ผ๋ ๊ฐ์ผ๋ก ์
ํ
๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ ๋น์
์๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ด์์ NULL์ด ๊ฐ๋ฅํ ์นผ๋ผ์ ํํํ๊ธฐ ์ํด ๋น์ ์ ์๋ฐํด๋์ค๋ด์ ์์ํ์
์ ์ฌ์ฉํ๋๋ก ํ๋ฝํ ๊ฒ์ด
๋ค. ๋ง์ฝ ๋น์ ์ด updates/inserts๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์ํ ์์
์ ์ํํ๊ธฐ๋ฅผ ์ํ ๋ ๋น์ ์ ํ๋ผ๋ฏธํฐ map๋ด์ nullValue๋ฅผ ์ ์ํด
21
- 22. ์ผ๋ง ํ๋ค๋ ๊ฒ์ ๊ธฐ์ตํด๋ผ.
select
select ์์ฑ์ ๊ฐ์ฒด์ฌ์ด์ ๊ด๊ณ๋ฅผ ์์ ํ๊ณ ์๋์ ์ผ๋ก ๋ณตํฉ ํ๋ผํผํฐ ํ์
์ ๋ก๋ํ๋๋ฐ ์ฌ์ฉ๋๋ค. statementํ๋ผํผํฐ๊ฐ
์ ๋ค๋ฅธ ๋งตํ๋ statement์ ์ด๋ฆ์ด ๋์ด์ผ๋ง ํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์นผ๋ผ๊ฐ์ statement์์ฑ์ด ํ๋ผ๋ฏธํฐ์ฒ๋ผ ๊ด๊ณ๋ ๋งตํ
statement๋ก ์ ๋ฌํ๋๊ฒ์ฒ๋ผ ๊ฐ์ property์์๋ด์ ์ ์๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์นผ๋ผ์ ์์ํ์
์ผ๋ก ์ง์์ด ๋์ด์ผ ํ๋ค. ์ง์๋
๋ ์์ํ์
๊ณผ ๋ณตํฉ ํ๋ผํผํฐ ๋งตํ/๊ด๊ณ์ ๋ํ ์์ธ์ ๋ณด๋ ์ด ๋ฌธ์ ๋์ค์ ์ด์ผ๊ธฐ ๋๋ค.
๋ดํฌํ๋ Result Maps
๋ง์ฝ ๋น์ ์ด ๋ช
์์ ์ผ๋ก ์ ์๋ resultMap์ ์ฌ์ฌ์ฉ์ ์๊ตฌํ์ง ์๋๋ค๋ ๋งค์ฐ ๊ฐ๋จํ ์๊ตฌ์ฌํญ์ ๊ฐ์ง๋ค๋ฉด ๋งตํ๋
statement์ resultClass์์ฑ์ ์
ํ
ํจ์ผ๋ก์จ result map์ ํจ์ถ์ ์ผ๋ก ์ ์ํ๋ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ด ์๋ค. ์ด ๋ฌ๊ธฐ๋ ๋น์ ์ด ๋ฐํ๋
๋ result set์ด ๋น์ ์ ์๋ฐ๋น์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ํ๋ผํผํฐ ์ด๋ฆ์ ๋งค์น๋๋ ์นผ๋ผ์ด๋ฆ(๋๋ ๋ผ๋ฒจ/๋ณ์นญ)์ ๊ฐ์ง๋ ๊ฒ์ ํ์คํด์ผ๋ง
ํ๋ค๋๊ฒ์ด๋ค. ์๋ฅผ ๋ค๋ฉด ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์์์ ์์ ๋ Productํด๋์ค๋ฅผ ์๊ฐํ ๋ ์ฐ๋ฆฌ๋ ๋ค์์ฒ๋ผ ๋ดํฌํ๋ result map์ผ๋ก
๋งตํ๋ statement๋ฅผ ์์ฑํ ์ ์๋ค.
<statement id=โgetProductโ resultClass=โcom.ibatis.example.Productโ>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #value#
</statement>
์์ ๋งตํ๋ statement๋ resultClass๋ฅผ ํ๊ธฐํ๊ณ Productํด๋์ค์ ์๋ฐ๋น์ฆ ํ๋ผํผํฐ์ ๋งค์น๋๋ ๊ฐ๊ฐ์ ์นผ๋ผ๋ฅผ ์ํ ๋ณ์นญ
์ ๋ช
์ํ๋ค. ์ด๊ฒ์ ๋ชจ๋ ํ์(required) ์ด๋ค. Result map์ ํ์ํ์ง ์๋ค. ์ฌ๊ธฐ์ ๊ตํ(tradeoff)์ ๋น์ ์ด ์นผ๋ผํ์
(๋๊ฐ
ํ์๊ฐ ์๋)๊ณผ null๊ฐ(๋๋ ๋ค๋ฅธ ์ด๋ค ํ๋ผํผํฐ ์์ฑ)์ ์ ์ํ๋ ๊ธฐํ๋ฅผ ๊ฐ์ง์ง ์๋๊ฒ์ด๋ค. ๋ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋์๋ฌธ
์๋ฅผ ๊ฐ๋ฆฌ์ง ์๊ธฐ ๋๋ฌธ์ ๋ดํฌ๋ result map๋ ๋ํ ๊ฐ๋ฆฌ์ง ์๋๋ค. ๋ง์ฝ ๋น์ ์ ์๋ฐ๋น์ด ๋๊ฐ์ ํ๋ผํผํฐ๋ฅผ ๊ฐ์ง๋ค๋ฉด ํ๋
์ ์ด๋ฆ์ firstName์ด๊ณ ๋ค๋ฅธ ๊ฒ์ firstname์ด๋ค(๋๊ฐ์ ๊ฐ์ ๋์๋ฌธ์์ ์ฐจ์ด์ด๋ค). ๊ทธ๊ฒ๋ค์ ๋์ผํ๊ณ ๋น์ ์ ๋ดํฌ๋
result map๋ฅผ ์ฌ์ฉํ ์์์๊ฒ์ด๋ค(์ด๊ฒ์ ์๋ฐ๋น ํด๋์ค์ ๋์์ธ์์ ์ ์ฌ์ ์ธ ๋ฌธ์ ์ ์ ํ์
ํ๊ฒ ๋ ๊ฒ์ด๋ค.). ๊ฒ๋ค๊ฐ
resultClass๋ฅผ ํตํด ์๋๋งตํ์ ํ๋ฉด ๋ช๋ช ์ฑ๋ฅ์ ๊ด๋ จ๋ ๋ถํ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค. ResultSetMetaData์ ์ ๊ทผํ๋ ๊ฒ์ ๋ช๋ช ์ฐ
์ฌ์ง JDBC๋๋ผ์ด๋ฒ๋ก๋ ๋๋ฆฌ๊ฒ ๋ง๋ค์ ์๋ค.
์์ํ์
์ Results (์ด๋ฅผ ํ
๋ฉด String, Integer, Boolean)
์๋ฐ๋น ํธํ ํด๋์ค๋ฅผ ์ง์ํ๊ธฐ ์ํด ์ถ๊ฐ์ ์ผ๋ก result Map์ String, Integer, Boolean ๋ฑ๋ฑ๊ณผ ๊ฐ์ ๊ฐ๋จํ ์๋ฐํ์
๋ํผ๋ฅผ
ํธ๋ฆฌํ๊ฒ ์์ฑํ ์ ์๋ค. ์์ํ์
๊ฐ์ฒด์ collection์ ๋ฐ์์ ์ด์ผ๊ธฐ ๋๋ API(executeQueryForList()๋ฅผ ๋ณด๋ผ)๋ค์ ์ฌ์ฉํด์
๊ฐ์ ธ์ฌ์ ์๋ค. ์์ํ์
์ ์๋ฐ๋น์ฒ๋ผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ ํํ๊ฒ ๋งตํ๋๋ค. ์์ํ์
์ ๋น์ ์ด ์ ํธํ๋(๋๊ฐ โvalueโ ๋๋
โvalโ) ์ด๋ฆํ์์ ์ด๋ค๊ฒ์ฒ๋ผ ๋ ์ ์๋ ํ๋์ ํ๋ผํผํฐ๋ง์ ๊ฐ์ง์ ์๋ค. ์๋ฅผ ๋ค๋ฉด ์ฐ๋ฆฌ๊ฐ ์ ์ฒด Productํด๋์ค ๋์ ์ ๋ชจ
๋ product์์ ์(description)์ ๋ชฉ๋ก๋ง์ ๋ก๋ํ๊ธธ ์ํ๋ค๋ฉด map์ ๋ค์์ฒ๋ผ ๋ณด์ฌ์ง๊ฒ์ด๋ค.
<resultMap id=โget-product-resultโ class=โjava.lang.Stringโ>
<result property=โvalueโ column=โPRD_DESCRIPTIONโ/>
</resultMap>
์ข๋ ๊ฐ๋จํ ์ ๊ทผ๋ฒ์ ๋งตํ๋ statement์์์ ๊ฐ๋จํ๊ฒ result class๋ฅผ ์ฌ์ฉํ๋๊ฒ์ด๋ค.(โasโํค์๋๋ฅผ ์ฌ์ฉํด์ โvalueโ
๋ผ๋ ์นผ๋ผ๋ณ์นญ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ฃผ์๊น๊ฒ ๋ณด๋ผ.)
<statement id=โgetProductCountโ resultClass=โjava.lang.Integerโ>
select count(1) as value
from PRODUCT
</statement>
22
- 23. Map Results
Result Maps์ HashMap๋๋ TreeMap์ฒ๋ผ Map์ธ์คํด์ค๋ฅผ ํธ๋ฆฌํ๊ฒ ์์ฑํ ์ ์๋ค. ๊ทธ๋ฐ ๊ฐ์ฒด(Map์ List)์ collection์
์๋์์ ์ด์ผ๊ธฐ๋๋ API(executeQueryForList()๋ฅผ ๋ณด๋ผ)๋ค์ ์ฌ์ฉํด์ ๊ฐ์ ธ์ฌ์ ์๋ค. Mapํ์
์ ์๋ฐ๋น๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก
์ ํํ๊ฒ ๋งตํ๋๋ค. ํ์ง๋ง ์๋ฐ๋น ํ๋ผํผํฐ์
ํ
๋์ ์ Map์ key๋ค์ ๋์๋๋ ๋งตํ์นผ๋ผ์ ์ํ ๊ฐ์ ์ฐธ์กฐํ๋๋ก ์
ํ
ํ
๋ค. ์๋ฅผ ๋ค๋ฉด ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ product์ ๊ฐ์ Map์ผ๋ก ๋นจ๋ฆฌ ๋ก๋์ํค๊ธธ ์ํ๋ค๋ฉด ์ฐ๋ฆฌ๋ ๋ค์์ฒ๋ผ ํ ๊ฒ์ด๋ค.
<resultMap id=โget-product-resultโ class=โjava.util.HashMapโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โcodeโ column=โPRD_CODEโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
<result property=โsuggestedPriceโ column=โPRD_SUGGESTED_PRICEโ/>
</resultMap>
์ ์์ ์์ HashMap์ธ์คํด์ค๋ Product๋ฐ์ดํฐ๋ฅผ ์์ฑํ ๊ฒ์ด๋ค. ํ๋ผํผํฐ ์ด๋ฆ ์์ฑ(์ด๋ฅผ ํ
๋ฉด โidโ)์ HashMap์ ํค๊ฐ ๋
๊ฒ์ด๋ค. ๋งตํ์นผ๋ผ์ ๊ฐ์ HashMap์ ๊ฐ์ด ๋ ๊ฒ์ด๋ค. ๋ฌผ๋ก ๋น์ ์ Mapํ์
์ ๊ฐ์ง๊ณ ๋ดํฌ๋ result map์ ์ฌ์ฉํ ์๋ ์๋ค.
์๋ฅผ ๋ค๋ฉด :
<statement id=โgetProductCountโ resultClass=โjava.util.HashMapโ>
select * from PRODUCT
</statement>
์์ ๊ฒ์ ๋ฐํ๋ ResultSet์ Mapํํ์ ๋น์ ์๊ฒ ์ค๊ฒ์ด๋ค.
๋ณตํฉ(Complex) Properties (์ด๋ฅผ ํ
๋ฉด ์ฌ์ฉ์์ ์ํด ์ ์๋ ํด๋์ค์ ํ๋ผํผํฐ)
์ด๊ฒ์ ์ ํธํ๋ ๋ฐ์ดํฐ์ ํด๋์ค๋ฅผ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ ๋งตํ๋ statement์ ํจ๊ป ๊ด๋ จ๋ resultMapํ๋ผํผํฐ์ ์ํด
๋ณตํฉํ์
์ ํ๋ผํผํฐ(์ฌ์ฉ์์ ์ํด ์์ฑ๋ ํด๋์ค)๋ฅผ ์๋์ ์ผ๋ก ์์ฑํ๋ ๊ฒ์ ๊ฐ๋ฅํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ด ๋ฐ์ดํฐ๋ ์ธ์
๋ ๋ณตํฉํ๋ผํผํฐ๋ ๊ด๊ณ์ โmany sideโ๋ก๋ถํฐ์ด๊ณ ํ๋ผํผํฐ ์์ ์ ๊ด๊ณ์ โone sideโ๋ก ๋ถํฐ์ด๋ค๋ผ๋ ๊ฒ์ ๊ณ ์ ํ๋ ํด๋
์ค์์ 1:1๊ด๊ณ ๋๋ 1:M๊ด๊ณ๋ฅผ ํตํด ํํ๋๋ค. ์๋ฅผ ๋ค๋ฉด :
<resultMap id=โget-product-resultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
<result property=โcategoryโ column=โPRD_CAT_IDโ select=โgetCategoryโ/>
</resultMap>
<resultMap id=โget-category-resultโ class=โcom.ibatis.example.Categoryโ>
<result property=โidโ column=โCAT_IDโ/>
<result property=โdescriptionโ column=โCAT_DESCRIPTIONโ/>
</resultMap>
<statement id=โgetProductโ parameterClass=โintโ resultMap=โget-product-resultโ>
select * from PRODUCT where PRD_ID = #value#
</statement>
<statement id=โgetCategoryโ parameterClass=โintโ resultMap=โget-category-resultโ>
select * from CATEGORY where CAT_ID = #value#
</statement>
์ ์์ ์์ Product์ ์ธ์คํด์ค๋ Categoryํ์
์ category๋ฅผ ํธ์ถํ๋ ํ๋ผํผํฐ๋ฅผ ๊ฐ์ง๋ค. Category๋ ๋ณตํฉ์ฌ์ฉ์ํ์
์ด
๊ธฐ ๋๋ฌธ์ JDBC๋ ๊ทธ๊ฒ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๊ฐ์ง์ง ์๋๋ค. ํ๋ผํผํฐ๋งตํ๊ณผ ํจ๊ป ๋ค๋ฅธ ๋งตํ๋ statement๋ฅผ ๊ด๋ จ์ํด์ผ๋ก์จ ์ฐ
๋ฆฌ๋ ๊ทธ๊ฒ์ ์์ฑํ๊ธฐ ์ํ SQL Map์์ง์ ์ํด ์ถฉ๋ถํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค. getProduct๋ฅผ ์ํํ๋ฉด get-product-result result
map์ด PRD_CAT_ID์นผ๋ผ๋ด ๋ฐํ๋๋ ๊ฐ์ ์ฌ์ฉํด์ getCategory์ ํธ์ถํ ๊ฒ์ด๋ค. get-category-result result map์ Category
๋ฅผ ์ด๊ธฐํํ ๊ฒ์ด๊ณ ๊ทธ๊ฒ์ ์์ฑํ๋ค. ์ ์ฒด Category์ธ์คํด์ค๋ Product์ categoryํ๋ผํผํฐ๋ก ์
ํ
ํ๋ค.
N+1 Selects (1:1) ํผํ๊ธฐ
23
- 24. ์ ์๋ฃจ์
์ ์ฌ์ฉํ ๋ ๋ฌธ์ ์ ์ ๋น์ ์ด Product๋ฅผ ๋ก๋ํ ๋๋ง๋ค ๋๊ฐ(Product๋ฅผ ์ํด ํ๋ ๊ทธ๋ฆฌ๊ณ Category๋ฅผ ์ํด์ ํ๋.
์ด 2๊ฐ)์ SQL๋ฌธ์ด ์ค์ ์ ์ผ๋ก ๊ตฌ๋๋๋ค๋๊ฒ์ด๋ค. ์ด ๋ฌธ์ ๋ ํ๋์ Product๋ฅผ ๋ก๋ํ ๋๋ ํฐ๋ฌธ์ ๊ฐ ์๋๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง
๋ง์ฝ 10๊ฐ์ Product๋ฅผ ๋ก๋ํ๋ ์ฟผ๋ฆฌ๋ฅผ ํ๋ค๋ฉด ๊ฐ๊ฐ์ ์ฟผ๋ฆฌ๋ ๊ด๋ จ๋ category๋ฅผ ๋ก๋ํ๊ธฐ ์ํ Product๋ฅผ ์ํด์๋ ์คํ๋
๊ฒ์ด๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก 11๋ฒ์ ์ฟผ๋ฆฌ๋ฅผ ํ๊ฒ ๋๋ค. Product์ ๋ชฉ๋ก์ ์ํด ํ๋, ๊ด๋ จ๋ Category๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ๋ฐํ๋๋
Product๋ฅผ ์ํด ํ๋์ฉ(N+1 ๋๋ ์ด ๊ฒฝ์ฐ์ 10+1=11)
ํด๊ฒฐ๋ฒ์ ๋ถ๋ฆฌ๋ select ๋ฌธ ๋์ ์ ์กฐ์ธ๊ณผ ๋ดํฌ๋(nested)ํ๋ผํผํฐ ๋งตํ์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ ๊ทธ์ ๊ฐ์ ์ํฉ์ ์ฌ์ฉ
ํ ์์ ๊ฐ ์๋ค.
<resultMap id=โget-product-resultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
<result property=โcategory.idโ column=โCAT_IDโ />
<result property=โcategory.descriptionโ column=โCAT_DESCRIPTIONโ />
</resultMap>
<statement id=โgetProductโ parameterClass=โintโ resultMap=โget-product-resultโ>
select * from PRODUCT, CATEGORY where PRD_CAT_ID=CAT_ID and PRD_ID = #value#
</statement>
๋ฆ์(Lazy) ๋ก๋ฉ ๋ ์กฐ์ธ(1:1)
์กฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ธ์ ๋ ๋ ์ข์ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ง๋ ์๋๋ค๋ ๊ฒ์ ์ฃผ์ํ๋ ๊ฒ์ ์ค์ํ๋ค. ๋ง์ฝ ๋น์ ์ด ๊ด๊ณ๊ฐ์ฒด์ ์ ๊ทผ
ํ๋ ๊ฒ์ด ๊ฑฐ์ ์๋ ์ํฉ์ด๋ผ๋ฉด ์กฐ์ธ์ ํผํ๋ ๊ฒ์ด ๋ ๋น ๋ฅด๊ณ ๋ชจ๋ categoryํ๋ผํผํฐ์ ๋ก๋ฉ์ด ๋ถํ์ํ๋ค. ์ด๊ฒ์ outer
์กฐ์ธ์ ํฌํจํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋์์ธ์ด๋ null๊ฐ์ด ๊ฐ๋ฅํ๊ฑฐ๋ ์ธ๋ฑ์ค๊ฐ ์๋ ์นผ๋ผ์๋ ์ฌ์ค์ด๋ค. ์ด๋ฐ ์ํฉ์์ ๋ฆ์ ๋ก
๋ฉ๊ณผ bytecodeํฅ์ ์ต์
์ผ๋ก sub-select์๋ฅ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ข๋ ํฅ์๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค๋ค. ์ผ๋ฐ์ ์ธ ๊ท์น์ ์ฐ๊ด๋ ํ๋ผ
ํผํฐ์ ์ ๊ทผํ๋ ๊ฒ์ ์ข๋ ํ๊ณ ์ ํ ๋๋ง ์กฐ์ธ์ ์ฌ์ฉํ๋ผ. ๋ฐ๋ฉด์ ๋ฆ์ ๋ก๋ฉ์ด ์ต์
์ด ์๋๋์๋ง ๊ทธ๊ฒ์ ์ฌ์ฉํ๋ผ.
๋ง์ฝ ๋น์ ์ด ์ฌ์ฉํ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํ๋๋ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ๊ฑฑ์ ํ์ง ๋ง๋ผ. ๊ทธ๊ฒ์ ๋ฌธ์ ๋ ์๋๋ค. ๋น์ ์ ์๋ฐ์ฝ๋ ์ถฉ๋์์ด
์ด๊ฒ์ ํญ์ ๋ณ๊ฒฝํ ์์๋ค. ์์ ๋ ์์ ๋ ๊ฐ์ ๊ฐ์ฒดํํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ณ ์ ํํ๊ฒ ๊ฐ์ ๋ฉ์๋ ํธ์ถ์ ์ฌ์ฉํด์ ๋ก๋๋
๋ค. ๋ง์ฝ ๋น์ ์ด ์บ์ฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ฉด ๋จ์ง ํ๋์ ๊ณ ๋ ค์ฌํญ์ separate select(์กฐ์ธ์ด ์๋) ์๋ฃจ์
์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐํ
๋๋ ์บ์ฌ๋ ์ธ์คํด์ค๋ด์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ฒ ๋๋ค.
๋ณตํฉ Collection ํ๋ผํผํฐ
๋ณตํฉ ๊ฐ์ฒด์ ๋ชฉ๋ก์ ํํํ๋ ํ๋ผํผํฐ๋ฅผ ๋ก๋ํ๋ ๊ฒ์ ๊ฐ๋ฅํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ด์ ๋ฐ์ดํฐ๋ M:M๊ด๊ณ๋ 1:M๊ด๊ณ์ ์
ํด ํํ๋ ๊ฒ์ด๋ค. ๊ฐ์ฒด๋ชฉ๋ก์ ๋ก๋ํ๋ ๊ฒ์ statement์ ์ด๋ค ๋ณ๊ฒฝ์ฌํญ๋ ์ฃผ์ง ์๋๋ค. SQL Mapํ๋ ์์ํฌ๊ฐ ๋น์ฆ๋์ค๊ฐ
์ฒด๋ด์์ ๋ฆฌ์คํธ์ฒ๋ผ ํ๋ผํผํฐ๋ฅผ ๋ก๋ํ๊ธฐ์ํด ์๊ตฌ๋๋ ๋จ ํ๋์ ์ฐจ์ด์ ์ java.util.List ๋๋ java.util.Collection ํ์
์ด
๋์ด์ผ ํ๋ค๋๊ฒ์ด๋ค. ์๋ฅผ๋ค๋ฉด Category๊ฐ Product ์ธ์คํด์ค ๋ชฉ๋ก์ ๊ฐ์ง๋ค๋ฉด ๋งตํ์ ๋ค์์ฒ๋ผ ๋ณด์ผ๊ฒ์ด๋ค.(Category๊ฐ
java.util.Listํ์
์ โproductListโ๋ผ๊ณ ๋ถ๋ฆฌ๋ ํ๋ผํผํฐ๋ฅผ ๊ฐ์ง๋ค๊ณ ๊ฐ์ ํ์.)
<resultMap id=โget-category-resultโ class=โcom.ibatis.example.Categoryโ>
<result property=โidโ column=โCAT_IDโ/>
<result property=โdescriptionโ column=โCAT_DESCRIPTIONโ/>
<result property=โproductListโ column=โCAT_IDโ select=โ getProductsByCatIdโ/>
</resultMap>
<resultMap id=โget-product-resultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
</resultMap>
<statement id=โgetCategoryโ parameterClass=โintโ resultMap=โget-category-resultโ>
select * from CATEGORY where CAT_ID = #value#
</statement>
<statement id=โgetProductsByCatIdโ parameterClass=โintโ resultMap=โget-product-resultโ>
select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
24
- 25. N+1 Selects (1:M ๊ณผ M:N) ํผํ๊ธฐ
์ด๊ฒ์ ์์ 1:1 ์ํฉ๊ณผ ์ ์ฌํ๋ค. ํ์ง๋ง ๊ต์ฅํ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ ๋ ์ข๋ ํฐ ๊ฑฑ์ ๊ฑฐ๋ฆฌ๊ฐ ๋ ๊ฒ์ด๋ค. ์ ํด๊ฒฐ๋ฒ๊ณผ ํจ๊ป
๋ฌธ์ ๋ ๋น์ ์ด Category๋ฅผ ๋ก๋ํ ๋๋ง๋ค ๋๊ฐ์ SQL๋ฌธ(ํ๋๋ Category๋ฅผ ์ํ ํ๋์ด๊ณ ํ๋๋ Products์ ๋ํ ๋ชฉ๋ก์ ์
ํ ๊ฒ)์ ์ค์ง์ ์ผ๋ก ์ํ๋๋ค. ์ด ๋ฌธ์ ๋ ํ๋์ Category๋ฅผ ๋ก๋ํ ๋ ํ๋ฒํ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง 10๊ฐ์ Category๋ฅผ ๋ก๋ํ
๋ ์ฟผ๋ฆฌ๋ฌธ์ ์คํํ ๋๋ ๊ฐ๊ฐ์ ์ฟผ๋ฆฌ๊ฐ Product์ ๋ชฉ๋ก์ ๋ก๋ํ๊ธฐ ์ํ ๊ฐ๊ฐ์ Category๋ฅผ ์ํด์ ์ํ๋ ๊ฒ์ด๋ค. ๊ฒฐ๊ณผ์ ์ผ
๋ก 11๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ํ๋๋ค. ํ๋๋ Category ๋ชฉ๋ก์ ์ํ๊ฒ์ด๊ณ ๊ฐ๊ฐ์ Product ๊ด๋ จ ๋ชฉ๋ก์ ๋ฐํํ๋ ๊ฐ๊ฐ์ Category๋ฅผ
์ํ ๊ฒ์ด๋ค(N+1 ๋๋ ์ด ๊ฒฝ์ฐ์ 10+1=11). ์ด ์ํ์ ๋์ฑ ๋์๊ฒ ๋ง๋ค๋ ค๋ฉด ์ฐ๋ฆฌ๋ ๊ต์ฅํ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ฉด ๋๋ค.
1:N ๊ณผ M:N ํด๊ฒฐ๋ฒ
iBATIS๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ๋ค์์ ๊ทธ ์์ ์ด๋ค.
<sqlMap namespace="ProductCategory">
<resultMap id=โcategoryResultโ class=โcom.ibatis.example.Categoryโ groupBy=โidโ>
<result property=โidโ column=โCAT_IDโ/>
<result property=โdescriptionโ column=โCAT_DESCRIPTIONโ/>
<result property=โproductListโ resultMap=โProductCategory.productResultโ/>
</resultMap>
<resultMap id=โproductResultโ class=โcom.ibatis.example.Productโ>
<result property=โidโ column=โPRD_IDโ/>
<result property=โdescriptionโ column=โPRD_DESCRIPTIONโ/>
</resultMap>
<select id=โgetCategoryโ parameterClass=โintโ resultMap=โcategoryResultโ>
select C.CAT_ID, C.CAT_DESCRIPTION, P.PRD_ID, P.PRD_DESCRIPTION
from CATEGORY C
left outer join PRODUCT P
on C.CAT_ID = P.PRD_CAT_ID
where CAT_ID = #value#
</select>
</sqlMap>
๋น์ ์ด ํธ์ถํ ๋,
List myList = executeQueryForList("ProductCategory.getCategory", new Integer(1002));
...๋ฉ์ธ ์ฟผ๋ฆฌ๋ ์ํ๋๊ณ ๊ฒฐ๊ณผ๋ โ com.ibatis.example.Category โํ์
์ bean์ธ myList๋ณ์์ ์ ์ฅ๋๋ค. List๋ด ๊ฐ๊ฐ์ ๊ฐ์ฒด๋
๊ฐ์ ์ฟผ๋ฆฌ๋ก๋ถํฐ ์์ฑ๋๋ List์ธ โ productList โํ๋ผํผํฐ๋ฅผ ๊ฐ์ง๊ฒ์ด๋ค. ํ์ง๋ง ํ์ ๋ชฉ๋ก๋ด bean์ ์์ฑํ๋ โ
productResult โ ๊ฒฐ๊ณผ ๋งต์ ์ฌ์ฉํ๋ค. ๊ทธ๋์ ๋น์ ์ ํ์๋ชฉ๋ก์ ํฌํจํ๋ ๋ชฉ๋ก์ผ๋ก ์ข
๋ฃํ๊ณ ์ค์ง ํ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ
๋ง์ด ์ํ๋๋ค.
๊ฐ์ฅ ์ค์ํ ํญ๋ชฉ์ "categoryResult" ๊ฒฐ๊ณผ ๋งต๋ด
groupBy="id"
...์์ฑ์ด๊ณ ...
<result property="productList" resultMap="ProductCategory.productResult"/>
...ํ๋ผํผํฐ ๋งตํ์ด๋ค. ๋ค๋ฅธ ์ค์ํ ์ฌํญ์ productListํ๋ผํผํฐ๋ฅผ ์ํ ๊ฒฐ๊ณผ๋งตํ์ด ๋ช
๋ช
๊ณต๊ฐ์ ์ธ์(์ด๊ฒ์ ์๋ํ์ง ์๋
โproductResult โ์ด ๋ ๊ฒ์ด๋ค.)ํ๋๊ฒ์ด๋ค.
์ด ์ ๊ทผ๋ฒ์ ์ฌ์ฉํ์ฌ, ๋น์ ์ N+1 ๋ฌธ์ ๋ฅผ ํ์ ์๋ค.
25
- 26. ๋ฆ์(Lazy) ๋ก๋ฉ ๋ ์กฐ์ธ(1:M and M:N)
๋จผ์ ์ด์ผ๊ธฐ๋ 1:1์ํฉ์ฒ๋ผ ์กฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ธ์ ๋ ๋ ์ข๋ค๋ ๊ฒ์ด ์๋๋ผ๋ ๊ฒ์ ์๋ ๊ฒ์ ์ค์ํ๋ค. ์ด๊ฒ์ ๋๋์
๋ฐ์ดํฐ๋ก ์ธํ์ฌ ๊ฐ๋ณ์ ์ธ ๊ฐ ํ๋ผํผํฐ๋ฅผ ์ํ ๊ฒ๋ณด๋ค collectionํ๋ผํผํฐ์์ ์ข๋ ์ฌ์ค์ ์ด๋ค. ๋ง์ฝ ๋น์ ์ด ๊ด๋ จ๋ ๊ฐ์ฒด์
์ ๊ทผํ๋ ๊ฒ์ด ๋๋ฌธ ์ํฉ(์ด๋ฅผ ํ
๋ฉด Categoryํด๋์ค์ productList ํ๋ผํผํฐ)์ด๋ผ๋ฉด ์ด๊ฒ์ ์กฐ์ธ๊ณผ product๋ชฉ๋ก์ ํ์์๋
๋ก๋ฉ์ ํผํ๋ค๋ฉด ์ ๋ง ๋น ๋ฅด๊ฒ ๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ outer์กฐ์ธ๊ณผ null์ด ๊ฐ๋ฅํ๊ณ ์๋๋ฉด ๋๋ ์ธ๋ฑ์ค๊ฐ ์๋ ์นผ๋ผ์ ํฌํจํ ๋ฐ์ด
ํฐ๋ฒ ์ด์ค ๋์์ธ์๋ ํน๋ณํ ์ฌ์ค์ด๋ค. ์ด๋ฐ ์ํฉ์์ ๋ฆ์(lazy)๋ก๋ฉ๊ณผ bytecodeํฅ์์ต์
์ผ๋ก sub-select์๋ฃจ์
์ ์ฌ์ฉํ๋
๊ฒ์ ์ข๋ ํฅ์์์ผ์ค๋ค. ์ผ๋ฐ์ ์ธ ๊ท์น์ ์ฐ๊ด๋ ํ๋ผํผํฐ์ ์ ๊ทผํ๋ ๊ฒ์ ์ข๋ ํ๊ณ ์ ํ ๋๋ง ์กฐ์ธ์ ์ฌ์ฉํ๋ผ. ๋ฐ๋ฉด์ ๋ฆ
์ ๋ก๋ฉ์ด ์ต์
์ด ์๋๋์๋ง ๊ทธ๊ฒ์ ์ฌ์ฉํ๋ผ.
๋จผ์ ์ธ๊ธํ๋ ๊ฒ ์ฒ๋ผ ๋ง์ฝ ๋น์ ์ด ์ด๋ค ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋์ง ๊ฒฐ์ ํ๋๋ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ๊ฑฑ์ ํ์ง ๋ง๋ผ. ์ด๋ค ๋ฐฉ๋ฒ์ ์ฌ
์ฉํ ์ง์ ๋ํด์ ๊ฑฑ์ ํ๋ ๊ฒ์ ํ์์๋ ์ผ์ด๋ค. ๋น์ ์ ๋น์ ์ ์๋ฐ์ฝ๋์ ์ถฉ๋์์ด ๊ทธ๊ฒ์ ๋ณํ์ํฌ์ ์๋ค. ์์ ๋ ์์
๋ ๊ฐ์ ๊ฐ์ฒดํํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ณ ์ ํํ๊ฒ ๊ฐ์ ๋ฉ์๋ ํธ์ถ์ ์ฌ์ฉํด์ ๋ก๋๋๋ค. ๋ง์ฝ ๋น์ ์ด ์บ์ฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ฉด ๋จ์ง
ํ๋์ ๊ณ ๋ ค์ฌํญ์ separate select(์กฐ์ธ์ด ์๋) ์๋ฃจ์
์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐํ๋๋ ์บ์ฌ๋ ์ธ์คํด์ค๋ด์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๊ฒ ๋
๋ค.
๋ณตํฉ ํค๋๋ ๋ค์ค ๋ณตํฉ ํ๋ผ๋ฏธํฐ ํ๋ผํผํฐ
๋น์ ์ ์ ์์ ์์ column ์์ฑ์ ์ํด resultMap๋ด์ ์ ์๋ ๊ฒ์ฒ๋ผ ์ฌ์ฉ๋์ด์ง๋ ๊ฒ์ ํ๋์ ํค๋ผ๋ ๊ฒ์ด ์ธ๊ธ๋์๋ค.
์ด๊ฒ์ ๋จ์ง ํ๋์ ํค๋ง์ด ๊ด๊ณ๋ ๋งตํ statement์ ๊ด๋ จ ๋ ์ ์๋ค๋ ๊ฒ์ ์ ์ํ๋ค. ์ด์จ๋ ๊ด๊ณ๋ ๋งตํ statement์ ์
๋ฌํ ๋ค์ค ์นผ๋ผ์ ํ๋ฝํ๋ ๋์์ ์ธ ๋ฌธ๋ฒ์ด ์๋ค. ์ด๊ฒ์ ๋ณตํฉํค ๊ด๊ณ๊ฐ ์กด์ฌํ๋ ์ํฉ์ด๋ ๋น์ ์ด ๊ฐ๋จํ๊ฒ #value#์ ๋ค
๋ฅธ ์ด๋ฆ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ ๋ ํธ๋ฆฌํ๋ค. Column ์์ฑ์ด ๊ฐ๋จ{param1=column1, param2=column2, โฆ,
paramN=columnN}ํ ๋ ๋์์ ์ธ ๋ฌธ๋ฒ์ด๋ค. PAYMENTํ
์ด๋ธ์ด Customer ID์ Order ID๋ฅผ ๋๋ค ํค๋ก ํ ๋ ๋ค์์ ์์ ๋ฅผ
๋ณด๊ณ ์๊ฐํด๋ณด๋ผ.
<resultMap id=โget-order-resultโ class=โcom.ibatis.example.Orderโ>
<result property=โidโ column=โORD_IDโ/>
<result property=โcustomerIdโ column=โORD_CST_IDโ/>
โฆ
<result property=โpaymentsโ column=โ{itemId=ORD_ID, custId=ORD_CST_ID}โ
select=โ getOrderPaymentsโ/>
</resultMap>
<statement id=โgetOrderPaymentsโ
resultMap=โget-payment-resultโ>
select * from PAYMENT
where PAY_ORD_ID = #itemId#
and PAY_CST_ID = #custId#
</statement>
์ต์
์ ์ผ๋ก ๋น์ ์ ๊ทธ๊ฒ๋ค์ด ํ๋ผ๋ฏธํฐ์ฒ๋ผ ๊ฐ์ ์์๋ก ์ ๋ ฌ๋๋ ๊ฒ์ฒ๋ผ ์นผ๋ผ์ด๋ฆ์ ์ ์ํ ์ ์๋ค. ์๋ฅผ ๋ค๋ฉด
{ORD_ID, ORD_CST_ID}
์ธ์ ๋ ์ฒ๋ผ ์ด๊ฒ์ ์ฝ๊ธฐ์ ์ ์ง๋ผ๋ ๊ฒ์ ์ํฅ๊ณผ ํจ๊ป ๋ฏธ์ธํ ์ฑ๋ฅ ํ๋์ด ์๋ค.
์ค์! ํ์ฌ์ SQL Mapํ๋ ์์ํฌ๋ ์ํํ๋ ๊ด๊ณ๋ฅผ ์๋์ผ๋ก ํด์ํ์ง ์๋๋ค. ๋ถ๋ชจ/์์ ๊ด๊ณ(ํธ๋ฆฌ)๋ฅผ ๊ตฌํํ ๋ ์ด๊ฒ์
์๊ณ ์์ด๋ผ. ์ฌ์ด ๋์์ ๊ฐ๋จํ๊ฒ ๋ถ๋ชจ๊ฐ์ฒด๋ฅผ ๋ก๋ํ๊ธฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ํ ํ๋ ๋๋ โN+1 avoidanceโ ํด๊ฒฐ๋ฒ์์ ์์ ๋
์กฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ฅผ ์ํ ๋๋ฒ์งธ result map๋ฅผ ์ ์ํ๋๊ฒ์ด๋ค.
์ฃผ์! ๋ช๋ช JDBC๋๋ผ์ด๋ฒ(์ด๋ฅผ ํ
๋ฉด ๋ด์ฅ๋ PointBase)๋ ๋์์ ๋ค์ค ResultSet(connection๋ง๋ค)์ ์ง์ํ์ง ์๋๋ค. ๊ทธ๋ฐ
๋๋ผ์ด๋ฒ๋ SQL Map์์ง์ด ๋ค์ค ResultSet connection์ ์๊ตฌํ๊ธฐ ์๊ธฐ ๋๋ฌธ์ ๋ณต์กํ ๊ฐ์ฒด ๋งตํ๊ณผ๋ ์๋ํ์ง ์์๊ฒ์ด๋ค.
๋ค์ ๋งํด ์กฐ์ธ์ ์ฌ์ฉํ๋๊ฑฐ ๋์ ์ ์ด๊ฒ์ ํด์ํ ์ ์๋ค.
์ฃผ์! Result Map ์ด๋ฆ์ ์ธ์ ๋ ๊ทธ๊ฒ๋ค์ด ์ ์๋ SQL Map XMLํ์ผ์ ์์นํ๋ค. ๋น์ ์ SQL Map์ ์ด๋ฆ์ Result map
์ ์ด๋ฆ์์ ์์น์ํด์ผ๋ก์จ ๋ค๋ฅธ SQL Map XMLํ์ผ๋ด์ Result Map๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
26
- 27. ๋ง์ฝ ๋น์ ์ด JDBC๋ฅผ ์ํด MS์ SQL Server2000 ๋๋ผ์ด๋ฒ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋น์ ์ ์๋ ํธ๋์ญ์
๋ชจ๋์ธ ๋์ ๋ค์ค statement
๋ฅผ ์ํํ๊ธฐ ์ํด connection url์ SelectMethod=Cursor์ ์ถ๊ฐํ ํ์๊ฐ ์์์ง๋ ๋ชจ๋ฅธ๋ค.(MS์ ์ง์ ๊ธฐ๋ฐ ๊ธฐ์ฌ 313181์
๋ณด๋ผ. http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B313181).
ํ๋ผ๋ฏธํฐ Maps์ Result Maps๋ฅผ ์ํด ์ง์๋๋ ํ์
๋ค
ํ๋ผ๋ฏธํฐ์ result๋ฅผ ์ํด iBATIS ํ๋ ์์ํฌ์ ์ํด ์ง์๋๋ ์๋ฐํ์
์ ๋ค์๊ณผ ๊ฐ๋ค.
Java Type JavaBean/Map Result Class / Type Alias**
Property Mapping Parameter Class***
boolean YES NO boolean
java.lang.Boolean YES YES boolean
byte YES NO byte
java.lang.Byte YES YES byte
short YES NO short
java.lang.Short YES YES short
int YES NO int/integer
java.lang.Integer YES YES int/integer
long YES NO long
java.lang.Long YES YES long
float YES NO float
java.lang.Float YES YES float
double YES NO double
java.lang.Double YES YES double
java.lang.String YES YES string
java.util.Date YES YES date
java.math.BigDecimal YES YES decimal
* java.sql.Date YES YES N/A
* java.sql.Time YES YES N/A
* java.sql.Timestamp YES YES N/A
* java.sql. date ํ์
์ฌ์ฉ์ ์ข์ง์๋ค(discouraged). ๋์ ์ java.util.Date ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ ์ผ์ข๋ค.
** .ํ๋ผ๋ฏธํฐ๋ resultํด๋์ค๋ฅผ ์ ์ํ ๋ ํ์
๋ณ์นญ์ ์ ์ฒด๊ฒฝ๋ก์ ํด๋์ค๋ช
์ ๋๋ ๊ฒ์ด ์ข๋ค.
*** int, boolean and float ์ ๊ฐ์ ์์ํ์
์ iBATIS ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ ์ด์ด๊ฐ ์์ ํ ๊ฐ์ฒด์งํฅ์ ๊ทผ๋ฒ์ ์ฌ์ฉํ๋๊ฒ์ฒ๋ผ ์ง
์ ์ ์ผ๋ก ์์ํ์
์ ์ง์ํ์ง๋ ์๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ชจ๋ ํ๋ผ๋ฏธํฐ์ result๋ ๊ทธ๋ค์ ์์๋ ๋ฒจ์์ ๊ฐ์ฒด๊ฐ ๋์ด์ผ ํ๋ค. ๋ถ์
์ ์ผ๋ก JDK1.5์ autoboxing๊ธฐ๋ฅ์ ์ ์ฌ์ฉ๋๊ธฐ ์ํด ์์ํ์
์ ํ๋ฝํ๋ค.
์ฌ์ฉ์ ์ ์ ํ์
ํธ๋ค๋ฌ ์์ฑํ๊ธฐ
ํ์
์ TypeHandlerCallback์ธํฐํ์ด์ค์ ์ฌ์ฉ์ ํตํด iBATIS๋ด์์ ํ์ฅ๋ ์ ์๋ค. ๋น์ ์์ ์ ํ์
ํธ๋ค๋ฌ๋ฅผ ์์ฑํ๊ธฐ ์
ํด, TypeHandlerCallback์ ๊ตฌํํ ํด๋์ค๋ฅผ ์์ฑํ ํ์๊ฐ ์๋ค. ์ฌ์ฉ์์ ์ ํ์
ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋น์ ์ ์ง์๋์ง ์๋
ํ์
์ ๋ค๋ฃจ๊ฑฐ๋ ์ง์๋๋ ํ์
์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ค๋ค์ ํ๋ ์์ํฌ๋ฅผ ํ์ฅํ ์ ์๋ค. ์๋ฅป๋ค๋ฉด, ๋น์ ์ ์ ์ ํ BLOB์ง์์
๊ตฌํํ๋ ์ฌ์ฉ์ ์ ์ ํ์
ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ๋๊ฐ 0/1๋์ ์ โYโ์ โNโ์ ์ฌ์ฉํ๋ boolean์ ๋ค๋ฃจ๊ธฐ ์ํด ์ด๊ฒ์ ์ฌ์ฉ
ํ ์ ์๋ค.
๋ค์์ โYesโ์ โNoโ๋ฅผ ์ฌ์ฉํ๋ booleanํธ๋ค๋ฌ์ ๊ฐ๋จํ ์์ ์ด๋ค.
public class YesNoBoolTypeHandlerCallback implements TypeHandlerCallback {
private static final String YES = "Y";
private static final String NO = "N";
public Object getResult(ResultGetter getter)
27
- 28. throws SQLException {
String s = getter.getString();
if (YES.equalsIgnoreCase(s)) {
return new Boolean (true);
} else if (NO.equalsIgnoreCase(s)) {
return new Boolean (false);
} else {
throw new SQLException (
"Unexpected value " + s + " found where " + YES + " or " + NO + " was expected.");
}
}
public void setParameter(ParameterSetter setter, Object parameter)
throws SQLException {
boolean b = ((Boolean)parameter).booleanValue();
if (b) {
setter.setString(YES);
} else {
setter.setString(NO);
}
}
public Object valueOf(String s) {
if (YES.equalsIgnoreCase(s)) {
return new Boolean (true);
} else if (NO.equalsIgnoreCase(s)) {
return new Boolean (false);
} else {
throw new SQLException (
"Unexpected value " + s + " found where " + YES + " or " + NO + " was expected.");
}
}
iBATIS๋ด ์ฌ์ฉํ๊ธฐ ์ํ ์ด๋ฌํ ํ์
์ ์ ์ธํ๊ธฐ ์ํด, ๋น์ ์ sqlMapConfig.xml๋ด ๋ค์์ ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ค.
<typeHandler
javaType="boolean"
jdbcType=โVARCHARโ
callback="org.apache.ibatis.sqlmap.extensions.YesNoBoolTypeHandlerCallback"/>
iBATIS ๊ฐ javaํ์
๊ณผ jdbcํ์
๊ฐ์ ์ด์ ์ ๋ค๋ฃจ๋๊ฒ์ ์๊ณ ๋๋ค์, ํน์ ํ์
ํธ๋ค๋ฌ ์ฝ๋ฐฑ์ ์์ฑ๋๋ค.
์บ์ฌ์ํ์ ๋งตํ๋ Statement Results
๋งตํ๋ statement ์ฟผ๋ฆฌ๋ก๋ถํฐ์ result๋ statementํํฌ๋ด์ cacheModelํ๋ผ๋ฏธํฐ๋ฅผ ์ ์ํจ์ผ๋ก์จ ๊ฐ๋จํ๊ฒ ์บ์ฌ๋ ์ ์๋ค.
์บ์ฌ ๋ชจ๋ธ์ ๋น์ ์ SQL Map๋ด์์ ์ ์๋ ์ค์ ๋ ์บ์ฌ๋ค. ์บ์ฌ ๋ชจ๋ธ์ ๋ค์์ฒ๋ผ cacheModel์์๋ฅผ ์ฌ์ฉํด์ ์ค์ ๋๋ค.
<cacheModel id="product-cache" type ="LRU" readOnly=โtrueโ serialize=โfalseโ>
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=โcache-sizeโ value=โ1000โ />
</cacheModel>
28