Java tutorial
/** * Copyright (c) 2011-2014, hubin (jobob@qq.com). * * 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 com.mybatisX.plugins; import java.util.ArrayList; import java.util.List; import java.util.Properties; 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.mapping.ParameterMode; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; 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 com.mybatisX.exceptions.MybatisXException; import com.mybatisX.toolkit.SqlUtils; import com.mybatisX.toolkit.StringUtils; import com.mybatisX.toolkit.SystemClock; /** * <p> * ??? SQL ?? * </p> * * @author hubin * @Date 2016-07-07 */ @Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }), @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) }) public class PerformanceInterceptor implements Interceptor { /** * SQL ??? */ private long maxTime = 0; private boolean format = false; public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameterObject = null; if (invocation.getArgs().length > 1) { parameterObject = invocation.getArgs()[1]; } String statementId = mappedStatement.getId(); BoundSql boundSql = mappedStatement.getBoundSql(parameterObject); Configuration configuration = mappedStatement.getConfiguration(); String sql = SqlUtils.sqlFormat(boundSql.getSql(), format); List<String> params = getParams(boundSql, parameterObject, configuration); long start = SystemClock.now(); Object result = invocation.proceed(); long end = SystemClock.now(); long timing = end - start; System.err.println(" Time" + timing + " ms" + " - ID" + statementId + "\n SQL Params:" + params.toString() + "\n Execute SQL" + sql + "\n"); if (maxTime >= 1 && timing > maxTime) { throw new MybatisXException(" The SQL execution time is too large, please optimize ! "); } return result; } public Object plugin(Object target) { if (target instanceof Executor) { return Plugin.wrap(target, this); } return target; } public void setProperties(Properties prop) { // TODO } private List<String> getParams(BoundSql boundSql, Object parameterObject, Configuration configuration) { List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); List<String> params = new ArrayList<String>(); if (parameterMappings != null) { for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (parameterObject == null) { value = null; } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else { MetaObject metaObject = configuration.newMetaObject(parameterObject); value = metaObject.getValue(propertyName); } params.add(StringUtils.sqlParam(value)); } } } return params; } public long getMaxTime() { return maxTime; } public void setMaxTime(long maxTime) { this.maxTime = maxTime; } public boolean isFormat() { return format; } public void setFormat(boolean format) { this.format = format; } }