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

Mybatis 實(shí)現(xiàn)打印sql語句的代碼

 更新時(shí)間:2021年04月01日 15:35:44   作者:上學(xué)威龍7  
這篇文章主要介紹了Mybatis 實(shí)現(xiàn)打印sql語句的代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

mybatis本身沒有提供日志的實(shí)現(xiàn),引入的是第三方組件。mybatis支持多個(gè)第三方日志插件,優(yōu)先級(jí)由低到高為slf4J、commonsLoging、Log4J2、Log4J和JdkLog。

mybatis中有一個(gè)LogFactory,獲取log的工廠類,在工程類中可以回去對(duì)應(yīng)的日志實(shí)現(xiàn)。分析工程類,可以發(fā)現(xiàn)mybatis如何來選擇log

public static Log getLog(String logger) {
 try {
 return logConstructor.newInstance(logger);
 } catch (Throwable t) {
 throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t);
 }
}

關(guān)于logConstructor的加載如下

static {
 tryImplementation(LogFactory::useSlf4jLogging);
 tryImplementation(LogFactory::useCommonsLogging);
 tryImplementation(LogFactory::useLog4J2Logging);
 tryImplementation(LogFactory::useLog4JLogging);
 tryImplementation(LogFactory::useJdkLogging);
 tryImplementation(LogFactory::useNoLogging);
}
private static void tryImplementation(Runnable runnable) {
 if (logConstructor == null) {
 try {
 runnable.run();
 } catch (Throwable t) {
 // ignore
 }
 }
}

在 tryImplementation ,中會(huì)設(shè)置mybatis使用的log類型。把引用的log設(shè)置到logConstructor中后,后續(xù)其他類型的log也不會(huì)再加載。所以在mybatis中優(yōu)先級(jí)由低到高為slf4J、commonsLoging、Log4J2、Log4J和JdkLog。感覺也是屬于SPI的一種實(shí)現(xiàn)方式,不同的是各種類型的第三方日志,無法形成一個(gè)統(tǒng)一的接口。故此,mybatis為了解決這一問題,使用了適配器模式。

適配器的實(shí)現(xiàn)一般是讓適配器實(shí)現(xiàn)或者繼承目標(biāo),并且內(nèi)部持有一個(gè)適配者的引用。這樣調(diào)用目標(biāo)對(duì)象方法,實(shí)際上是調(diào)用適配者的方法。

mybatis 又是如何把這log,用起來的。根據(jù)mybatis的習(xí)慣,應(yīng)該會(huì)使用代理模式,來打印這個(gè)日志。 舉例查詢的語句查看,根據(jù)MapperProxy,查到最后查詢的語句

public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
 Statement stmt = null;
 try {
 Configuration configuration = ms.getConfiguration();
 StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
 stmt = prepareStatement(handler, ms.getStatementLog());
 return handler.query(stmt, resultHandler);
 } finally {
 closeStatement(stmt);
 }
}
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
 Statement stmt;
 Connection connection = getConnection(statementLog);
 stmt = handler.prepare(connection, transaction.getTimeout());
 handler.parameterize(stmt);
 return stmt;
}
protected Connection getConnection(Log statementLog) throws SQLException {
 Connection connection = transaction.getConnection();
 if (statementLog.isDebugEnabled()) {
 return ConnectionLogger.newInstance(connection, statementLog, queryStack);
 } else {
 return connection;
 }
}

到此處可以看到mybatis在獲取連接的時(shí)候,會(huì)根據(jù)日志的打印級(jí)別來判斷是否會(huì)創(chuàng)建一個(gè)代理類。到這里就基本可以猜到,在代理類中,mybatis會(huì)去打印這個(gè)sql的語句

public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {
 InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);
 ClassLoader cl = Connection.class.getClassLoader();
 return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
}

用 ConnectionLogger 來舉例,看到里面的invoke的方法

public Object invoke(Object proxy, Method method, Object[] params)
 throws Throwable {
 try {
 if (Object.class.equals(method.getDeclaringClass())) {
 return method.invoke(this, params);
 }
 if ("prepareStatement".equals(method.getName())) {
 if (isDebugEnabled()) {
 debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
 }
 PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
 stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
 return stmt;
 } else if ("prepareCall".equals(method.getName())) {
 if (isDebugEnabled()) {
 debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
 }
 PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
 stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
 return stmt;
 } else if ("createStatement".equals(method.getName())) {
 Statement stmt = (Statement) method.invoke(connection, params);
 stmt = StatementLogger.newInstance(stmt, statementLog, queryStack);
 return stmt;
 } else {
 return method.invoke(connection, params);
 }
 } catch (Throwable t) {
 throw ExceptionUtil.unwrapThrowable(t);
 }
}

