配置 mybatis 打印出執行的 sql 及返回的結果集

在開發過程中, 經常會遇到想要看到應用所執行的 sql 這樣的需求.

比如你寫了一個查詢的功能, 但查詢出來的結果與你預期的不符合, 你想搞清楚到底哪裏出了問題, 你自然需要看看所執行的 sql 語句, 必要的話甚至還要親自拷貝到數據庫裏去查查.

自然, 這就要求應用要能把執行的 sql 輸出出來. 以常用的 mybatis 框架爲例, 來看一個最終的效果:

14:48 ==>  Preparing: select * from user where id = ? 
14:48 ==> Parameters: 1(Integer)
14:48 <==      Total: 1

另注: 這裏的日誌佈局我啓用了一種極簡的風格, 只有"分鐘:秒數", 具體見 配置簡化開發階段日誌輸出佈局 的介紹.

那麼, 在 mybatis 裏, 這個要怎麼做到呢?

配置 sql 輸出

具體來說, 是要增加一個日誌級別的配置, 將 dao(或 mapper) 包級別調整到 DEBUG.

示例:

# log sql statement
logging.level.net.xiaogd.sample.mybatis.dao=DEBUG

注: 上述配置建議放在你的本地開發環境配置文件中, 通常爲 application-dev.properties, 關於 spring-boot 的 分環境配置profile 機制, 如不熟悉請自行查閱網絡瞭解.

對應工程代碼包結構如下:

工程包結構

注: 我的代碼結構下, mybatis 相關的類放到了 dao 這個包下, 你的如果不是這樣, 可以根據自己的情況加以調整.

在上述配置下, 執行以下測試:

package net.xiaogd.sample.mybatis.dao.user;

import lombok.extern.slf4j.Slf4j;
import net.xiaogd.sample.mybatis.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@Slf4j
@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class SimpleTest {

	@Autowired
	private UserDao userDao;

    @Test
    public void testGetUserById() {
        User user = userDao.findUserById(1);
        log.info("user find id: {}", user.getId());
    }
}

相應的 dao 接口:

package net.xiaogd.sample.mybatis.dao.user;

import net.xiaogd.sample.mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserDao {

	@Select("select * from user where id = #{id}")
	User findUserById(int id);
}

相應的 sql 語句, 參數值及查詢的總數都會打印出來:

14:48 ==>  Preparing: select * from user where id = ? 
14:48 ==> Parameters: 1(Integer)
14:48 <==      Total: 1

輸出結果集

如果想進一步輸出結果集, 則可以進一步把日誌級別提升到 TRACE. 如下:

# log sql statement and result set
logging.level.net.xiaogd.sample.mybatis.dao=TRACE

警告: 可能導致大量的日誌輸出, 非必要情況下不要啓用, 且僅可以在本地開發環境調試情況下啓用!

對於下述的數據表:

表數據

最終的輸出如下:

17:36 ==>  Preparing: select * from user 
17:36 ==> Parameters: 
17:36 <==    Columns: id, username, password, nick_name
17:36 <==        Row: 1, admin, 123456, 管理員
17:36 <==        Row: 2, root, root, 根用戶
17:36 <==      Total: 2

可以看到字段及每行的值都被打印出來了.

遺留問題

當然了, 上述在輸出 sql 語句時還有一個問題, 就是在有參數的情況下, 這個還不是最終的 sql, 而是類似於 jdbc 中的那種 prepare statement:

select * from user where id = ? 

可以看到參數的值是用一個問號佔位符代替的, 真正的參數值輸出到了另一行.

如果要真的拷貝到數據庫查看工具裏執行, 比如 navicat 或者 mysql workbench 抑或是最簡單的 mysql console 中, 我們還是得自行替換及拼湊最終的 sql.

雖然多數情況下這也不是特別麻煩, 但在特別多參數的情況下, 如果你發現執行結果不對, 用眼睛看輸出的參數值似乎也沒有問題, 自行去拼湊就有點麻煩了, 能否直接輸出最終的 sql 呢? 也是有方式的, 我們將在下一篇再介紹這種方式.

參考文檔

更多打印 sql 日誌相關的配置, 請參考其官網: https://mybatis.org/mybatis-3/logging.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章