spring+mybatis+log4jdbc源码分析!

最近有个需求,记录框架spring+mybatis的项目的慢sql,想到了log4jdbc框架,log4jdbc只是对传统jdbc的一层封装,然后打印出sql执行日志和执行时间:

先简单介绍一下log4jdbc的使用:

第一步:引用log4jdbc的gradle配置,如果是maven的自己转换:

compile 'com.googlecode.log4jdbc:log4jdbc:1.2'

第二步:修改jdbc的driver和url:

mysql:
  datasource:
    driverClassName: net.sf.log4jdbc.DriverSpy
    url: jdbc:log4jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC

就是这么简单,修改了这2个地方,就可以直接使用了,现在只要操作了数据库,日志便会打印出sql和sql的执行时间,以下面的这种格式:


然而具体的执行过程是怎么样的呢,我们有必要先阅读一下log4jdbc的源码,log4jdbc的源码包并不大,只有十几个类:



DriverSpy是对java.sql.Driver接口的实现,ConnectionSpy是对java.sql.Connection接口的实现,先来看看Class.forName(“net.sf.log4jdbc.DriverSpy”)时到底干了什么,先来看看DriverSpy的static静态代码块:

static
{
//log4jdbc初始化开始
 log.debug("... log4jdbc initializing ...");
//从classpath下读取配置文件
  InputStream propStream =
    DriverSpy.class.getResourceAsStream("/log4jdbc.properties");

  Properties props = new Properties(System.getProperties());
  if (propStream != null)
  {
    try
    {
      props.load(propStream);
    }
    catch (IOException e)
    {
      log.debug("ERROR!  io exception loading " +
        "log4jdbc.properties from classpath: " + e.getMessage());
    }
    finally
    {
      try
      {
        propStream.close();
      }
      catch (IOException e)
      {
        log.debug("ERROR!  io exception closing property file stream: " +
          e.getMessage());
      }
    }
    log.debug("  log4jdbc.properties loaded from classpath");
  }
  else
  {
    log.debug("  log4jdbc.properties not found on classpath");
  }

  // look for additional driver specified in properties
//加载dubug模式的前缀
 DebugStackPrefix = getStringOption(props, "log4jdbc.debug.stack.prefix");
  TraceFromApplication = DebugStackPrefix != null;
//当SqlTimingWarnThresholdEnabled 为true时,SqlTimingWarnThresholdMsec 才有效,当sql执行时间大于
//SqlTimingWarnThresholdMsec 时间时,才打印warn日志
  Long thresh = getLongOption(props, "log4jdbc.sqltiming.warn.threshold");
  SqlTimingWarnThresholdEnabled = (thresh != null);
  if (SqlTimingWarnThresholdEnabled)
  {
    SqlTimingWarnThresholdMsec = thresh.longValue();
  }

  thresh = getLongOption(props, "log4jdbc.sqltiming.error.threshold");
  SqlTimingErrorThresholdEnabled = (thresh != null);
  if (SqlTimingErrorThresholdEnabled)
  {
    SqlTimingErrorThresholdMsec = thresh.longValue();
  }

  DumpBooleanAsTrueFalse =
    getBooleanOption(props, "log4jdbc.dump.booleanastruefalse",false);

  DumpSqlMaxLineLength = getLongOption(props,
    "log4jdbc.dump.sql.maxlinelength", 90L).intValue();

  DumpFullDebugStackTrace =
    getBooleanOption(props, "log4jdbc.dump.fulldebugstacktrace",false);

  StatementUsageWarn =
    getBooleanOption(props, "log4jdbc.statement.warn",false);

//默认的打印所有类型的日志,也可以自己在配置文件中配置只打印某一种类型的日志,比如“select”
  DumpSqlSelect = getBooleanOption(props, "log4jdbc.dump.sql.select",true);
  DumpSqlInsert = getBooleanOption(props, "log4jdbc.dump.sql.insert",true);
  DumpSqlUpdate = getBooleanOption(props, "log4jdbc.dump.sql.update",true);
  DumpSqlDelete = getBooleanOption(props, "log4jdbc.dump.sql.delete",true);
  DumpSqlCreate = getBooleanOption(props, "log4jdbc.dump.sql.create",true);

  DumpSqlFilteringOn = !(DumpSqlSelect && DumpSqlInsert && DumpSqlUpdate &&
    DumpSqlDelete && DumpSqlCreate);

  DumpSqlAddSemicolon = getBooleanOption(props,
    "log4jdbc.dump.sql.addsemicolon", false);

//是否加载所有有名气的数据库驱动,默认是加载
  AutoLoadPopularDrivers = getBooleanOption(props,
    "log4jdbc.auto.load.popular.drivers", true);

  TrimSql = getBooleanOption(props, "log4jdbc.trim.sql", true);

  TrimExtraBlankLinesInSql = getBooleanOption(props, "log4jdbc.trim.sql.extrablanklines", true);

  SuppressGetGeneratedKeysException =
    getBooleanOption(props, "log4jdbc.suppress.generated.keys.exception",
    false);

  // The Set of drivers that the log4jdbc driver will preload at instantiation
  // time.  The driver can spy on any driver type, it's just a little bit
  // easier to configure log4jdbc if it's one of these types!

  Set subDrivers = new TreeSet();

 
  if (AutoLoadPopularDrivers)
  {
    subDrivers.add("oracle.jdbc.driver.OracleDriver");
    subDrivers.add(
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值