Spring Boot + Log4jdbc + MyBatis์์ /* NOT_SQL_LOG */ ์ฃผ์์ผ๋ก SQL ๋ก๊ทธ ์ ์ธํ๊ธฐ
โจ ๊ฐ์
์ค์ ๊ฐ๋ฐ์์๋ ๋ก๊ทธ์ SQL์ด ์ฐํ๋ ๊ฒ ์ ์ฉํ ๋๊ฐ ๋ง์ง๋ง,
โ
๋ฏผ๊ฐํ ์ฟผ๋ฆฌ๋
โ
๋๋ฌด ์์ฃผ ํธ์ถ๋๋ ๋ฐ๋ณต ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ, ๋ก๊ทธ๋ฅผ ๊น๋ํ๊ฒ ๊ด๋ฆฌํ๊ณ ์ ๋ก๊ทธ ์ถ๋ ฅ์ ์ ์ธํ๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค.
Spring Boot + Log4jdbc ํ๊ฒฝ์์,
/* NOT_SQL_LOG */๋ผ๋ ์ฃผ์์ MyBatis XML ํ์ผ์ ์ฝ์
ํ๋ฉด ํด๋น SQL๋ง ๋ก๊ทธ์ ์ถ๋ ฅ๋์ง ์๋๋ก ํํฐ๋งํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํฉ๋๋ค.
๐๏ธ ํ๋ก์ ํธ ํ๊ฒฝ
- Spring Boot: 3.3.4
- Java: 17
- MyBatis + XML ๋งคํผ
- Log4jdbc: 1.16
- Log4j2: 3.3.1
- ๋ก๊ทธ ์ถ๋ ฅ์ log4jdbc-log4j2-jdbc4.1 ์ฌ์ฉ
- SQL ๋ก๊ทธ๋ฅผ ์ปค์คํฐ๋ง์ด์งํ๊ธฐ ์ํ Log4j2 Filter ์ ์ฉ
๐ ์ฌ์ฉ ๋ฐฉ๋ฒ ์์ฝ
- MyBatis SQL XML์ ์ฃผ์ ์ถ๊ฐ
- ์ปค์คํ Log4j2 Filter ์์ฑ
- log4j2.xml์ ํํฐ ๋ฑ๋ก
๐ Step 1. XML ๋งคํผ์ ์ฃผ์ ์ถ๊ฐ
mapper.xml ํ์ผ์ SQL์ ์๋ ์ฃผ์์ ํฌํจ์ํต๋๋ค: (/* NOT_SQL_LOG */)
<select id="getAB">
/* NOT_SQL_LOG */
SELECT * FROM user WHERE id = 5;
</select>
์ด ์ฃผ์์ด ํฌํจ๋ ์ฟผ๋ฆฌ๋ ๋ก๊ทธ์ ์ฐํ์ง ์์ต๋๋ค.
๐ ๏ธ Step 2. ํํฐ ํด๋์ค ์์ฑ
SqlLogFilter ํด๋์ค๋ Log4j2์ ์ปค์คํ ํํฐ๋ก, /* NOT_SQL_LOG */ ๋ฌธ์์ด์ ๊ฐ์งํ์ฌ ๋ก๊ทธ ์ถ๋ ฅ์ ๋ง์ต๋๋ค.
package kr.co.sh.SmartWork.common.util;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.AbstractFilter;
/**
* SQL ๋ก๊ทธ์์
*/
@Plugin(name = "SqlLogFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE)
public class SqlLogFilter extends AbstractFilter {
private static final String NOT_SQL_LOG_COMMENT = "/* NOT_SQL_LOG */";
protected SqlLogFilter(Result onMatch, Result onMismatch) {
super(onMatch, onMismatch);
}
@Override
public Result filter(LogEvent event) {
if (event == null || event.getMessage() == null) {
return Result.NEUTRAL;
}
String message = event.getMessage().getFormattedMessage();
// /* NOT_SQL_LOG */ ์ฃผ์์ด ํฌํจ๋ SQL๋ฌธ์ธ์ง ํ์ธ
if (message.contains(NOT_SQL_LOG_COMMENT)) {
return Result.DENY; // ๋ก๊ทธ ์ถ๋ ฅ ์ฐจ๋จ
}
return Result.NEUTRAL; // ๋ค๋ฅธ ๋ก๊ทธ๋ ์ ์ ์ถ๋ ฅ
}
@PluginFactory
public static SqlLogFilter createFilter(
@PluginAttribute("onMatch") Result onMatch,
@PluginAttribute("onMismatch") Result onMismatch) {
Result match = onMatch != null ? onMatch : Result.NEUTRAL;
Result mismatch = onMismatch != null ? onMismatch : Result.NEUTRAL;
return new SqlLogFilter(match, mismatch);
}
}
๐ ์์น ์์:
kr.co.project.common.util.SqlLogFilter
โ๏ธ Step 3. log4j2.xml์ ํํฐ ๋ฑ๋ก
log4j2.xml์ JDBC ๋ก๊ฑฐ ์ค์ ์ ํํฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค:
<Filters>
<SqlLogFilter onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
์์)

