/************************************************************************
|
Licensed under the Apache License, Version 2.0 (the "License");
|
you may not use this file except in compliance with the License.
|
You may obtain a copy of the License at
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
Unless required by applicable law or agreed to in writing, software
|
distributed under the License is distributed on an "AS IS" BASIS,
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
See the License for the specific language governing permissions and
|
limitations under the License.
|
************************************************************************/
|
package core.plugin.mybatis;
|
|
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.reflection.MetaObject;
|
import org.apache.ibatis.session.Configuration;
|
import org.apache.ibatis.session.ResultHandler;
|
import org.apache.ibatis.session.RowBounds;
|
import org.apache.ibatis.type.TypeHandlerRegistry;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.text.DateFormat;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Locale;
|
import java.util.Properties;
|
|
/**
|
* <p>
|
* 记录MyBatis执行SQL拦截器
|
* </p>
|
*
|
* @author CSJ (raulcsj@126.com)
|
* @version 1.0
|
*/
|
@Intercepts({
|
@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
|
@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
|
RowBounds.class, ResultHandler.class }) })
|
public class ExecuteSqlLogInterceptor implements Interceptor {
|
|
private static final Logger L = LoggerFactory.getLogger(ExecuteSqlLogInterceptor.class);
|
|
@Override
|
public Object intercept(Invocation invocation) throws Throwable {
|
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
|
Object parameter = null;
|
if (invocation.getArgs().length > 1) {
|
parameter = invocation.getArgs()[1];
|
}
|
String sqlId = mappedStatement.getId();
|
L.debug("Execute: " + sqlId);
|
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
|
Configuration configuration = mappedStatement.getConfiguration();
|
// configuration.getEnvironment().getDataSource().getConnection();
|
Object returnValue;
|
long start = System.currentTimeMillis();
|
returnValue = invocation.proceed();
|
long end = System.currentTimeMillis();
|
long execTime = (end - start);
|
String exexcSql = getRuntimeExeSql(configuration, boundSql);
|
L.debug(String.format("Execute '%s' cost %d ms", exexcSql, execTime));
|
|
return returnValue;
|
}
|
|
@Override
|
public Object plugin(Object target) {
|
return Plugin.wrap(target, this);
|
}
|
|
@Override
|
public void setProperties(Properties props) {
|
}
|
|
private static String getRuntimeExeSql(Configuration configuration, BoundSql boundSql) {
|
Object parameterObject = boundSql.getParameterObject();
|
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
|
if (parameterMappings.size() > 0 && parameterObject != null) {
|
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
|
sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
|
} else {
|
MetaObject metaObject = configuration.newMetaObject(parameterObject);
|
for (ParameterMapping parameterMapping : parameterMappings) {
|
String propertyName = parameterMapping.getProperty();
|
if (metaObject.hasGetter(propertyName)) {
|
Object obj = metaObject.getValue(propertyName);
|
sql = sql.replaceFirst("\\?", getParameterValue(obj));
|
} else if (boundSql.hasAdditionalParameter(propertyName)) {
|
Object obj = boundSql.getAdditionalParameter(propertyName);
|
sql = sql.replaceFirst("\\?", getParameterValue(obj));
|
}
|
}
|
}
|
}
|
return sql;
|
}
|
|
private static String getParameterValue(Object obj) {
|
String value;
|
if (obj instanceof String) {
|
value = "'" + obj.toString() + "'";
|
} else if (obj instanceof Date) {
|
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
|
value = "'" + formatter.format(new Date()) + "'";
|
} else {
|
if (obj != null) {
|
value = obj.toString();
|
} else {
|
value = "";
|
}
|
}
|
return value;
|
}
|
}
|