2017-05-01 8 views
1

JAVA에서 명령 줄 응용 프로그램을 개발 중입니다. 몇 가지 요인에 따라 MySQL 쿼리가 샌드 박스 MySQL 서버에서 실행되고 일부 수동 확인 후에 프로덕션 서버에서 쿼리를 실행해야합니다. 이 MySQL 쿼리를 샌드 박스 서버의 .sql 파일에 기록하고 나중에 스크립트를 사용하여 실행하려고합니다.MyBatis Java의 최종 MySQL 쿼리를 나중에 다른 서버에서 수동으로 실행하려면

스택 오버플로를 통해 검색을 시도했지만 쿼리를 로깅하는 예제가 많이 발견되었지만 기록 된 쿼리는 실행 된 최종 쿼리가 아닙니다. 예 :

Preparing: INSERT into table_name values(null, ?,?, ?,?,?, ?, ?,?); 
DEBUG [pool-4-thread-1] - ==> Parameters: 21655(Integer), 2658413(Integer), 04:05:00(Time), null, 1565.0(Double), 3(String), (String), 0(Integer) 

또한 쿼리는 직접 실행 가능한 형식으로 기록되지 않습니다.

내 log4j.properties 파일 :

log4j.rootLogger=INFO, stdout 
log4j.logger.com.test.mappers.TableMapper=TRACE 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 
log4j.logger.java.sql.PreparedStatement=DEBUG, stdout 

log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG 

log4j.logger.com.ibatis=DEBUG 
log4j.logger.java.sql.Connection=DEBUG 
log4j.logger.java.sql.Statement=DEBUG 
log4j.logger.java.sql.PreparedStatement=DEBUG 
log4j.logger.java.sql.ResultSet=DEBUG 

내가 별도로 .SQL 파일에 정확한 최종 MySQL의 쿼리를 로그인 할 수 있습니까?

+0

에 로거? –

+0

@YCF_L 답장을 보내 주셔서 감사합니다. log4jdbc-log4j2를 사용하고 정확한 Mysql 쿼리를 별도의 파일에 기록하는 사용자 정의 로그 위임자를 사용하여 해결책을 찾았습니다. – Saheb

+0

당신은 미래의 다른 사람들에게 도움이 될지도 모른다. –

답변

0

많은 것을 시도한 후에 Mybatis 및 log4j에서만 가능하다는 것을 알았습니다. 요청을 JDBC 드라이버에 기록 할 수있는 프록시 드라이버가 필요합니다.

나는 별도의 파일로 SQL 쿼리를 보낼 LOG4JDBC_SQL 마커 here에서 log4jdbc2를 사용하는 아이디어를 발견했다. 하지만이 파일에는 실행에 소요 된 대략적인 시간과 연결 번호가 포함됩니다. 그래서 그들을 없애기 위해 나는 커스텀 스파이 로그 위임자를 썼다.

log4jdbc2의 설치 및 구성은 here입니다.

