日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Mybatis打印替換占位符后的完整Sql教程

瀏覽:28日期:2023-10-22 11:48:10

利用mybtis插件打印完整的sql,將占位符?替換成實際值

import org.apache.ibatis.cache.CacheKey;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.*;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 org.springframework.context.annotation.Profile;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Properties;/** * 打印sql * * @date 2019/1/14 20:13 */@Component@Profile({'dev', 'test'})@Intercepts({ @Signature(type = Executor.class, method = 'query', args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), @Signature(type = Executor.class, method = 'query', args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}), @Signature(type = Executor.class, method = 'update', args = {MappedStatement.class, Object.class})})public class SqlInterceptor implements Interceptor { private static ThreadLocal<SimpleDateFormat> dateTimeFormatter = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); } }; @Override public Object intercept(Invocation invocation) throws Throwable { Object result = null; //捕獲掉異常,不要影響業務 try { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } String sqlId = mappedStatement.getId(); BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); long startTime = System.currentTimeMillis(); try { result = invocation.proceed(); } finally { long endTime = System.currentTimeMillis(); long sqlCostTime = endTime - startTime; String sql = this.getSql(configuration, boundSql); this.formatSqlLog(sqlId, sql, sqlCostTime, result); } return result; } catch (Exception e) { return result; } } @Override public Object plugin(Object target) { if (target instanceof Executor) { return Plugin.wrap(target, this); } return target; } @Override public void setProperties(Properties properties) { } /** * 獲取完整的sql語句 * * @param configuration * @param boundSql * @return */ private String getSql(Configuration configuration, BoundSql boundSql) { // 輸入sql字符串空判斷 String sql = boundSql.getSql(); if (StringUtil.isEmpty(sql)) { return ''; } return formatSql(sql, configuration, boundSql); } /** * 將占位符替換成參數值 * * @param sql * @param configuration * @param boundSql * @return */ private String formatSql(String sql, Configuration configuration, BoundSql boundSql) { //美化sql sql = beautifySql(sql); //填充占位符, 目前基本不用mybatis存儲過程調用,故此處不做考慮 Object parameterObject = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); List<String> parameters = new ArrayList<>(); if (parameterMappings != null) { MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); 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 { value = metaObject == null ? null : metaObject.getValue(propertyName); } if (value instanceof Number) { parameters.add(String.valueOf(value)); } else { StringBuilder builder = new StringBuilder(); builder.append('’'); if (value instanceof Date) { builder.append(dateTimeFormatter.get().format((Date) value)); } else if (value instanceof String) { builder.append(value); } builder.append('’'); parameters.add(builder.toString()); } } } } for (String value : parameters) { sql = sql.replaceFirst('?', value); } return sql; } /** * 格式化sql日志 * * @param sqlId * @param sql * @param costTime * @return */ private void formatSqlLog(String sqlId, String sql, long costTime, Object obj) { String sqlLog = '==> ' + sql; StringBuffer result = new StringBuffer(); if (obj instanceof List) { List list = (List) obj; int count = list.size(); result.append('<== Total: ' + count); } else if (obj instanceof Integer) { result.append('<== Total: ' + obj); } result.append(' Spend Time ==> ' + costTime + ' ms'); Logger log = LoggerFactory.getLogger(sqlId); log.info(sqlLog); log.info(result.toString()); } public static String beautifySql(String sql) { sql = sql.replaceAll('[sn ]+', ' '); return sql; }}

補充知識:Mybatis配置控制臺輸出SQL語句填充占位符

我們使用spring整合mybatis時候,希望根據控制臺輸出的sql語句來復制到Navicat等工具去測試,配置如下

在mybatis的配置文件mybatis-config.xml中配置

<configuration><!-- | 全局配置設置 | | 可配置選項 默認值, 描述 | | aggressiveLazyLoading true, 當設置為‘true’的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。 | multipleResultSetsEnabled true, 允許和不允許單條語句返回多個數據集(取決于驅動需求) | useColumnLabel true, 使用列標簽代替列名稱。不同的驅動器有不同的作法。參考一下驅動器文檔,或者用這兩個不同的選項進行測試一下。 | useGeneratedKeys false, 允許JDBC 生成主鍵。需要驅動器支持。如果設為了true,這個設置將強制使用被生成的主鍵,有一些驅動器不兼容不過仍然可以執行。 | autoMappingBehavior PARTIAL, 指定MyBatis 是否并且如何來自動映射數據表字段與對象的屬性。PARTIAL將只自動映射簡單的,沒有嵌套的結果。FULL 將自動映射所有復雜的結果。 | defaultExecutorType SIMPLE, 配置和設定執行器,SIMPLE 執行器執行其它語句。REUSE 執行器可能重復使用prepared statements 語句,BATCH執行器可以重復執行語句和批量更新。 | defaultStatementTimeout null, 設置一個時限,以決定讓驅動器等待數據庫回應的多長時間為超時 | --><settings> <!-- 這個配置使全局的映射器啟用或禁用緩存 --> <setting name='cacheEnabled' value='true'/> <!-- 全局啟用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載 --> <setting name='lazyLoadingEnabled' value='false'/> <setting name='multipleResultSetsEnabled' value='true'/> <setting name='useColumnLabel' value='true'/> <setting name='logImpl' value='STDOUT_LOGGING' /> <setting name='defaultExecutorType' value='REUSE'/> <setting name='defaultStatementTimeout' value='25000'/> <setting name='aggressiveLazyLoading' value='true'/> </settings> </configuration>

配置上面后就可以在控制臺輸出sql語句了,但是語句與條件會分開輸出,我們想填充sql語句的占位符的話需要再spring整合mybatis中加配置

Mybatis打印替換占位符后的完整Sql教程

只要添加這個即可<!-- Mybatis配置控制臺輸出SQL語句填充占位符-->

<!-- 性能攔截器,兼打印sql,不生產環境配置 --><bean class='com.baomidou.mybatisplus.plugins.PerformanceInterceptor'> <!-- SQL 執行最大時長,超過自動停止運行,有助于發現問題。 --> <property name='maxTime' value='100'></property></bean>

以上這篇Mybatis打印替換占位符后的完整Sql教程就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Mybatis 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩一区电影| 精品成人18| 欧美亚洲国产精品久久| 国产成年精品| 国产精品久久免费视频| 18国产精品| 国产毛片精品| 久久女人天堂| 日本а中文在线天堂| 久久婷婷亚洲| 美女少妇全过程你懂的久久| 亚洲激情另类| 石原莉奈一区二区三区在线观看| 噜噜噜久久亚洲精品国产品小说| 男人的天堂久久精品| 亚洲日本久久| 欧美精品影院| 免费视频一区二区三区在线观看| 精品免费av| 日韩精品91| 国产成人黄色| 99久久亚洲精品| 另类国产ts人妖高潮视频| 日韩有吗在线观看| 欧美国产另类| 久久夜色精品| 日韩精品欧美大片| 麻豆免费精品视频| 日韩精品不卡一区二区| 亚洲激情精品| 久久激五月天综合精品| 精品福利久久久| 日本精品在线中文字幕| 国产亚洲网站| 日韩精品电影一区亚洲| 国产毛片久久久| 日韩电影免费网址| 久久亚洲欧美| 国产精品mv在线观看| 欧美日韩精品免费观看视完整| 黄色免费成人| 国产精品一区二区99| 青青久久av| 亚洲v天堂v手机在线| 久久免费影院| 亚洲成人精选| 欧美日韩亚洲国产精品| а√天堂8资源在线| 鲁大师影院一区二区三区| 国产欧美一区二区三区国产幕精品| 国产伊人久久| 美日韩精品视频| 日韩av片子| 一区二区三区四区精品视频| 国产成人免费精品| 视频一区欧美精品| 欧美www视频在线观看| 另类亚洲自拍| 精品国产免费人成网站| 亚洲最大av| 中文字幕在线视频网站| 蜜桃av一区二区在线观看| 国产高清亚洲| 亚洲专区一区| 日本激情一区| 亚洲欧洲日韩精品在线| 欧美日韩视频网站| 国产日韩欧美一区二区三区在线观看| 免费污视频在线一区| 国产欧美一区二区三区米奇| 99热精品在线| 精品久久国产一区| 蜜桃视频在线观看一区| 亚洲伦乱视频| 国产欧美日韩精品一区二区免费 | 久久久久久免费视频| 视频一区日韩精品| 日韩一区二区三区免费| 国产乱人伦丫前精品视频| 亚洲激情婷婷| 伊伊综合在线| 国产精品一区二区三区av| 丝袜美腿一区二区三区| 日韩欧美综合| 久久亚洲资源中文字| 日本亚洲三级在线| 午夜国产精品视频免费体验区| 精品欧美视频| 国产精品日韩精品中文字幕| 免费日韩av片| 国产一区欧美| 国产aⅴ精品一区二区三区久久| 亚洲日本三级| 国产亚洲在线| 久久久夜精品| 国产一区二区视频在线看| 欧美精品中文字幕亚洲专区| 丝袜亚洲精品中文字幕一区| 亚洲午夜av| 欧美freesex黑人又粗又大| 精品国产美女a久久9999| 91综合久久爱com| 久久午夜视频| 欧美精品九九| 久久一区二区三区电影| 日韩88av| 精品在线网站观看| 国产日韩在线观看视频| 日本电影久久久| 亚洲午夜久久| 久久av一区| 国产偷自视频区视频一区二区| 99精品一区| 激情自拍一区| 1024精品一区二区三区| 韩国精品主播一区二区在线观看| 成人综合一区| 高清日韩中文字幕| 丁香婷婷久久| 91偷拍一区二区三区精品| 国产一区二区亚洲| 国产精品久久久久久久免费观看 | 国产主播一区| 久久久久久美女精品| 日韩欧美一区二区三区在线观看 | 美日韩精品视频| 丝瓜av网站精品一区二区| 尤物网精品视频| 91久久在线| 偷拍欧美精品| 亚洲成人精选| 视频一区二区三区在线| 中文字幕亚洲精品乱码| 一本一道久久a久久| 青青国产精品| 国产激情精品一区二区三区| 麻豆精品久久| 欧美天堂视频| 婷婷激情久久| 欧美日韩激情在线一区二区三区| 欧美日韩国产传媒| 男女激情视频一区| 日韩高清一区| 国产精品亚洲综合色区韩国| 欧美a级一区二区| 激情久久99| 91精品一区国产高清在线gif| 美女网站一区| 亚洲精品第一| 精品免费视频| 免费av一区| 丝袜脚交一区二区| 久久国内精品| 亚洲黄色中文字幕| 亚洲免费播放| 日本视频在线一区| 国产在线日韩精品| 久久影视一区| 综合亚洲自拍| 美女久久久久久| 亚洲三级欧美| 男女精品网站| 国产精品色婷婷在线观看| 超碰在线99| 麻豆久久一区| 国产午夜精品一区二区三区欧美| 国产成人精品一区二区三区免费| 麻豆一区二区三| 亚洲天堂黄色| 婷婷五月色综合香五月| 国产精品亚洲四区在线观看| 日韩精品专区| 伊人国产精品| 精品久久亚洲| 亚洲精品视频一二三区| 欧美一级专区| 国产精品一国产精品| 欧美日韩尤物久久| 亚洲精品自拍| 色在线中文字幕| 亚洲精品国产精品粉嫩| 久草免费在线视频| 亚洲乱码一区| 日韩成人a**站| 视频一区欧美日韩| 精品一区二区三区的国产在线观看| 久久激情中文| 日本电影久久久| 成人午夜国产| 69堂精品视频在线播放| 日韩中文影院| 91亚洲精品在看在线观看高清| www在线观看黄色| 日韩国产一区二| 日韩免费福利视频| 91九色综合| 欧美成人高清| 精品一区二区三区的国产在线观看| 国产精品日韩欧美一区| 国产一区二区三区日韩精品|