• mybatis源码——日志ErrorContext类


    一、特性表示

      mybatis的日志输出具有如下特性:

      (1)日志量随程序执行量增加(例如:xml文件中sql报错,那么一定会有初始化、xml加载等信息出现);

      (2)日志输出的顺序,是按顺序且隔离的;

    二、附上源代码

    package org.apache.ibatis.executor;
    
    /**
     * @author Clinton Begin
     */
    public class ErrorContext {
    
      private static final String LINE_SEPARATOR = System.getProperty("line.separator","
    ");
      private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
    
      //暂存线程上下文
      private ErrorContext stored;
    
      private String sql;
      ... //各个阶段的值存储
    
      private Throwable cause;
    
      private ErrorContext() {
      }
    
      public static ErrorContext instance() {
        //单例模式,从当前线程获取线程存储变量(一个)
        ErrorContext context = LOCAL.get();
        if (context == null) {
          context = new ErrorContext();
          LOCAL.set(context);
        }
        return context;
      }
    
      public ErrorContext store() {
        stored = this;
        LOCAL.set(new ErrorContext());
        return LOCAL.get();
      }
    
      public ErrorContext recall() {
        if (stored != null) {
          LOCAL.set(stored);
          stored = null;
        }
        return LOCAL.get();
      }
    
      public ErrorContext sql(String sql) {
        //这种写法是流式编程
        this.sql = sql;
        return this;
      }
    
      public ErrorContext cause(Throwable cause) {
        this.cause = cause;
        return this;
      }
    
      public ErrorContext reset() {
        ...各个阶段记录初始化
        sql = null;
        
        LOCAL.remove();
        return this;
      }
    
      @Override
      public String toString() {
        StringBuilder description = new StringBuilder();
    
        ...各阶段日志输出
    
        // sql
        if (sql != null) {
          description.append(LINE_SEPARATOR);
          description.append("### SQL: ");
          description.append(sql.replace('
    ', ' ').replace('
    ', ' ').replace('	', ' ').trim());
        }
    
        // cause
        if (cause != null) {
          description.append(LINE_SEPARATOR);
          description.append("### Cause: ");
          description.append(cause.toString());
        }
    
        return description.toString();
      }
    
    }
    

      

    此处有几个值得借鉴的地方:

    (1)使用ThreadLocal<ErrorContext>类变量可以做到在当前线程执行的任何阶段保证只有一个类对象实例。即使说,只要是出于一个线程,不论走多少层方法栈都没关系,只要使用对应方法将对应阶段的信息记录下来,最终在所有操作完结的使用toString()一下就能将整个过程的信息输出出来。(否则就要将信息存储的类一个接一个方法地以形参方式传入)

    (2)每个记录方法都以类对象this返回,可以使用流式编程。简洁明了,可以直接将方法名.出来

  • 相关阅读:
    sqlserver服务 正在挂起更改,导致无法打开或者停止服务
    menuStrip与toolStrip的使用
    sqlDataCommandBuilder为dataGridView自动生成增删改代码时报错
    visual studio属性面板解释文字看不见
    窗体句柄 控件句柄
    form窗体show不出来
    TextBox密码框变文本框,文本框变密码框
    DataSet数据集手动添加一行记录
    Anaconda3-更换为清华源后依旧报错CondaHTTPError: HTTP 000 CONNECTION FAILED
    Kali Linux 国内源
  • 原文地址:https://www.cnblogs.com/chendeming/p/9461681.html
Copyright © 2020-2023  润新知