1. 程式人生 > 實用技巧 >Mybatis入門-03-日誌工廠

Mybatis入門-03-日誌工廠

一、 前言

一切當以官方文件為基準。

參考網站:

參考視訊:

本文之前的操作步驟:

  1. Mybatis入門-第一個程式
  2. Mybatis入門-02-增刪改查及配置(屬性、別名、對映器)

前置內容:

  • Java
  • maven
  • MySQL
  • JDBC
  • JavaWeb中持久化層的一些知識,如POJO

環境:

  • Java11
  • IDEA 2019.3.3
  • MySQL8
  • mybatis3

路徑:

目的:使用日誌,更好地排錯。

二、設定

檢視Mybatis官方中文文件-xml配置-settings

logImpl項:

設定名 描述 有效值 預設值
logImpl 指定 MyBatis 所用日誌的具體實現,未指定時將自動查詢。 SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING 未設定

1.STDOUT_LOGGING

按照文件,將mybatis-config.xml設定為:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <properties resource="db.properties"></properties>
    
<!--====================add=====================-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
<!--============================================-->
    
    <typeAliases>
        <package name="com.duzhuan.pojo"/>
    </typeAliases>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.duzhuan.dao.UserMapper"></mapper>
    </mappers>
</configuration>

注意順序,若不知道順序,可以先隨便放置,IDEA會報錯:

使用測試樣例getUerListById進行測試:

沒有啟用日誌前:

啟用日誌後:

可以看到返回了許多關鍵的資訊,圈起來的是SQL語句。

2.SLF4J+Log4j2

目前最流行的日誌門面是SLF4J,雖然Log4J也是日誌門面,但是因為功能強大,效能優越,一般還是將其看作是日誌實現。

依賴:

        <!--使用slf4j 作為日誌門面-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!--使用 log4j2 的介面卡進行繫結-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.12.1</version>
            <scope>test</scope>
        </dependency>


        <!--log4j2 日誌門面-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.12.1</version>
        </dependency>
        <!--log4j2 日誌實現-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>

這裡參考bdqfork創作-SLF4J日誌級別以及使用場景,SFL4J+Log4J2的日誌級別:

  • trace(最低)
  • debug
  • info
  • warn
  • error(最高)

檸檬五個半-log4j使用教程裡獲取配置,部分備註參考黑馬程式設計師-2020年Java進階教程,全面學習多種java日誌框架-P33 log4j2 配置檔案

<?xml version="1.0" encoding="UTF-8"?>

<!--
    status="debug" 日誌框架本身的級別
    configuration還有個屬性是 monitorInterval = 5,自動載入配置檔案的最小間隔時間,單位是秒
-->
<configuration status="debug">

    <!--
        集中配置屬性進行管理,使用時通過:${}
    -->
    <properties>
        <property name="LOG_HOME">./logs</property>
    </properties>

    <!--日誌處理器-->
    <!--先定義所有的appender -->
    <appenders>
        <!--這個輸出控制檯的配置 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!--             控制檯只輸出level及以上級別的資訊(onMatch),其他的直接拒絕(onMismatch) -->
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            <!--             這個都知道是輸出日誌的格式 -->
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} [%-5level] %class{36} %L %M - %msg%xEx%n"/>
        </Console>

        <!--檔案會打印出所有資訊,這個log每次執行程式會自動清空,由append屬性決定,這個也挺有用的,適合臨時測試用 -->
        <!--append為TRUE表示訊息增加到指定檔案中,false表示訊息覆蓋指定的檔案內容,預設值是true -->
        <File name="log" fileName="${LOG_HOME}/mybatis-log.log" append="false">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} [%-5level] %class{36} %L %M - %msg%xEx%n"/>
        </File>

        <!--
            新增過濾器ThresholdFilter,可以有選擇的輸出某個級別以上的類別
            onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否則直接拒絕
        -->
        <File name="ERROR" fileName="${LOG_HOME}/mybatis-error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} [%-5level] %class{36} %L %M - %msg%xEx%n"/>
        </File>

        <!--
            使用隨機讀寫流的日誌檔案輸出appender,效能提高
        -->
        <RandomAccessFile name="accessFile" fileName="${LOG_HOME}/mybatis-access.log">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} [%-5level] %class{36} %L %M - %msg%xEx%n"/>
        </RandomAccessFile>

        <!--
            這個會打印出所有的資訊,每次大小超過size,
            則這size大小的日誌會自動存入按年份-月份建立的資料夾下面並進行壓縮,
            作為存檔
         -->
        <RollingFile name="RollingFile" fileName="${LOG_HOME}/mybatis-web.log"
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} [%-5level] %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="2MB"/>
        </RollingFile>
    </appenders>


    <!--然後定義logger,只有定義了logger並引入的appender,appender才會生效 -->
    <loggers>
        <!--使用rootLogger配置   日誌級別level="trace" -->
        <root level="trace">
            <!--制定日誌使用的處理器-->
            <appender-ref ref="log"/>
            <appender-ref ref="ERROR" />
            <appender-ref ref="Console"/>
            <appender-ref ref="accessFile"/>
            <appender-ref ref="RollingFile"/>
        </root>
    </loggers>
