zoukankan      html  css  js  c++  java
  • 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返回,可以使用流式编程。简洁明了,可以直接将方法名.出来

  • 相关阅读:
    js和css
    主题
    php.ini
    css 选择器、元素默认宽度、media screen
    linux 重要笔记
    cookie和session、
    tp5 报 A non well formed numeric value encountered 的错解决办法
    pdo
    二叉树
    顺序串
  • 原文地址:https://www.cnblogs.com/chendeming/p/9461681.html
Copyright © 2011-2022 走看看