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

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

mybatis 通過(guò)攔截器打印完整的sql語(yǔ)句以及執(zhí)行結(jié)果操作

瀏覽:34日期:2023-10-22 12:14:22

開(kāi)發(fā)過(guò)程中,如果使用mybatis做為ORM框架,經(jīng)常需要打印出完整的sql語(yǔ)句以及執(zhí)行的結(jié)果做為參考。

雖然mybatis結(jié)合日志框架可以做到,但打印出來(lái)的通常都是sql和參數(shù)分開(kāi)的。

有時(shí)我們需要調(diào)試這條sql的時(shí)候,就需要把參數(shù)填進(jìn)去,這樣未免有些浪費(fèi)時(shí)間。

此時(shí)我們可以通過(guò)實(shí)現(xiàn)mybatis攔截器來(lái)做到打印帶參數(shù)的完整的sql,以及結(jié)果通過(guò)json輸出到控制臺(tái)。

直接看代碼和使用方法吧:

MyBatis攔截器打印不帶問(wèn)號(hào)的完整sql語(yǔ)句攔截器

import java.text.DateFormat;import java.util.Date;import java.util.List;import java.util.Locale;import java.util.Properties;import java.util.regex.Matcher; import org.apache.commons.collections.CollectionUtils;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; /** * MyBatis攔截器打印不帶問(wèn)號(hào)的完整sql語(yǔ)句 * * @author gogym * @version 2018年8月13日 * @see MybatisInterceptor * @since */@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})})@SuppressWarnings({'unchecked', 'rawtypes'})public class MybatisInterceptor implements Interceptor{ @Override public Object intercept(Invocation invocation) throws Throwable { try { // 獲取xml中的一個(gè)select/update/insert/delete節(jié)點(diǎn),是一條SQL語(yǔ)句 MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0]; Object parameter = null; // 獲取參數(shù),if語(yǔ)句成立,表示sql語(yǔ)句有參數(shù),參數(shù)格式是map形式 if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; System.out.println('parameter = ' + parameter); } String sqlId = mappedStatement.getId(); // 獲取到節(jié)點(diǎn)的id,即sql語(yǔ)句的id System.out.println('sqlId = ' + sqlId); BoundSql boundSql = mappedStatement.getBoundSql(parameter); // BoundSql就是封裝myBatis最終產(chǎn)生的sql類 Configuration configuration = mappedStatement.getConfiguration(); // 獲取節(jié)點(diǎn)的配置 String sql = getSql(configuration, boundSql, sqlId); // 獲取到最終的sql語(yǔ)句 System.out.println('sql = ' + sql); } catch (Exception e) { e.printStackTrace(); } // 執(zhí)行完上面的任務(wù)后,不改變?cè)械膕ql執(zhí)行過(guò)程 return invocation.proceed(); } // 封裝了一下sql語(yǔ)句,使得結(jié)果返回完整xml路徑下的sql語(yǔ)句節(jié)點(diǎn)id + sql語(yǔ)句 public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId) { String sql = showSql(configuration, boundSql); StringBuilder str = new StringBuilder(100); str.append(sqlId); str.append(':'); str.append(sql); return str.toString(); } // 如果參數(shù)是String,則添加單引號(hào), 如果是日期,則轉(zhuǎn)換為時(shí)間格式器并加單引號(hào); 對(duì)參數(shù)是null和不是null的情況作了處理 private static String getParameterValue(Object obj) { String value = null; 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; } // 進(jìn)行?的替換 public static String showSql(Configuration configuration, BoundSql boundSql) { // 獲取參數(shù) Object parameterObject = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); // sql語(yǔ)句中多個(gè)空格都用一個(gè)空格代替 String sql = boundSql.getSql().replaceAll('[s]+', ' '); if (CollectionUtils.isNotEmpty(parameterMappings) && parameterObject != null) { // 獲取類型處理器注冊(cè)器,類型處理器的功能是進(jìn)行java類型和數(shù)據(jù)庫(kù)類型的轉(zhuǎn)換 TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); // 如果根據(jù)parameterObject.getClass()可以找到對(duì)應(yīng)的類型,則替換 if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { sql = sql.replaceFirst('?', Matcher.quoteReplacement(getParameterValue(parameterObject))); } else { // MetaObject主要是封裝了originalObject對(duì)象,提供了get和set的方法用于獲取和設(shè)置originalObject的屬性值,主要支持對(duì)JavaBean、Collection、Map三種類型對(duì)象的操作 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('?', Matcher.quoteReplacement(getParameterValue(obj))); } else if (boundSql.hasAdditionalParameter(propertyName)) { // 該分支是動(dòng)態(tài)sql Object obj = boundSql.getAdditionalParameter(propertyName); sql = sql.replaceFirst('?', Matcher.quoteReplacement(getParameterValue(obj))); } else { // 打印出缺失,提醒該參數(shù)缺失并防止錯(cuò)位 sql = sql.replaceFirst('?', '缺失'); } } } } return sql; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } }

打印結(jié)果攔截器:

import java.util.Properties; import org.apache.ibatis.executor.Executor;import org.apache.ibatis.mapping.MappedStatement;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.session.ResultHandler;import org.apache.ibatis.session.RowBounds; import com.poly.rbl.utils.FastJsonUtils; /** * 打印結(jié)果攔截器 〈功能詳細(xì)描述〉 * * @author gogym * @version 2019年4月2日 * @see InterceptorForQry * @since */@Intercepts({@Signature(type = Executor.class, method = 'query', args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})public class InterceptorForQry implements Interceptor{ @SuppressWarnings({'rawtypes', 'unchecked'}) public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); // 執(zhí)行請(qǐng)求方法,并將所得結(jié)果保存到result中 String str = FastJsonUtils.toJSONString(result); System.out.println(str); return result; } public Object plugin(Object target) { return Plugin.wrap(target, this); } public void setProperties(Properties arg0) {}}

用法直接配置在mybatis配置文件里面即可:

<plugins> <!-- 啟動(dòng)SQL打印,帶參數(shù) <plugin interceptor='com.poly.rbl.plugin.mybatis.MybatisInterceptor'> </plugin> <plugin interceptor='com.poly.rbl.plugin.mybatis.InterceptorForQry'> </plugin> </plugins>

以上這篇mybatis 通過(guò)攔截器打印完整的sql語(yǔ)句以及執(zhí)行結(jié)果操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
福利一区在线| 天堂8中文在线最新版在线| 欧美特黄一区| 精品资源在线| 欧美亚洲一区二区三区| 免费精品国产的网站免费观看| 日韩va亚洲va欧美va久久| 国产一区二区三区视频在线| 欧美日韩18| 久久精品97| 亚洲天堂免费| 日韩.com| 综合在线一区| 在线一区免费| 成人一区而且| 久久精品一区二区三区中文字幕| 喷白浆一区二区| 亚洲深夜影院| 日韩天堂av| 一区二区三区四区日本视频| 玖玖玖国产精品| 97精品97| 红杏一区二区三区| 国产精品777777在线播放| 男人的天堂亚洲一区| 亚洲午夜久久久久久尤物| 中文字幕高清在线播放| 日韩成人a**站| 国产一区二区三区精品在线观看| 国产精品地址| 福利一区二区免费视频| 国产一区二区三区精品在线观看| 日产精品一区二区| 色婷婷色综合| 日韩国产激情| 中文欧美日韩| 91成人精品在线| 国产aa精品| 欧美日韩国产精品一区二区亚洲| 亚洲1234区| 视频一区二区欧美| 日本va欧美va精品| 亚洲天堂av影院| 欧美日韩国产探花| 欧美一区久久| 麻豆国产欧美日韩综合精品二区| 久久中文字幕av一区二区不卡| 日韩欧美一区免费| 免费一级片91| 免费在线欧美黄色| 日韩精品免费视频人成| 国产一区国产二区国产三区| 136国产福利精品导航网址| 日本不卡一区二区| 精品欧美日韩精品| 中文欧美日韩| 日韩av有码| 日本麻豆一区二区三区视频| 高清日韩欧美| 综合色就爱涩涩涩综合婷婷| 精品视频在线你懂得| 五月激激激综合网色播| 欧美在线看片| 欧美不卡视频| 色一区二区三区四区| 999久久久91| 蜜臀av性久久久久蜜臀aⅴ流畅| 午夜一级久久| 激情综合网站| 久久久久久久久成人| 日日摸夜夜添夜夜添国产精品| 久热精品在线| 亚洲视频国产| 日韩国产一区二| 国产精品综合| 精品91福利视频| 亚洲一区二区三区免费在线观看| 久久精品影视| 五月天久久网站| 中文字幕一区二区三区日韩精品| 老司机精品久久| 青青伊人久久| 先锋亚洲精品| 亚洲免费成人| 日韩精品亚洲专区在线观看| 欧美日韩一区二区三区不卡视频| 国产精品探花在线观看| 高清久久精品| 亚洲欧美日韩在线观看a三区| 亚洲欧美专区| 久久精品资源| 中文日韩在线| 国产剧情在线观看一区| 久久精品123| 日韩高清国产一区在线| 黄色在线网站噜噜噜| 婷婷久久一区| 国产福利一区二区精品秒拍| 国产精品嫩草99av在线| 88xx成人免费观看视频库| 国产毛片一区| 亚洲欧洲另类| 国产精品亚洲四区在线观看| 999久久久国产精品| 免费成人av在线播放| 国产成人免费视频网站视频社区| 亚洲手机视频| 国产精品久久国产愉拍| 一区在线免费观看| 日韩一区中文| av资源亚洲| 另类亚洲自拍| 欧美日韩精品一区二区视频| 美女精品网站| 亚洲免费播放| 国产+成+人+亚洲欧洲在线| 国产精品久久久久久久久久白浆| 日韩中文字幕av电影| 在线天堂资源www在线污| 日韩高清在线不卡| 午夜视频一区二区在线观看| 亚洲一区成人| 国产99在线| 97久久亚洲| 蜜臀av亚洲一区中文字幕| 欧美日韩精品免费观看视欧美高清免费大片 | 清纯唯美亚洲综合一区| 久久亚洲精品中文字幕| 999久久久国产精品| 国产极品嫩模在线观看91精品| 91精品精品| 群体交乱之放荡娇妻一区二区| 成人午夜亚洲| 麻豆精品在线视频| 国产精品jk白丝蜜臀av小说| 国产精品亚洲一区二区在线观看| 日韩影院免费视频| 午夜电影一区| 久久免费大视频| 亚洲影院天堂中文av色| 日韩精品电影一区亚洲| 欧美亚洲一级| 99国产精品99久久久久久粉嫩| 91精品国产成人观看| 国产精品久久久久久久免费观看 | 国产a亚洲精品| 国产欧美在线观看免费| 日韩精品一区二区三区中文字幕| 国产亚洲在线观看| 精品视频一区二区三区在线观看 | 日本亚洲欧美天堂免费| 在线看片一区| 99精品电影| 激情欧美亚洲| 中文字幕亚洲在线观看| 最新国产精品久久久| 亚洲一级淫片| 免费在线亚洲欧美| 亚洲二区免费| 欧美一区三区| 亚洲免费在线| 免费人成黄页网站在线一区二区| 一区久久精品| 88久久精品| 午夜久久tv| 国产精品成人3p一区二区三区| 啪啪国产精品| 日本成人在线视频网站| 免费精品国产的网站免费观看| 亚洲欧美日韩视频二区| 亚洲另类黄色| 欧美aa在线视频| 精品国产亚洲日本| 欧美日韩尤物久久| 欧洲av不卡| 亚洲免费在线| 亚欧洲精品视频在线观看| 在线 亚洲欧美在线综合一区| 天堂va欧美ⅴa亚洲va一国产| 精品高清久久| 天堂资源在线亚洲| 日韩精品一区二区三区av| 日韩三区免费| 亚洲欧洲国产精品一区| 欧美日韩在线观看视频小说| 亚洲综合婷婷| 精品在线91| 久久精品国产亚洲aⅴ| 日韩一区中文| 欧美日韩三区| 成人国产精品一区二区免费麻豆| 久久亚洲图片| 久久九九国产| 伊人久久在线| 精品网站aaa| sm久久捆绑调教精品一区| 久久不卡日韩美女| 奇米亚洲欧美| 精品五月天堂| 国产日韩精品视频一区二区三区|