</configuration>

將mybatis-config.xml中name="logImpl"setting標籤的value的值設為SLF4J

    <settings>
        <setting name="logImpl" value="SLF4J"/>
    </settings>

執行UserMapperTest中的測試樣例,這裡執行getUserByIdTest:

    @Test
    public void getUserByIdTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);

        sqlSession.close();
    }

第一次使用時,還會在設定好的目錄裡建立日誌檔案:

根據上面的註釋,可以知道這裡記錄最完整的是mybatis-access.logmybatis-web.log,用記事本開啟可以看到:

2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.logging.LogFactory 105 setImplementation - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.logging.LogFactory 105 setImplementation - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.VFS 116 getClass - Class not found: org.jboss.vfs.VFS
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.JBoss6VFS 149 setInvalid - JBoss 6 VFS API is not available in this environment.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.VFS 116 getClass - Class not found: org.jboss.vfs.VirtualFile
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.VFS$VFSHolder 64 createVFS - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.VFS$VFSHolder 74 createVFS - Using VFS adapter org.apache.ibatis.io.DefaultVFS
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 220 findJarForResource - Find JAR URL: file:/D:/IdeaProject/MyBaitsLearn/mybatis-01/target/classes/com/duzhuan/pojo
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 247 findJarForResource - Not a JAR: file:/D:/IdeaProject/MyBaitsLearn/mybatis-01/target/classes/com/duzhuan/pojo
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 100 list - Reader entry: User.class
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 111 list - Listing file:/D:/IdeaProject/MyBaitsLearn/mybatis-01/target/classes/com/duzhuan/pojo
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 220 findJarForResource - Find JAR URL: file:/D:/IdeaProject/MyBaitsLearn/mybatis-01/target/classes/com/duzhuan/pojo/User.class
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 247 findJarForResource - Not a JAR: file:/D:/IdeaProject/MyBaitsLearn/mybatis-01/target/classes/com/duzhuan/pojo/User.class
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.DefaultVFS 100 list - Reader entry: ����   7 :
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.io.ResolverUtil 288 addIfMatching - Checking to see if class com.duzhuan.pojo.User matches criteria [is assignable to Object]
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 363 forceCloseAll - PooledDataSource forcefully closed/removed all connections.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 363 forceCloseAll - PooledDataSource forcefully closed/removed all connections.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 363 forceCloseAll - PooledDataSource forcefully closed/removed all connections.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 363 forceCloseAll - PooledDataSource forcefully closed/removed all connections.
2020-09-11 at 22:41:49 CST [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction 137 openConnection - Opening JDBC Connection
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 434 popConnection - Created connection 1727420902.
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction 101 setDesiredAutoCommit - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@66f659e6]
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 debug - ==>  Preparing: select * from mybatis.user where name like concat('%',?,'%')
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 debug - ==> Parameters: a(String)
2020-09-11 at 22:41:50 CST [TRACE] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 143 trace - <==    Columns: id, name, pwd
2020-09-11 at 22:41:50 CST [TRACE] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 143 trace - <==        Row: 1, admin, 123456
2020-09-11 at 22:41:50 CST [TRACE] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 143 trace - <==        Row: 2, Jax, 123456
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 debug - <==      Total: 2
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction 123 resetAutoCommit - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@66f659e6]
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction 91 close - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@66f659e6]
2020-09-11 at 22:41:50 CST [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource 391 pushConnection - Returned connection 1727420902 to pool.

格式設定得好找一點的話在控制檯也可以比較輕鬆找到: