import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import com.github.vertical_blank.sqlformatter.SqlFormatter;
import java.util.List;
import java.util.Properties;
@Intercepts({
@Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
)
})
public class ParameterReplacingInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 쿼리 정보 가져오기
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameterObject = args[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
// 원본 SQL 및 파라미터 처리
String modifiedSql = replacePlaceholdersWithParameterNames(boundSql);
// 로그 출력
System.out.println("Modified SQL:");
System.out.println(modifiedSql);
// 실제 실행
return invocation.proceed();
}
private String replacePlaceholdersWithParameterNames(BoundSql boundSql) {
String sql = boundSql.getSql(); // 원본 SQL
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
Object parameterObject = boundSql.getParameterObject();
// SQL을 포매팅
String prettySql = SqlFormatter.format(sql);
StringBuilder modifiedSql = new StringBuilder(prettySql);
int questionMarkIndex = 0;
// `?`를 순차적으로 파라미터 이름으로 치환
for (ParameterMapping parameterMapping : parameterMappings) {
String paramName = parameterMapping.getProperty();
Object value = boundSql.getAdditionalParameter(paramName);
// AdditionalParameter에서 값을 찾지 못하면 parameterObject에서 가져옴
if (value == null && parameterObject instanceof Map) {
Map<?, ?> paramMap = (Map<?, ?>) parameterObject;
value = paramMap.get(paramName);
}
// SQL의 `?`를 `:paramName`로 대체
questionMarkIndex = modifiedSql.indexOf("?", questionMarkIndex);
if (questionMarkIndex != -1) {
modifiedSql.replace(
questionMarkIndex,
questionMarkIndex + 1,
":" + paramName
);
questionMarkIndex += paramName.length() + 1; // 위치 이동
}
}
// 결과 반환
return modifiedSql.toString();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 필요 시 설정 추가
}
}
댓글 없음:
댓글 쓰기