• mybatis源码阅读-SqlSessionFactory和SqlSession(三)


    说明

    读了3遍:https://my.oschina.net/zudajun/blog/665956 现在统一整理成笔记 并跟着源码一行一行调试 统一整理起来

    SqlSession

    接口定义

    public interface SqlSession extends Closeable {
        <T> T selectOne(String var1);
    
        <T> T selectOne(String var1, Object var2);
    
        <E> List<E> selectList(String var1);
    
        <E> List<E> selectList(String var1, Object var2);
    
        <E> List<E> selectList(String var1, Object var2, RowBounds var3);
    
        <K, V> Map<K, V> selectMap(String var1, String var2);
    
        <K, V> Map<K, V> selectMap(String var1, Object var2, String var3);
    
        <K, V> Map<K, V> selectMap(String var1, Object var2, String var3, RowBounds var4);
    
        <T> Cursor<T> selectCursor(String var1);
    
        <T> Cursor<T> selectCursor(String var1, Object var2);
    
        <T> Cursor<T> selectCursor(String var1, Object var2, RowBounds var3);
    
        void select(String var1, Object var2, ResultHandler var3);
    
        void select(String var1, ResultHandler var2);
    
        void select(String var1, Object var2, RowBounds var3, ResultHandler var4);
    
        int insert(String var1);
    
        int insert(String var1, Object var2);
    
        int update(String var1);
    
        int update(String var1, Object var2);
    
        int delete(String var1);
    
        int delete(String var1, Object var2);
    
        void commit();
    
        void commit(boolean var1);
    
        void rollback();
    
        void rollback(boolean var1);
    
        List<BatchResult> flushStatements();
    
        void close();
    
        void clearCache();
    
        Configuration getConfiguration();
    
        <T> T getMapper(Class<T> var1);
    
        Connection getConnection();
    }

    完成数据库CRUD操作

    实现类结构图

    DefaultSqlSession部分源码 

     //执行器 接口
        private Executor executor;
        //配置文件 类
        private Configuration configuration;
        /***
         * 查询方法
         * @param statement mapper.xml namesapce+id
         * @param parameter 查询参数
         * @param rowBounds 分页参数 解析返回值的handler
         */
        public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
            List var5;
            try {
                //从config根据 namesapce+id 获得对应的mappedStatement 然后交给executor的query方法
                MappedStatement ms = this.configuration.getMappedStatement(statement);
                var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
            } catch (Exception var9) {
                throw ExceptionFactory.wrapException("Error querying database.  Cause: " + var9, var9);
            } finally {
                ErrorContext.instance().reset();
            }
    
            return var5;
        }
        /**
         * 修改方法 增加删除也是最终调用这个方法
         * @param statement mapper.xml namesapce+id
         * @param parameter 参数
         * @return
         */
        public int update(String statement, Object parameter) {
            int var4;
            try {
                this.dirty = true;
                //从config根据 namesapce+id 获得对应的mappedStatement 然后交给executor的query方法
                MappedStatement ms = this.configuration.getMappedStatement(statement);
                var4 = this.executor.update(ms, this.wrapCollection(parameter));
            } catch (Exception var8) {
                throw ExceptionFactory.wrapException("Error updating database.  Cause: " + var8, var8);
            } finally {
                ErrorContext.instance().reset();
            }
    
            return var4;
        }

    职责是根据namesapce+id 获得对应的mappedStatement然后交给executor执行

    SqlSessionFactory

    接口定义

    public interface SqlSessionFactory {
        SqlSession openSession();
    
        SqlSession openSession(boolean var1);
    
        SqlSession openSession(Connection var1);
    
        SqlSession openSession(TransactionIsolationLevel var1);
    
        SqlSession openSession(ExecutorType var1);
    
        SqlSession openSession(ExecutorType var1, boolean var2);
    
        SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
    
        SqlSession openSession(ExecutorType var1, Connection var2);
    
        Configuration getConfiguration();
    }

    sqlSession工厂

    类图

    DefaultSqlSessionFactory源码

    public class DefaultSqlSessionFactory implements SqlSessionFactory {
        //配置文件 保存了解析的mybaits.xml和mapper.xml的内容
        private final Configuration configuration;
    
        /**
         * openSession()最终都是调用这个方法创建Session
         * @param execType 执行器
         * @param level 事物隔离级别
         * @param autoCommit 是否自动提交
         * @return
         */
        private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
            Transaction tx = null;
    
            DefaultSqlSession var8;
            try {
                //根据配置文件获得Environment 内部封装了数据源信息和事物管理器Factory  environments标签配置
                Environment environment = this.configuration.getEnvironment();
                //获得对应的事物管理器
                TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
                //开启事物
                tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
                //创建执行器
                Executor executor = this.configuration.newExecutor(tx, execType);
                //创建DefaultSqlSession
                var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
            } catch (Exception var12) {
                this.closeTransaction(tx);
                throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
            } finally {
                ErrorContext.instance().reset();
            }
    
            return var8;
        }
    
        /**
         * 判断是否有指定事物管理创建工厂 如果没有指定 则默认ManagedTransactionFactory environments标签配置
         * @param environment
         * @return
         */
        private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
            return (TransactionFactory)(environment != null && environment.getTransactionFactory() != null ? environment.getTransactionFactory() : new ManagedTransactionFactory());
        }
    
    }

     SqlSessionManager

    使用

    执行完后自动提交回滚 创建2个session

      public static void main(String[] args) throws FileNotFoundException {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder
                    .build(ClassLoader.getSystemResourceAsStream("mybatis.xml"));
            SqlSessionManager sqlSessionManager = SqlSessionManager.newInstance(sqlSessionFactory);
            List<Classes> list = sqlSessionManager.selectList("classes.selectAll");
            list = sqlSessionManager.selectList("classes.selectAll");
        }

    创建一个session手动提交回滚

    public static void main(String[] args) throws FileNotFoundException {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder
                    .build(ClassLoader.getSystemResourceAsStream("mybatis.xml"));
            SqlSessionManager sqlSessionManager=null;
            try {
                sqlSessionManager.startManagedSession();
                List<Classes> list = sqlSessionManager.selectList("classes.selectAll");
                list = sqlSessionManager.selectList("classes.selectAll");
                sqlSessionManager.commit();
            }catch (Exception e) {
                if(sqlSessionManager!=null) {
                    sqlSessionManager.rollback();
                }
            }
        }

    类图

    源码

    public class SqlSessionManager implements SqlSessionFactory, SqlSession {
        private final SqlSessionFactory sqlSessionFactory;
        //被代理的sqlSeesion
        private final SqlSession sqlSessionProxy;
        //线程缓存
        private ThreadLocal<SqlSession> localSqlSession = new ThreadLocal();
    
        private SqlSessionManager(SqlSessionFactory sqlSessionFactory) {
            this.sqlSessionFactory = sqlSessionFactory;
            //代理sqlSession 第一个参数类装载器 第二个参数哪个接口类型被代理  第三个参数为代理类 为SqlSessionManager内部内
            this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionManager.SqlSessionInterceptor());
        }
    
        public <T> T selectOne(String statement, Object parameter) {
            return this.sqlSessionProxy.selectOne(statement, parameter);
        }
    
        public int insert(String statement) {
            return this.sqlSessionProxy.insert(statement);
        }
    
        public int update(String statement, Object parameter) {
            return this.sqlSessionProxy.update(statement, parameter);
        }
    
        public int delete(String statement) {
            return this.sqlSessionProxy.delete(statement);
        }
      public SqlSession openSession() {
    return this.sqlSessionFactory.openSession();
      }
    }

    内部类SqlSessionInterceptor源码

     private class SqlSessionInterceptor implements InvocationHandler {
            public SqlSessionInterceptor() {
            }
    
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //从当前线程获得SqlSession 如果为空则创建不为空则直接使用缓存中的SqlSession
                SqlSession sqlSession = (SqlSession)SqlSessionManager.this.localSqlSession.get();
                if (sqlSession != null) {
                    try {
                        //直接使用线程缓存中的SqlSession 并不提交不回滚
                        return method.invoke(sqlSession, args);
                    } catch (Throwable var12) {
                        throw ExceptionUtil.unwrapThrowable(var12);
                    }
                } else {
                    //调用SqlSessionManager的openSession方法获得SqlSession 执行完毕后提交回滚
                    SqlSession autoSqlSession = SqlSessionManager.this.openSession();
    
                    Object var7;
                    try {
                        Object result = method.invoke(autoSqlSession, args);
                        autoSqlSession.commit();
                        var7 = result;
                    } catch (Throwable var13) {
                        autoSqlSession.rollback();
                        throw ExceptionUtil.unwrapThrowable(var13);
                    } finally {
                        autoSqlSession.close();
                    }
    
                    return var7;
                }
            }
        }
  • 相关阅读:
    洛谷春季多校第四场
    HZNU Training 8 for Zhejiang Provincial Competition 2020
    HZNU Training 6 for Zhejiang Provincial Competition 2020
    二分图
    HZNU Training 5 for Zhejiang Provincial Competition 2020
    洛谷春季 ACM 多校训练第二周
    HZNU Training 2 for Zhejiang Provincial Competition 2020
    TestNG入门教程-12-Java代码执行testng.xml和失败后重跑
    eclipse导出可执行jar包步骤
    创建可执行的JAR包并运行
  • 原文地址:https://www.cnblogs.com/LQBlog/p/9277786.html
Copyright © 2020-2023  润新知