Spring boot Mybatis Plus 日志打印插件

插件類

import java.lang.reflect.Field;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
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.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.util.ReflectionUtils;


@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class }),
        @Signature(type = StatementHandler.class, method = "update", args = { Statement.class }),
        @Signature(type = StatementHandler.class, method = "batch", args = { Statement.class }) })
public class MybatisSqlPrintIntercepter implements Interceptor, Ordered {
    private static final Logger logger = LoggerFactory.getLogger(MybatisSqlPrintIntercepter.class);
    private Configuration configuration = null;

    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT_THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        }
    };

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        long startTime = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            try {
                long endTime = System.currentTimeMillis();
                long sqlCost = endTime - startTime;
                StatementHandler statementHandler = (StatementHandler) target;
                BoundSql boundSql = statementHandler.getBoundSql();
                if (configuration == null) {
                    final DefaultParameterHandler parameterHandler = (DefaultParameterHandler) statementHandler
                            .getParameterHandler();
                    Field configurationField = ReflectionUtils.findField(parameterHandler.getClass(), "configuration");
                    ReflectionUtils.makeAccessible(configurationField);
                    this.configuration = (Configuration) configurationField.get(parameterHandler);
                }
                // 替換參數(shù)格式化Sql語句棍掐,去除換行符
                String sql = formatSql(boundSql, configuration).concat(";");
                String  warning = "";
                if(sqlCost > 100) {
                    warning  = "[耗時(shí)過長(zhǎng)]";
                }
                logger.info("SQL==> {}    執(zhí)行耗時(shí):{} ms {}", sql, sqlCost,warning);

            } catch (Exception e) {
                logger.error("==> 打印sql 日志異常 {}",e);
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

    /**
     * 獲取完整的sql實(shí)體的信息
     *
     * @param boundSql
     * @return
     */
    private String formatSql(BoundSql boundSql, Configuration configuration) {
        String sql = boundSql.getSql();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        Object parameterObject = boundSql.getParameterObject();
        // 輸入sql字符串空判斷
        if (StringUtils.isBlank(sql)) {
            return "";
        }
        if (configuration == null) {
            return "";
        }
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        sql = beautifySql(sql);
        // 參考mybatis 源碼 DefaultParameterHandler
        if (parameterMappings != null) {
            for (ParameterMapping parameterMapping : parameterMappings) {
                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);
                    }
                    String paramValueStr = "";
                    if (value instanceof String) {
                        paramValueStr = "'" + value + "'";
                    } else if (value instanceof Date) {
                        paramValueStr = "'" + DATE_FORMAT_THREAD_LOCAL.get().format(value) + "'";
                        DATE_FORMAT_THREAD_LOCAL.remove();
                    } else {
                        paramValueStr = value + "";
                    }
                    sql = sql.replaceFirst("\\?", paramValueStr);


                }
            }
        }
        return sql;
    }

    private String beautifySql(String sql) {
        sql = sql.replaceAll("[\\s\n ]+", " ");
        return sql;
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

}

注入

import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @Description
 * @Author
 * @Date
 */
@Configuration
public class MybatisPlusConfig {
    /**
     *   mybatis-plus分頁(yè)插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }

    @Bean
    public MybatisSqlPrintIntercepter mybatisSqlPrintIntercepter() {
        return new MybatisSqlPrintIntercepter();
    }


}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末招拙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姨伟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡套菜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門设易,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逗柴,“玉大人,你說我怎么就攤上這事顿肺∠纺纾” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵屠尊,是天一觀的道長(zhǎng)旷祸。 經(jīng)常有香客問我,道長(zhǎng)讼昆,這世上最難降的妖魔是什么托享? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮浸赫,結(jié)果婚禮上闰围,老公的妹妹穿的比我還像新娘。我一直安慰自己掺炭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布凭戴。 她就那樣靜靜地躺著涧狮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上者冤,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天肤视,我揣著相機(jī)與錄音,去河邊找鬼涉枫。 笑死邢滑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的愿汰。 我是一名探鬼主播困后,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼衬廷!你這毒婦竟也來了摇予?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吗跋,失蹤者是張志新(化名)和其女友劉穎侧戴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跌宛,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酗宋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疆拘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜕猫。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖入问,靈堂內(nèi)的尸體忽然破棺而出丹锹,到底是詐尸還是另有隱情,我是刑警寧澤芬失,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布楣黍,位于F島的核電站,受9級(jí)特大地震影響棱烂,放射性物質(zhì)發(fā)生泄漏租漂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一颊糜、第九天 我趴在偏房一處隱蔽的房頂上張望哩治。 院中可真熱鬧,春花似錦衬鱼、人聲如沸业筏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒜胖。三九已至消别,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間台谢,已是汗流浹背寻狂。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朋沮,地道東北人蛇券。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像樊拓,于是被迫代替她去往敵國(guó)和親纠亚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 今天感恩節(jié)哎骑脱,感謝一直在我身邊的親朋好友菜枷。感恩相遇!感恩不離不棄叁丧。 中午開了第一次的黨會(huì)啤誊,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,566評(píng)論 0 11
  • 彩排完,天已黑
    劉凱書法閱讀 4,218評(píng)論 1 3
  • 表情是什么拥娄,我認(rèn)為表情就是表現(xiàn)出來的情緒蚊锹。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了稚瘾,難過就哭了牡昆。兩者是相互影響密不可...
    Persistenc_6aea閱讀 125,053評(píng)論 2 7