ThreadLocal transformation to obtain the tool class of SqlSession [now basically not used, spring automatically encapsulates the object]

Introduction to ThreadLocal

  • In actual development, we use MyBatis framework to obtain SqlSession should belong to the Dao layer code, which is not allowed to appear in the Service layer. If the dao layer data is applied to the services layer, the coupling is improved. We need to delete the service layer's dependency on Mybastis ( dao layer)
  • ThreadLocal is java.lang.ThreadLocal This class provides thread-local variables for sharing data in the current thread.

Review threads to understand ThreadLocal

  We know that the process is a resource allocation unit, the thread is scheduled to run the unit . Any running program must belong to a certain thread. Whether it is the main thread/gc thread or other threads.
  When the program is running, a thread will be generated. There is a Context in the thread. The way to obtain the thread context: Thread.currentThread().getContext();(return type ThreadContext)
  In the JDK, the thread context is created only when it is used, and the context for creating the thread is through ThreadLocal To achieve .
ThreadLocal is the proxy object of the thread context context. It is mainly used to store data (through get and set methods). It is the bottom layer that stores data in the form of Map key-value pairs. When ThreadLocal calls the set method to store data, its The key is to store itself (this-current thread).
Insert picture description here

ThreadLocal features

  1. The bottom layer of the ThreadLocal tool class is in the form of a Map key-value pair. The key stores the current thread (this), and the value stores the data that needs to be shared (data can only be shared between the same threads).
  2. The data stored by which thread is used can only be retrieved through that thread (the thread that stores the data)
  3. ThreadLocal guarantees the independence of data in a multi-threaded environment (data between different threads is not shared, only the same thread data is shared)

Use ThreadLocal to load the SqlSession of MyBatis objects to achieve decoupling of service and dao layers

Transform SqlSessionUtils2:

//sqlSession工具类,获取sqlSession
public class SqlSessionUtils2 {
    
    
    private static SqlSessionFactory sqlSessionFactory;
    //static 静态代码,在类加载的时候执行一次,且只执行一次
    static{
    
    
        //1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //2. 加载mybatis-config.xml配置文件   参数:核心配置文件
        InputStream inputStream = SqlSessionUtils.class.getClassLoader().getResourceAsStream("com/xgf/mybatisdemo/config/mybatis-config.xml");
        //3. 创建SqlSessionFactory对象  加载核心配置文件  参数:输入流
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);

    }

    //通过ThreadLocal改造
    //A: 定义一个ThreadLocal集合,本质是Map<Thread,Object> map
    private   static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();//这个key默认是当前线程,value就是传入的参数SqlSession类型

    public static SqlSession getSession() {
    
    

        //查找在当前线程中,是否有对应的SqlSession
        SqlSession sqlSession = threadLocal.get(); //相当于map.get(Thread.currentThread())
        if (sqlSession != null) {
    
    
            //当前线程存在SqlSession直接返回给调用者使用
            return sqlSession;
        } else {
    
    
            //没有就创建一个新的,并且保存在当前线程中
            sqlSession = sqlSessionFactory.openSession();
            //保存
            threadLocal.set(sqlSession);//实际存储的是threadLocal.set(Thread.currentThread(),sqlSession)
            return sqlSession;//返回
        }
    }

    public static void commitAndClose() {
    
    
        //进行修改表操作,需要提交sqlSession才能更新数据库,定义这个方法
        SqlSession sqlSession = threadLocal.get();
        if (sqlSession != null) {
    
    
            sqlSession.commit();//提交
            sqlSession.close();//关闭
            //已经关闭的session不能留在threadLocal中
            //所以要删除
            threadLocal.remove();
        }
    }

    //出现错误,回调
    public static void rollbackAndClose() {
    
    
        SqlSession sqlSession = threadLocal.get();
        if (sqlSession != null) {
    
    
            sqlSession.rollback();//回滚
            sqlSession.close();//释放
            //已经关闭的session不能留在local
            //所以要删除
            threadLocal.remove();
        }
    }

    //通过该方法实现dao和service解耦
    public static <T> T getMapper(Class className) {
    
    
        return (T) getSession().getMapper(className);
    }
}

Guess you like

Origin blog.csdn.net/qq_40542534/article/details/108875123