โ ๊ฒฐ๊ณผ ํ์ธ
// ์ด ์ฟผ๋ฆฌ๋ ๋ก๊ทธ์ ์ฐํ
<select id="getBC">
SELECT * FROM attendance WHERE user_id = 1;
</select>
// ์ด ์ฟผ๋ฆฌ๋ ๋ก๊ทธ์ ์ฐํ์ง ์์
<select id="getAB">
/* NOT_SQL_LOG */
SELECT * FROM user WHERE id = 5;
</select>
๐ฏ ์ ๋ฆฌ
| ๋ชฉ์ | ํน์ SQL ๋ก๊ทธ ๊ฐ์ถ๊ธฐ (๋ณด์ or ๋ก๊ทธ ๊ฐ๋ ์ฑ) |
| ๋ฐฉ๋ฒ | /* NOT_SQL_LOG */ ์ฃผ์์ ํ์ฉํ ํํฐ๋ง |
| ์ ์ฉ ๋์ | MyBatis XML ๋งคํผ + log4jdbc ํ๊ฒฝ |
| ์ปค์คํฐ๋ง์ด์ง | log4j2 ํํฐ ํ๋ฌ๊ทธ์ธ์ผ๋ก ์ ์ฐํ๊ฒ ํ์ฅ ๊ฐ๋ฅ |
๐งฉ ํ์ฉ ํ
- ๋ฏผ๊ฐ ์ ๋ณด ์กฐํ ์ฟผ๋ฆฌ (ex. ๋น๋ฐ๋ฒํธ, ์ฃผ๋ฏผ๋ฒํธ ๋ฑ)
- ๋์ฉ๋ ๋ฐฐ์น ๋ฐ๋ณต ์ฟผ๋ฆฌ
- ๋จ์ ํ ์คํธ ์ค ๋ก๊ทธ๊ฐ ๋๋ฌด ๋ง์ ๋
๊ถ๊ธํ ์ ์ด ์๋ค๋ฉด ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์!
๋์์ด ๋์
จ๋ค๋ฉด โญ๏ธ ๊ณต๊ฐ + ์คํฌ๋ฉ ๋ถํ๋๋ ค์!
'๊ฐ๋ฐ ์ผ์ง ๐ฉโ๐ป' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ๐ ๏ธ minSdk์ targetSdk๋ ๊ฐ๋ฐ์๊ฐ ์ค์ ๊ฐ๋ฅํ ๊น? (3) | 2025.06.18 |
|---|---|
| ๐ฑ ์๋๋ก์ด๋ SDK๋ ํฐ ๊ธฐ์ข ์ด ๋ฌด์จ ์๊ด์ด์ผ? (2) | 2025.06.18 |
| Java CopyOnWriteArrayList ์๋ฒฝ ์ ๋ฆฌ (1) | 2025.06.12 |
| cursor ai) maven ํญ์ด ์๋ณด์ผ ๋ ํด๊ฒฐ๋ฒ (3) | 2025.05.26 |
| Spring Boot์์ MariaDB ์คํค๋ง๋ฅผ ๋ค๋ฅธ ์๋ฒ์์ ๋ด ๋ก์ปฌ๋ก ๋ณต์ฌํ๊ธฐ (2) | 2025.05.23 |