最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2020年10月09日 11:22:38   作者:Gogym  
這篇文章主要介紹了mybatis 通過攔截器打印完整的sql語句以及執(zhí)行結(jié)果操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

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

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

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

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

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

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

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攔截器打印不帶問號(hào)的完整sql語句
 * 
 * @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語句
   MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
   Object parameter = null;
   // 獲取參數(shù),if語句成立,表示sql語句有參數(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語句的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語句
   System.out.println("sql = " + sql);
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  // 執(zhí)行完上面的任務(wù)后,不改變原有的sql執(zhí)行過程
  return invocation.proceed();
 }
 
 // 封裝了一下sql語句,使得結(jié)果返回完整xml路徑下的sql語句節(jié)點(diǎn)id + sql語句
 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); 對參數(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語句中多個(gè)空格都用一個(gè)空格代替
  String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
  if (CollectionUtils.isNotEmpty(parameterMappings) && parameterObject != null)
  {
   // 獲取類型處理器注冊器,類型處理器的功能是進(jìn)行java類型和數(shù)據(jù)庫類型的轉(zhuǎn)換
   TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
   // 如果根據(jù)parameterObject.getClass()可以找到對應(yīng)的類型,則替換
   if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
   {
    sql = sql.replaceFirst("\\?",
     Matcher.quoteReplacement(getParameterValue(parameterObject))); 
   }
   else
   {
    // MetaObject主要是封裝了originalObject對象,提供了get和set的方法用于獲取和設(shè)置originalObject的屬性值,主要支持對JavaBean、Collection、Map三種類型對象的操作
    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í)行請求方法,并將所得結(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 通過攔截器打印完整的sql語句以及執(zhí)行結(jié)果操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot整合jcasbin權(quán)限管理

    springboot整合jcasbin權(quán)限管理

    jcasbin的權(quán)限控制非常簡單,本文就來介紹一下springboot整合jcasbin權(quán)限管理,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • SpringBoot攔截器實(shí)現(xiàn)登錄攔截的示例代碼

    SpringBoot攔截器實(shí)現(xiàn)登錄攔截的示例代碼

    本文主要介紹了SpringBoot攔截器實(shí)現(xiàn)登錄攔截,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 解決springboot遇到autowire注入為null的問題

    解決springboot遇到autowire注入為null的問題

    這篇文章主要介紹了解決springboot遇到autowire注入為null的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 使用Spring注入Hibernate驗(yàn)證框架

    使用Spring注入Hibernate驗(yàn)證框架

    這篇文章主要介紹了使用Spring注入Hibernate驗(yàn)證框架方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot如何基于POI-tl和word模板導(dǎo)出龐大的Word文件

    SpringBoot如何基于POI-tl和word模板導(dǎo)出龐大的Word文件

    這篇文章主要介紹了SpringBoot如何基于POI-tl和word模板導(dǎo)出龐大的Word文件,poi-tl是一個(gè)基于Apache?POI的Word模板引擎,也是一個(gè)免費(fèi)開源的Java類庫
    2022-08-08
  • Spring IOC的相關(guān)注解運(yùn)用詳解

    Spring IOC的相關(guān)注解運(yùn)用詳解

    這篇文章主要介紹了Spring IOC的相關(guān)注解運(yùn)用詳解,純注解實(shí)現(xiàn)IOC需要一個(gè)Java類代替xml文件,這個(gè)Java類上方需要添加@Configuration,表示該類是一個(gè)配置類,作用是代替配置文件,需要的朋友可以參考下
    2023-08-08
  • 詳解使用Spring?Data?repository進(jìn)行數(shù)據(jù)層的訪問問題

    詳解使用Spring?Data?repository進(jìn)行數(shù)據(jù)層的訪問問題

    這篇文章主要介紹了使用Spring?Data?repository進(jìn)行數(shù)據(jù)層的訪問,抽象出Spring Data repository是因?yàn)樵陂_發(fā)過程中,常常會(huì)為了實(shí)現(xiàn)不同持久化存儲(chǔ)的數(shù)據(jù)訪問層而寫大量的大同小異的代碼,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-06-06
  • springboot使用kafka事務(wù)的示例代碼

    springboot使用kafka事務(wù)的示例代碼

    Kafka?同數(shù)據(jù)庫一樣支持事務(wù),當(dāng)發(fā)生異常的時(shí)候可以進(jìn)行回滾,確保消息監(jiān)聽器不會(huì)接收到一些錯(cuò)誤的或者不需要的消息,本文就來介紹一下springboot使用kafka事務(wù)的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 新手了解java 數(shù)組基礎(chǔ)知識(shí)

    新手了解java 數(shù)組基礎(chǔ)知識(shí)

    這篇文章主要介紹了Java 數(shù)組分析及簡單實(shí)例的相關(guān)資料,在Java中它就是對象,一個(gè)比較特殊的對象,需要的朋友可以參考下,希望可以對你有所幫助
    2021-07-07
  • 新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程

    新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程

    這篇文章給大家介紹了新版idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)教程,本教程對新手小白友好,若根據(jù)教程創(chuàng)建出現(xiàn)問題導(dǎo)致失敗可下載我提供的源碼,在文章最后,本教程較新,文中通過圖文給大家介紹的非常詳細(xì),感興趣的朋友可以參考下
    2024-01-01

最新評論

门源| 库车县| 山阳县| 明水县| 望奎县| 临泽县| 嵊泗县| 监利县| 武川县| 长葛市| 广南县| 河北省| 松滋市| 延长县| 新乐市| 五常市| 土默特右旗| 柯坪县| 微博| 顺平县| 灵宝市| 都昌县| 蓬莱市| 南漳县| 新干县| 定州市| 景宁| 佛坪县| 荆州市| 内黄县| 河池市| 枝江市| 黔南| 西城区| 平原县| 年辖:市辖区| 海口市| 北票市| 韶关市| 连山| 东阳市|