可以看到,mybatis在里面還可以更具情況創(chuàng)建代理類。代理類又一次被代理,這也是mybatis喜歡的編程方式,比如插件也是代理類再次被代理,來實(shí)現(xiàn)多個(gè)插件并行。

到此這篇關(guān)于Mybatis 實(shí)現(xiàn)打印sql語句的代碼的文章就介紹到這了,更多相關(guān)Mybatis 打印sql語句內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JVM對(duì)象創(chuàng)建和內(nèi)存分配原理解析

    JVM對(duì)象創(chuàng)建和內(nèi)存分配原理解析

    這篇文章主要介紹了JVM對(duì)象創(chuàng)建和內(nèi)存分配原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • java中的可變參數(shù)使用方法

    java中的可變參數(shù)使用方法

    這篇文章主要介紹了java中的可變參數(shù)使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • java中判斷String類型為空和null的幾種方法

    java中判斷String類型為空和null的幾種方法

    判斷一個(gè)字符串是否為空或者為null是一個(gè)常見的操作,本文主要介紹了java中判斷String類型為空和null的幾種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Java使用正則表達(dá)式獲取子文本的方法示例

    Java使用正則表達(dá)式獲取子文本的方法示例

    這篇文章主要介紹了Java使用正則表達(dá)式獲取子文本的方法,結(jié)合實(shí)例形式分析了java針對(duì)子文本的正則操作相關(guān)函數(shù)與使用技巧,需要的朋友可以參考下
    2017-09-09
  • spring boot集成rabbitmq的實(shí)例教程

    spring boot集成rabbitmq的實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于spring boot集成rabbitmq的相關(guān)資料,springboot集成RabbitMQ非常簡單,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 關(guān)于Hystrix的監(jiān)控及可視化面板

    關(guān)于Hystrix的監(jiān)控及可視化面板

    這篇文章主要介紹了關(guān)于Hystrix的監(jiān)控及可視化面板,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java排序算法圖文詳解

    java排序算法圖文詳解

    這篇文章主要為大家詳細(xì)介紹了Java經(jīng)典排序算法之歸并排序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望可以對(duì)你有所幫助
    2021-07-07
  • IDEA代碼警告(warning)整理以及解決方案

    IDEA代碼警告(warning)整理以及解決方案

    在日常開發(fā)中,IntelliJ?IDEA會(huì)通過problems窗口和編輯窗口的黃色標(biāo)記提示警告,這些警告可能指示代碼存在潛在風(fēng)險(xiǎn)或需要優(yōu)化的空間,文章介紹了如何利用IDEA檢查代碼,以及針對(duì)常見警告的原因和解決辦法
    2024-10-10
  • 詳解SpringBoot實(shí)現(xiàn)JPA的save方法不更新null屬性

    詳解SpringBoot實(shí)現(xiàn)JPA的save方法不更新null屬性

    直接調(diào)用原生Save方法會(huì)導(dǎo)致null屬性覆蓋到數(shù)據(jù)庫,使用起來十分不方便。本文詳細(xì)的介紹了如何解決這個(gè)問題,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-12-12
  • 詳解@Autowired是如何注入變量的

    詳解@Autowired是如何注入變量的

    在?Spring?容器中,當(dāng)我們想給某一個(gè)屬性注入值的時(shí)候,有多種不同的方式,例如使用?@Autowired、@Inject等注解,下面小編就來和小伙伴們聊一聊,@Autowired?到底是如何把數(shù)據(jù)注入進(jìn)來的
    2023-07-07

最新評(píng)論

崇明县| 扎鲁特旗| 苏尼特右旗| 岳普湖县| 克山县| 嘉鱼县| 扬州市| 襄汾县| 文昌市| 开封县| 云龙县| 潮州市| 桦南县| 古浪县| 治县。| 大石桥市| 二手房| 桃园县| 桂东县| 珲春市| 武山县| 合山市| 阿鲁科尔沁旗| 泽库县| 潜山县| 丹巴县| 达日县| 贡嘎县| 云霄县| 龙川县| 澎湖县| 沭阳县| 穆棱市| 扎赉特旗| 大宁县| 河北区| 玉龙| 凌海市| 南乐县| 老河口市| 英山县|