Spring Framrwork

Mybatis SQL Logging

gregorio 2019. 4. 28. 14:44

Mybatis 사용 시 SQL LOG를 Log 파일에 추가하는 Source Code이다.

BoundSql을 사용하면 파라미터를 SQL에 매핑하지 못하는데 이를 해결하기 위해

SQL 호출 시 사용하는 Value Object를 파라미터를 받아 Field Name과 Value를 Map으로

변환하여 SQL의 파라미터와 매핑한다.

 

public class SqlLogger {

private static final Logger SQL = LoggerFactory.getLogger("sqllog");

/**
 * Logging SQL with parameter
 * @param sqlId
 * @param params
 * @throws Exception
 */
public static void logging(String sqlId, Object params) throws Exception {

SqlSessionFactory sqlSessionFactory = BaseContext.getBean("sqlSessionFactory");

SqlSession session = sqlSessionFactory.openSession();
MappedStatement ms = session.getConfiguration().getMappedStatement(sqlId);
BoundSql boundSql = ms.getBoundSql(params);
List mappedParams = boundSql.getParameterMappings();
String  finalSql = boundSql.getSql();
    finalSql = finalSql.trim();
    finalSql = finalSql.replaceAll("\\s+", " ");
        if (params instanceof String || params instanceof Integer || params instanceof Long) {
     finalSql = finalSql.replaceFirst("\\?", String.valueOf(params));
        }
        else {
     Map<String, Object > fieldInfo = fieldInfo(params);
         for (ParameterMapping pm : mappedParams) {
          if (fieldInfo.containsKey(pm.getProperty())) {
          String value = null;
          if (fieldInfo.get(pm.getProperty()) instanceof String) {
          value = String.format("'%s'", String.valueOf(fieldInfo.get(pm.getProperty())));
          }
          else {
          value = String.valueOf(fieldInfo.get(pm.getProperty()));
          }
                 finalSql = finalSql.replaceFirst("\\?", value);
             }
         }        
        }
SQL.info("{}", finalSql);
}

/**
 * Extract object field value
 * @param object
 * @return
 * @throws Exception
 */
public static Map<String, Object> fieldInfo(Object object) throws Exception {
Map<String, Object> fieldInfo = new HashMap<String, Object>();

List fields = FieldUtils.getAllFieldsList(object.getClass());
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(object) != null ? field.get(object) : "";
fieldInfo.put(field.getName(), value);
}
return fieldInfo;
}
}