mybatis 与 日志
如上图所示,mybatis默认支持7种日志记录的方式,也可以自己实现Log接口,然后将实现类通过LogFactory注入到日志工厂中。
LogFactory是日志模块的入口,外层通过getLog获取Log对象,然后调用Log接口方法进行日志的记录,代码示例:
private static final Log log = LogFactory.getLog(BaseExecutor.class);
...
@Override
public void close(boolean forceRollback) {
try {
try {
rollback(forceRollback);
} finally {
if (transaction != null) {
transaction.close();
}
}
} catch (SQLException e) {
// Ignore. There's nothing that can be done at this point.
log.warn("Unexpected exception on closing transaction. Cause: " + e);
} finally {
transaction = null;
deferredLoads = null;
localCache = null;
localOutputParameterCache = null;
closed = true;
}
}
LogFactory的初始化过程:
static {
tryImplementation(new Runnable() {
@Override
public void run() {
useSlf4jLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useCommonsLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4J2Logging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4JLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useJdkLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useNoLogging();
}
});
}
private static void tryImplementation(Runnable runnable) {
if (logConstructor == null) {
try {
runnable.run();
} catch (Throwable t) {
// ignore
}
}
}
private static void setImplementation(Class<? extends Log> implClass) {
try {
Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
Log log = candidate.newInstance(LogFactory.class.getName());
if (log.isDebugEnabled()) {
log.debug("Logging initialized using '" + implClass + "' adapter.");
}
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}
按照顺序依次去尝试着实例化各个实例(tryImplementation方法),slf4j -> common-logging -> log4j2 -> log4j -> jdk -> nologging,当某个Log实例化成功后,就会停止下面的初始化。
实例化是setImplementation方法做的,当所有日志都没有做配置或者缺少包的话就会失败,所以默认的日志是NoLoggingImpl。
我们可以在mybatis配置文件中指定具体的配置类或者自定义配置类。
我们可以在代码中调用LogFactory的方法来手动指定配置类,但是由于mybatis在初始化配置的时候将组建的各个配置都初始化好存放到configuration对象中,包括log。所以当mybatis初始化完成之后再去调用LogFactory的方法更改log对于configuration是没有影响的,所以,我们应该在SqlSessionFactoryBuilder开始之前对LogFactory操作,下面是使用代码配置成控制台log:
public class TestLog { public static void main(String[] args) throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
LogFactory.useStdOutLogging();
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = factory.openSession();
List<Gscope> result = session.selectList("getGscopes");
session.close();
System.out.println(result);
}
}
logging包还有个重要的组件,负责对JDBC对象拦截和日志记录:
其中,基类BaseJdbcLogger实现了一些工具类,并封装了column,它的4个子类ConnectionLogger,StatementLogger,PreparedStatementLogger和ResultLogger实现了InvacationHandler接口,作为JDBC对象Connection,Statement,ResultSet的代理,其中,StatementLogger和PreparedStatementLogger在ConnectionLogger中拦截statement方法并返回代理对象,ResultLogger在StatementLogger和PreparedStatementLogger中拦截execute并返回代理对象,
而ConnectionLogger是在Executor中创建的代理:
BaseExecutor.java
protected Connection getConnection(Log statementLog) throws SQLException {
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog, queryStack);
} else {
return connection;
}
}
上例中的控制台打印的log如下
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Tue Jan 03 23:54:04 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Created connection 1635546341.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@617c74e5]
==> Preparing: select * from gscope;
==> Parameters:
<== Columns: sid, id, code, name, pinyin, first_pinyin, level, parent_id, alias, orderby, lng, lat, show_in_web
<== Row: 1, 22, TJ , 天津, tianji, tj, 1, 0, 天津, 1, 0, 0, 1
...省略...
<== Total: 133
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@617c74e5]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@617c74e5]
Returned connection 1635546341 to pool.
mybatis 与 日志的更多相关文章
- Mybatis 的日志管理
Mybatis通过日志工厂提供日志信息,Mybatis内置的日志模版是log4j,commons.log,jdk log也可以通过slf4j简单日志模版结合log4j使用日志信息输出.具体选择哪个日志 ...
- MyBatis 显示日志
<!-- 全局配置 --> <settings> <setting name="cacheEnabled" value="false&quo ...
- SpringBoot打印MyBatis sql日志输出
SpringBoot打印MyBatis sql日志输出 默认情况下mybatis是不开启SQL日志输出,需要手动配置 方法一:(在mybatis整合在springboot框架的情况下) 只需要在配置文 ...
- Mybatis学习日志
在Mybatis深入学习的一周中,总感觉跟着师傅的视屏讲解什么都能懂,但实际自己操作的时候才发现自己一脸懵逼,不知道从何入手.但还好自己做了点笔记.在此记录一下自己浅度学习Mybatis遇到几个小问题 ...
- logback打印mybatis sql日志
近期在项目中调试sql,发现现有的配置 使用logback 无法打印出sql语句,原配置如下(修改为debug也不好使): <!--jdbc --><logger name=&quo ...
- Mybatis学习--日志
学习笔记,选自Mybatis官方中文文档:http://www.mybatis.org/mybatis-3/zh/logging.html Logging Mybatis内置的日志工厂提供日志功能,具 ...
- Mybatis之日志工厂
思考:我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率? 如果一个 数据库相关的操作出现了问题,我们可以根据输出的SQL语句快速排查问题. 对于以往的开发过程, ...
- IDEA集成Mybatis打印日志插件
MyBatis Log Plugin :把 mybatis 输出的sql日志还原成完整的sql语句. 如下图所示,点击Tools>MyBatis Log Plugin 然后运行程序后,就会看到对 ...
- Mybatis学习-日志与分页
日志 为什么需要日志 如果一个数据库操作出现了异常,需要排错,那么日志就是最好的助手 Mybatis通过使用内置的日志工厂提供日志功能,有一下几种实现方式: SLF4J Apache Commons ...
随机推荐
- 将list转换为datatable的方法
public static DataTable CopyToDataTable<T>(this IEnumerable<T> array) { var ret = new Da ...
- unix下输出重定向
> 为重定向符号 >> 重定向不覆盖原文件内容 example: 1. 标准输出重定向 echo "123" > /home/123.txt ---- 标准 ...
- 通过docker-machine和etcd部署docker swarm集群
本片文章介绍一下 使用docker-machine 搭建docker swarm 集群:docker swarm是docker 官方搭建的容器集群编排工具:容器编排,就是可以使你像使用一太机器一样来使 ...
- C#中MessageBox用法大全
我们在程序中经常会用到MessageBox. MessageBox.Show()共有21中重载方法.现将其常见用法总结如下: 1.MessageBox.Show("Hello~~~~&quo ...
- Huffman编码(测试源代码)
1.此程序为c++程序 2.以下代码可实现手动输入,即去掉代码中的/*...*/注释符,并同时去掉赋值代码段 3.源代码 #include<iostream> using namespac ...
- Git 的详细使用
本文翻译自Understanding Git Source Control in Xcode (译者myShire)欢迎您加入我们的翻译小组. 在应用程序开发过程中,很重要的一部分工作就是如何进行 ...
- Mac OS 后台服务注册
/Library/LaunchAgents/ /Library/LaunchDaemons
- oracle行转列,decode 等用法
DECODE()函数,它将输入数值与函数中的参数列表相比较,根据输入值返回一个对应值.函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式.当然,如果未能与任何一个实参序偶匹配成功,则函数也有默 ...
- arcgis制作兴趣点分布图
数据准备: 1.矢量:芜湖市区行政区.shp 企业分布点.shp 2.影像:Landsat 8 软件:arcgis 10.3 Envi4.8 目的:制作一幅以市区行政区为底图的企业分布点的图,同时 ...
- 微信开发03----------XML解析与封装
3.1 解析微信发来的请求 微信服务器发来的请求消息都被封装在request对象中,可以从request对象中将请求参数取出来.通常是用request的getParament()方法获取请求中的参数 ...