** ๐ 2.1๋จ๊ณ: parameterType์ ์๋ ์๋ฆฌ **
๐ ๋ชฉํ ์์ฝ
์ ๋ฌ ๋ฐฉ์ | ์ค๋ช | ์ฌ์ฉ ์ |
---|---|---|
๋จ์ผ ๊ฐ | ๊ธฐ๋ณธํ ๋๋ ๋ฌธ์์ด ํ๋ ์ ๋ฌ | int , String , ๋ฑ |
Map ๊ฐ์ฒด | Map<String, Object> ๋ก key-value ์ ๋ฌ |
์ฌ๋ฌ ์กฐ๊ฑด ์์ ๋ ์ ์ฉ |
DTO ๊ฐ์ฒด | ์๋ฐ ๊ฐ์ฒด ์ ์ฒด ์ ๋ฌ | Student ์ฒ๋ผ ํ๋๊ฐ ๋ง์ ๊ฒฝ์ฐ |
โ 1) ๋จ์ผ ๊ฐ ์ ๋ฌ ๋ฐฉ์
๐ก ์: ํ๋ (grade)์ด ์ผ์นํ๋ ํ์ ์กฐํ
๐ง ๋งคํผ XML ์์ (StudentMapper1.xml
์ ์ถ๊ฐ ๊ฐ๋ฅ)
<select id="getStudentsByGrade" parameterType="int" resultType="main.Student">
SELECT * FROM student WHERE grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋ ์์
List<Student> list = session.selectList("student.getStudentsByGrade", 1);
#{grade}
๋ ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ผ๋ก, ๋จ์ผ ๊ฐ์ ๊ทธ๋๋ก ๋งคํparameterType="int"
์ ํตํด ์ ์ํ ๊ฐ ํ๋๋ฅผ ๋ฐ๋๋ค๊ณ ๋ช ์
โ 2) Map ์ ๋ฌ ๋ฐฉ์
๐ก ์: ์ด๋ฆ + ํ๋ ์ผ๋ก ๊ฒ์ํ ๋
๐ง ๋งคํผ XML ์์
<select id="searchStudentByNameAndGrade" parameterType="map" resultType="main.Student">
SELECT * FROM student
WHERE irum = #{irum} AND grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋
Map<String, Object> param = new HashMap<>();
param.put("irum", "๊น๋ฏผ์");
param.put("grade", 1);
List<Student> list = session.selectList("student.searchStudentByNameAndGrade", param);
Map
์ ํค์#{}
์์ ์ด๋ฆ์ด ๊ฐ์์ผ ํจ- ๋ค์ค ์กฐ๊ฑด ํํฐ๋ง์ ์์ฃผ ์ ์ฉ
โ 3) ๊ฐ์ฒด ์ ๋ฌ ๋ฐฉ์
๐ก ์: Student
๊ฐ์ฒด ์์ฒด๋ก ๊ฒ์
๐ง ๋งคํผ XML ์์
<select id="searchStudentByObject" parameterType="main.Student" resultType="main.Student">
SELECT * FROM student
WHERE irum = #{irum} AND grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋
Student s = new Student();
s.setIrum("์ด์ํฌ");
s.setGrade(2);
List<Student> list = session.selectList("student.searchStudentByObject", s);
parameterType="main.Student"
: ๊ฐ์ฒด ์ ์ฒด ์ ๋ฌ#{irum}
,#{grade}
๋ ๊ฐ์ฒด ํ๋๋ช ๊ณผ ์ผ์นํด์ผ ํจ
๐ง ์ ๋ฆฌ ์์ฝ
์ ๋ฌ ๋ฐฉ์ | parameterType ๊ฐ | Java ์ ๋ฌ ์ | ํน์ง |
---|---|---|---|
๋จ์ผ ๊ฐ | int , String ๋ฑ |
selectList("id", 1) |
๊ฐ์ฅ ๊ฐ๋จ |
Map | map |
selectList("id", Map) |
์ ์ฐํ ๋ค์ค ์กฐ๊ฑด |
๊ฐ์ฒด | ํด๋์ค ๊ฒฝ๋ก | selectList("id", new Student()) |
ํ๋๋ช ๋งคํ ์๋ ์ฒ๋ฆฌ |
๐งช ๋ค ํ๋ก์ ํธ ์ ์ฉ ์์ (์ถ์ฒ ํ์ฅ)
ID | ์ค๋ช | ์ถ์ฒ ๋ฐฉ์ |
---|---|---|
getStudentsByGrade |
ํน์ ํ๋ ์กฐํ | ๋จ์ผ ๊ฐ (int ) |
searchStudentByNameAndGrade |
์ด๋ฆ + ํ๋ ๋ณตํฉ ์กฐ๊ฑด | Map |
searchStudentByObject |
DTO ๊ธฐ๋ฐ ํํฐ๋ง | ๊ฐ์ฒด (Student ) |
โ ์ค์ต ์ถ๊ฐ ํ
parameterType
์ ์๋ต ๊ฐ๋ฅํ์ง๋ง ๋ช ์ํ๋ฉด ์ ์ง๋ณด์์ ์ข์#{}
๋ด๋ถ ์ด๋ฆ์ Java์์ ๋๊ธด ๋ณ์๋ช , ๊ฐ์ฒด ํ๋๋ช , Map ํค๋ช ๊ณผ ๋ฐ๋์ ์ผ์นํด์ผ ํจ- ์ฌ๋ฌ ๊ฐ์ ์กฐ๊ฑด์ผ๋ก ๊ฑธ ๋ Map ๋๋ ๊ฐ์ฒด ๋ฐฉ์์ด ํ์คํ ๊น๋ํ๊ณ ์ ์ฐํจ
โ 2.2๋จ๊ณ: SQL ์กฐ๊ฑด์ ๊ณผ ํ๋ผ๋ฏธํฐ ๋งคํ ์ค์ต
(๐ StudentMapper1.xml
ํ์ฅ ๊ธฐ๋ฐ)
๐ฏ ํ์ต ๋ชฉํ
#{}
๊ตฌ๋ฌธ์ด SQL์์ ์ด๋ป๊ฒ ํ์ฉ๋๋์ง ์ดํด- ์ ๋ฌ๋ฐ์ ๋จ์ผ ๊ฐ, Map, DTO ๊ฐ์ฒด๋ฅผ WHERE ์กฐ๊ฑด์ ์ ํ์ฉํ๋ ๋ฒ ํ์ต
- ์๋ชป๋ ํ๋ผ๋ฏธํฐ ๋งคํ ์ ์ค๋ฅ ์์ธ์ ํ์ ํ ์ ์๋๋ก ํ๊ธฐ
โ 1) ๋จ์ผ ํ๋ผ๋ฏธํฐ + WHERE ์กฐ๊ฑด์ ์ค์ต
๐ง ๋งคํผ XML ์์ (StudentMapper1.xml
์ ์ถ๊ฐ ๊ฐ๋ฅ)
<select id="getStudentsByGrade" parameterType="int" resultType="main.Student">
SELECT * FROM student
WHERE grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋
List<Student> list = session.selectList("student.getStudentsByGrade", 1);
๐ง ์๋ ์๋ฆฌ
#{grade}
๋ Java์์ ๋๊ธด int ๊ฐ(1)์ ์์ ํ๊ฒ SQL์ ๋ฐ์ธ๋ฉparameterType="int"
์ ์ ํ์ ์ผ๋ก ๋ช ์ ๊ฐ๋ฅ
โ 2) ๋ค์ค ํ๋ผ๋ฏธํฐ(Map) + ์กฐ๊ฑด์
๐ง ๋งคํผ XML
<select id="searchStudentByNameAndGrade" parameterType="map" resultType="main.Student">
SELECT * FROM student
WHERE irum = #{irum}
AND grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋
Map<String, Object> param = new HashMap<>();
param.put("irum", "๊น๋ฏผ์");
param.put("grade", 1);
List<Student> list = session.selectList("student.searchStudentByNameAndGrade", param);
๐ง ์๋ ์๋ฆฌ
#{irum}
โ"๊น๋ฏผ์"
#{grade}
โ1
Map
์ key ์ด๋ฆ๊ณผ#{}
๋ด๋ถ ์ด๋ฆ์ด ๋ฐ๋์ ์ผ์นํด์ผ ํจ
โ 3) ๊ฐ์ฒด ํ๋ผ๋ฏธํฐ + ์กฐ๊ฑด์
๐ง ๋งคํผ XML
<select id="searchStudentByObject" parameterType="main.Student" resultType="main.Student">
SELECT * FROM student
WHERE irum = #{irum}
AND grade = #{grade}
</select>
๐ง Java ํธ์ถ ์ฝ๋
Student s = new Student();
s.setIrum("์ด์ํฌ");
s.setGrade(2);
List<Student> list = session.selectList("student.searchStudentByObject", s);
๐ง ์๋ ์๋ฆฌ
#{irum}
โs.getIrum()
#{grade}
โs.getGrade()
- ๊ฐ์ฒด์ ํ๋๋ช
์ ๊ทธ๋๋ก
#{}
์์ ์จ์ผ ํจ
โ ๐ ์ค์ ์์ ์์ฃผ ๋์ค๋ ์กฐ๊ฑด์ ๋งคํ ํจํด
์กฐ๊ฑด ์ ํ | SQL ์์ | MyBatis ์์ |
---|---|---|
๋ฌธ์์ด ๋น๊ต | WHERE irum = '๊น๋ฏผ์' |
WHERE irum = #{irum} |
๋ถ๋ถ ๊ฒ์ | WHERE irum LIKE '๊น%' |
WHERE irum LIKE CONCAT(#{keyword}, '%') |
๋ฒ์ | WHERE grade BETWEEN 1 AND 3 |
WHERE grade BETWEEN #{min} AND #{max} |
๋ณตํฉ ์กฐ๊ฑด | WHERE irum = '๊น' AND grade = 1 |
WHERE irum = #{irum} AND grade = #{grade} |
โ SQL ์กฐ๊ฑด์ ๋ฐ์ธ๋ฉ ์ค๋ฅ ์ ํ ์์
์ฆ์ | ์์ธ | ํด๊ฒฐ ๋ฐฉ๋ฒ |
---|---|---|
SQL ๊ตฌ๋ฌธ ์ค๋ฅ | #{} ๊ฐ ์๋ ${} ์ฌ์ฉ |
SQL ์ธ์ ์
์ฐ๋ ค โ #{} ์ฌ์ฉ ๊ถ์ฅ |
๊ฐ์ด null์ธ๋ฐ ํํฐ ์กฐ๊ฑด ํฌํจ | null-safe ์กฐ๊ฑด ํ์ | if ์ฌ์ฉํ์ฌ ์กฐ๊ฑด ๋ถ๊ธฐ ์ฒ๋ฆฌ |
#{} ์ ์ด๋ฆ์ด Java ํ๋/Map key์ ๋ถ์ผ์น |
๋งคํ ์คํจ | ์ ํํ ๋์ผํ ์ด๋ฆ ์ฌ์ฉ ํ์ |
โ ์ ๋ฆฌ ์์ฝ
ํฌ์ธํธ | ์ค๋ช |
---|---|
#{} |
Java ๊ฐ โ ์์ ํ๊ฒ SQL์ ์ ๋ฌ (PreparedStatement) |
parameterType |
Java์์ ์ ๋ฌํ๋ ๊ฐ์ ์๋ฃํ ๋ช ์ |
WHERE ์กฐ๊ฑด์ | #{} ๋ก Java ๊ฐ๊ณผ ๋งคํํด์ ๋์ ์ผ๋ก ์กฐ๊ฑด ์ค์ |
์ค๋ฅ ๋ฐฉ์ง | Map key ๋๋ ๊ฐ์ฒด ํ๋๋ช
๊ณผ ๋ฐ๋์ ์ผ์นํด์ผ ํจ |
๐งช ์ค์ต ์ฒดํฌ๋ฆฌ์คํธ
parameterType
์ด ์ ํํ๊ฐ?#{}
์์ ์ด๋ฆ์ด Java ์ ๋ฌ๊ฐ๊ณผ ์ผ์นํ๋๊ฐ?- ์ฝ์์์ ์คํ๋ SQL ๋ก๊ทธ ํ์ธํด๋ณด๊ธฐ (log4j ํ์ฑํ ์)
โ 2.3๋จ๊ณ: MyBatis SQL ๋ก๊ทธ ์ถ๋ ฅ ์ค์ (Log4j ์ ์ฉ ์ค์ต)
๐ฏ ๋ชฉํ ์์ฝ
ํญ๋ชฉ | ์ค๋ช |
---|---|
๋ชฉ์ | SQL ์คํ ๋ก๊ทธ + ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ์์์ ํ์ธ |
์ฌ์ฉ ๋๊ตฌ | Log4j (MyBatis๊ฐ ์ง์ํ๋ ๋ํ ๋ก๊น ํ๋ ์์ํฌ) |
์ค์ ์์น | src/log4j.properties ๋๋ src/resources/log4j.xml |
ํ์ธ ํญ๋ชฉ | ์คํ๋ SQL ๋ฌธ์ฅ, ๋ฐ์ธ๋ฉ๋ ์ค์ ๊ฐ, ์๋ฌ ๋ฐ์ ์ ์์น |
โ 1. ๋ก๊ทธ ์ถ๋ ฅ ์ค์ ์ค๋น
โ
ํ์ํ JAR ํ์ผ (๋์ lib
ํด๋์ ์์ด์ผ ํจ)
ํ์ผ๋ช | ์ค๋ช |
---|---|
log4j-1.2.17.jar |
๋ก๊ทธ ์ถ๋ ฅ ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ |
slf4j-api-*.jar |
๋ก๊น ์ธํฐํ์ด์ค |
slf4j-log4j12-*.jar |
slf4j โ log4j ์ฐ๊ฒฐ ์ด๋ํฐ |
๐ ๊ฒฝ๋ก: WebContent/WEB-INF/lib/
โ ๋์ zip ํ์ผ ์์ ์ด JAR๋ค์ด ์ด๋ฏธ ์กด์ฌํ๋์ง ํ์ธ ํ, ์์ผ๋ฉด ์๋ ์ถ๊ฐ ํ์
โ
2. log4j.properties
์ค์ ํ์ผ ๋ง๋ค๊ธฐ
๐ ํ์ผ ์์ฑ ์์น: src/log4j.properties
# ๊ธฐ๋ณธ ๋ก๊ทธ ๋ ๋ฒจ ์ค์
log4j.rootLogger=DEBUG, stdout
# ์ฝ์ ์ถ๋ ฅ ์ค์
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] %c - %m%n
# MyBatis SQL ๋ก๊ทธ ํ์ธ
log4j.logger.org.apache.ibatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
โ 3. ๋ก๊ทธ ํ์ธ ์์
์๋ฅผ ๋ค์ด ๋ค์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ์ ๋:
Student s = new Student();
s.setIrum("์ด์ํฌ");
s.setGrade(2);
List<Student> list = session.selectList("student.searchStudentByObject", s);
โ ๋ก๊ทธ ์์ (์ฝ์ ์ถ๋ ฅ)
2025-04-17 10:12:45 [DEBUG] org.apache.ibatis.logging - ==> Preparing: SELECT * FROM student WHERE irum = ? AND grade = ?
2025-04-17 10:12:45 [DEBUG] org.apache.ibatis.logging - ==> Parameters: ์ด์ํฌ(String), 2(Integer)
โ 4. ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋์ง ์์ ๊ฒฝ์ฐ ์ฒดํฌ์ฌํญ
์ฆ์ | ์์ธ | ํด๊ฒฐ ๋ฐฉ๋ฒ |
---|---|---|
์ฝ์์ ์๋ฌด ๋ก๊ทธ๋ ์ ๋์ด | log4j.properties ์์น๊ฐ classpath ๋ฐ | src ํด๋์ ์ ํํ ์์นํด์ผ ํจ |
์๋ฌ๋ง ์ถ๋ ฅ๋๊ณ SQL์ ์ ๋์ด | org.apache.ibatis ๋ก๊ทธ ๋ ๋ฒจ ๋๋ฝ |
DEBUG ์ค์ ํ์ |
๋ก๊ทธ๊ฐ ๊นจ์ง | ํจํด ์ค์ ์ค๋ฅ | ConversionPattern ๋ค์ ํ์ธ |
โ ์ค์ต ์ฒดํฌ๋ฆฌ์คํธ
log4j.properties
๋src
์ ์ ํํ ์์นํ๋๊ฐ?mybatis-config.xml
๊ณผ ๋ก๊ทธ ์ค์ ์ด ์ถฉ๋ํ์ง ์๋๊ฐ?- ๋ก๊ทธ์
Preparing
,Parameters
๊ฐ ์ถ๋ ฅ๋๋๊ฐ? - ์๋ฌ ๋ฐ์ ์ ์์น์ SQL๋ ํจ๊ป ๋ณด์ด๋๊ฐ?
โ ์ ๋ฆฌ ์์ฝ
ํญ๋ชฉ | ์ค๋ช |
---|---|
log4j ์ค์ | ์ฝ์ ๋ก๊ทธ ํ์ธ์ฉ |
logger ์ค์ | org.apache.ibatis , java.sql.PreparedStatement ๋ฑ |
ํ์ธํ ๋ก๊ทธ | Preparing(์ฟผ๋ฆฌ), Parameters(ํ๋ผ๋ฏธํฐ) |
์์น | ๋ฐ๋์ src/log4j.properties ์ ์์ด์ผ ํจ |
โ 2.4๋จ๊ณ: #{} vs ${} ์ฐจ์ด & SQL Injection ๋ฐฉ์ง ์ค์ต
(๐ StudentMapper1.xml
์ ์ฉ ๊ฐ๋ฅ)
๐ฏ ๋ชฉํ ์์ฝ
ํญ๋ชฉ | ์ค๋ช |
---|---|
๋ชฉ์ | #{} ์ ${} ์ ์ฐจ์ด์ ๊ณผ ๋ณด์ ์ํ์ฑ์ ์ดํด |
๋ณด์ | SQL Injection์ ๋ฐฉ์งํ๋ ์์ ํ ๋ฐฉ๋ฒ ์ตํ๊ธฐ |
์ค์ต | ์ ์ ๋ฐ์ธ๋ฉ vs ๋์ ๋ฌธ์์ด ์ฝ์ ์ ์ฐจ์ด ๋น๊ต |
โ
1. #{}
vs ${}
์ฐจ์ด ํต์ฌ ์์ฝ
ํญ๋ชฉ | #{} |
${} |
---|---|---|
์๋ฏธ | PreparedStatement์ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ | SQL ๋ฌธ์์ด ์นํ |
์ฒ๋ฆฌ ๋ฐฉ์ | ? ๋ก ์นํ๋์ด ์๋ฒ์์ ๊ฐ ๋ฐ์ธ๋ฉ | SQL์ ๋ฌธ์์ด ์ง์ ์ฝ์ |
๋ณด์ | SQL Injection ๋ฐฉ์ง ๊ฐ๋ฅ | โ ๏ธ SQL Injection ์ํ ๋์ |
์ฉ๋ | ์ผ๋ฐ ์กฐ๊ฑด์ ๊ฐ ๋ฐ์ธ๋ฉ | ์ปฌ๋ผ๋ช , ํ ์ด๋ธ๋ช , ORDER BY ๊ฐ์ ๊ตฌ์กฐ ์กฐ๋ฆฝ ์๋ง ์ฌ์ฉ |
โ 2. ์ค์ต ์์ ๋น๊ต
๐ก ์์ ํ ๋ฐฉ์ โ #{}
(๊ถ์ฅ)
<select id="getStudentByName" parameterType="string" resultType="main.Student">
SELECT * FROM student WHERE irum = #{irum}
</select>
String name = "์ด์ํฌ";
List<Student> list = session.selectList("student.getStudentByName", name);
โ ์ถ๋ ฅ ๋ก๊ทธ ์์ (log4j ์ค์ ์)
Preparing: SELECT * FROM student WHERE irum = ?
Parameters: ์ด์ํฌ(String)
โ ๏ธ ์ํํ ๋ฐฉ์ โ ${}
(SQL Injection ๊ฐ๋ฅ)
<select id="getStudentByNameUnsafe" parameterType="string" resultType="main.Student">
SELECT * FROM student WHERE irum = '${irum}'
</select>
String name = "' OR '1'='1";
List<Student> list = session.selectList("student.getStudentByNameUnsafe", name);
โ ์คํ๋๋ SQL ์:
SELECT * FROM student WHERE irum = '' OR '1'='1'
โก๏ธ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์กฐํ๋จ โ SQL Injection ๊ณต๊ฒฉ ์ฑ๊ณต
โ
3. ์ปฌ๋ผ๋ช
์ ${}
์ฐ๋ ์์ ํ ์ (์ ์ ๊ตฌ์กฐ ์กฐ๋ฆฝ์ฉ)
<select id="getStudentsSorted" parameterType="string" resultType="main.Student">
SELECT * FROM student ORDER BY ${sortColumn}
</select>
String sortColumn = "grade"; // ์ธ๋ถ ์
๋ ฅ์ด๋ฉด ๋ฐ๋์ ํ์ดํธ๋ฆฌ์คํธ ์ฒดํฌ!
List<Student> list = session.selectList("student.getStudentsSorted", sortColumn);
โ ์ฃผ์:
sortColumn
๊ฐ์"hakbun"
,"grade"
๋ฑ ์ฌ์ ๊ฒ์ฆ๋ ๊ฐ๋ง ํ์ฉํด์ผ ํจ- ์ฌ์ฉ์๊ฐ ์ง์ ์
๋ ฅํ ๋ฌธ์์ด์
${}
์ ๋ฃ๋ ๊ฑด ๋งค์ฐ ์ํ
โ ์ค์ต ์ฒดํฌ๋ฆฌ์คํธ
ํญ๋ชฉ | ํ์ธ ์ฌ๋ถ |
---|---|
WHERE ์กฐ๊ฑด, ๊ฐ ๋น๊ต์๋ ๋ฌด์กฐ๊ฑด #{} ์ฌ์ฉ |
โ |
${} ๋ ๊ตฌ์กฐ์ ์กฐ๋ฆฝ์์๋ง ์ ํ์ ์ผ๋ก ์ฌ์ฉ |
โ |
์ธ๋ถ ๋ฌธ์์ด์ด ${} ์ ๋ค์ด๊ฐ์ง ์๋๋ก ํํฐ๋ง |
โ |
๋ก๊ทธ ์ถ๋ ฅ ์ Preparing: โ ? ์ฌ์ฉ๋๋์ง ํ์ธ |
โ |
โ ์ ๋ฆฌ ์์ฝ
ํญ๋ชฉ | #{} |
${} |
---|---|---|
๋ด๋ถ ๋์ | ? ๋ก ์นํ + ์์ ํ ๊ฐ ๋ฐ์ธ๋ฉ | ๋ฌธ์์ด ์ง์ ์ฝ์ (์นํ) |
SQL Injection | ๋ฐฉ์ง ๊ฐ๋ฅ (๊ถ์ฅ) | ์ํ ๋งค์ฐ ๋์ |
์ฌ์ฉ ์์น | WHERE, SET, INSERT VALUES ๋ฑ ๊ฐ ๋ฐ์ธ๋ฉ | ํ ์ด๋ธ๋ช /์ปฌ๋ผ๋ช ์กฐ๋ฆฝ ์๋ง |
์์ | WHERE name = #{name} |
ORDER BY ${column} |
๐ง ์ค๋ฌด ๋ณด์ ํ
${}
๋ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ ๋ ์ง์ ๋ฃ์ง ๋ง ๊ฒ!- ๋ฐ๋์ ์๋ฒ ์ฝ๋์์ ํ์ฉ๋ ๊ฐ๋ง ๋๊ธฐ๋๋ก ํํฐ๋ง
- log4j๋ก SQL ๋ก๊ทธ ์ถ๋ ฅํด์ ์ค์ SQL ํ์ธํ๋ฉฐ ๋๋ฒ๊น ํ ๊ฒ