내가 원하는 결과를 얻기를 위해 촬영 한 단계를 다시 작성합니다 log4jdbc2에 대한

  • 추가 받는다는 의존성. log4jdbc2는 log4j-api 및 log4j-core에 의존하며 프로젝트에 포함되어 있는지 확인하십시오.

    <dependency> 
        <groupId>org.bgee.log4jdbc-log4j2</groupId> 
        <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> 
        <version>1.16</version> 
    </dependency> 
    
  • 는 펜더를 작성 net.sf.log4jdbc.sql.jdbcapi.DriverSpy

  • 에 드라이버를 사용 변경 jdbc:log4jdbc:mysql://localhost:3306/mydb

  • jdbc:mysql://localhost:3306/mydb에서 JDBC URL을 변경 만 SQL 쿼리를 필터링 할 LOG4JDBC_SQL 마커로 로거를 만들었습니다.

    <Appenders> 
        <File name="queryLog" fileName="/Users/sahebpreetsingh/queries.sql" 
        immediateFlush="false" append="false"> 
         <PatternLayout pattern="%msg%n" /> 
        </File> 
    </Appenders> 
    
    <Loggers> 
        <logger name="log4jdbc.log4j2" level="info" additivity="false"> 
         <MarkerFilter marker="LOG4JDBC_SQL" onMatch="ACCEPT" 
         onMismatch="DENY" /> 
         <appender-ref ref="queryLog" /> 
        </logger> 
    </Loggers> 
    

    여기 마커는 SQL 쿼리를 필터링하고 그 결과의 나머지 부분을 무시하도록 지정합니다.

  • 기존 Log4j2SpyLogDelegator를 확장하여 시간을 절약하고 sql 쿼리 만 실행 가능한 형식으로 기록합니다.

    package com.myapp.utils; 
    
    import org.apache.logging.log4j.LogManager; 
    import org.apache.logging.log4j.Logger; 
    import org.apache.logging.log4j.Marker; 
    import org.apache.logging.log4j.MarkerManager; 
    
    import net.sf.log4jdbc.Properties; 
    import net.sf.log4jdbc.log.log4j2.Log4j2SpyLogDelegator; 
    import net.sf.log4jdbc.sql.Spy; 
    
    public class QueryLogDelegator extends Log4j2SpyLogDelegator { 
    
        private static final Logger LOGGER = LogManager.getLogger("log4jdbc.log4j2"); 
    
        private static final Marker SQL_MARKER = MarkerManager.getMarker("LOG4JDBC_SQL"); 
    
        private static final Marker SELECT_MARKER = MarkerManager.getMarker("LOG4JDBC_SELECT", SQL_MARKER); 
    
        private static final Marker INSERT_MARKER = MarkerManager.getMarker("LOG4JDBC_INSERT", SQL_MARKER); 
    
        private static final Marker UPDATE_MARKER = MarkerManager.getMarker("LOG4JDBC_UPDATE", SQL_MARKER); 
    
        private static final Marker DELETE_MARKER = MarkerManager.getMarker("LOG4JDBC_DELETE", SQL_MARKER); 
    
        private static final Marker CREATE_MARKER = MarkerManager.getMarker("LOG4JDBC_CREATE", SQL_MARKER); 
    
        private String getSqlOperation(String sql) { 
         if (sql == null) { 
          return ""; 
         } 
         sql = sql.trim(); 
    
         if (sql.length() < 6) { 
          return ""; 
         } 
         return sql.substring(0, 6).toLowerCase(); 
        } 
    
        private boolean shouldSqlBeLogged(String operation) { 
         return ((operation == null) || ((Properties.isDumpSqlSelect()) && ("select".equals(operation))) 
           || ((Properties.isDumpSqlInsert()) && ("insert".equals(operation))) || ((Properties.isDumpSqlUpdate()) && ("update".equals(operation))) 
           || ((Properties.isDumpSqlDelete()) && ("delete".equals(operation))) || ((Properties.isDumpSqlCreate()) && ("create".equals(operation)))); 
        } 
    
        @Override 
        public void sqlTimingOccurred(Spy spy, long execTime, String methodCall, String sql) { 
         String operation = getSqlOperation(sql); 
         if ((Properties.isDumpSqlFilteringOn()) && (!(shouldSqlBeLogged(operation)))) { 
          return; 
         } 
    
         Marker marker = getStatementMarker(operation); 
    
         if ((Properties.isSqlTimingErrorThresholdEnabled()) && (execTime >= Properties.getSqlTimingErrorThresholdMsec())) { 
          LOGGER.error(marker, sql); 
         } else if (LOGGER.isWarnEnabled()) 
          if ((Properties.isSqlTimingWarnThresholdEnabled()) && (execTime >= Properties.getSqlTimingWarnThresholdMsec())) { 
           LOGGER.warn(marker, sql); 
          } else 
           LOGGER.info(marker, sql); 
        } 
    
        private Marker getStatementMarker(String operation) { 
         if (operation == null) 
          return SQL_MARKER; 
         if ("select".equals(operation)) 
          return SELECT_MARKER; 
         if ("insert".equals(operation)) 
          return INSERT_MARKER; 
         if ("update".equals(operation)) 
          return UPDATE_MARKER; 
         if ("delete".equals(operation)) 
          return DELETE_MARKER; 
         if ("create".equals(operation)) { 
          return CREATE_MARKER; 
         } 
         return SQL_MARKER; 
        } 
    
    } 
    
  • 추가 당신은 당신의 코드를하시기 바랍니다 공유 할 수 있습니다 log4jdbc.log4j2.properties

    log4jdbc.dump.sql.addsemicolon=true 
    log4jdbc.spylogdelegator.name=com.myapp.QueryLogDelegator