1.加载配置文件 进行初始化都干了什么?
把配置文件通过xml解析产生configruation配置信息对象
SqlSessionFactoryBuilder通过Configuration对象创建一个DefaultSessionFactory对象并返回
配置文件中的SQL块解析并放到一个MappedStatement里面,后面根据sql的id就能获得对应的MappedStatement
/ 创建XMLConfigBuilder对象用来解析XML配置文件,生成Configuration对象 XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); //将XML配置文件内的信息解析成Java对象Configuration对象 Configuration config = parser.parse(); //SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象并返回; return build(config);
2.从sqlSessonFactory打开一个sqlSesson 都干了什么?
第一步:打开一个会话,我们看看里面具体做了什么事情。
的Java代码 SqlSession session = ssf.openSession();
DefaultSqlSessionFactory的openSession()方法内容如下:
的Java代码 public SqlSession openSession(){ 返回 openSessionFromDataSource(configuration.getDefaultExecutorType(), null , false ); }
跟进去,我们看一下openSessionFromDataSource方法到底做了啥:
的Java代码 private SqlSession openSessionFromDataSource(ExecutorType execType,TransactionIsolationLevel level, boolean autoCommit){ 连接连接= null ; 尝试 { final environment environment = configuration.getEnvironment(); 最终的 DataSource dataSource = getDataSourceFromEnvironment(environment); TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); connection = dataSource.getConnection(); if (level!= null ){ connection.setTransactionIsolation(level.getLevel()); } connection = wrapConnection(connection); 事务tx = transactionFactory.newTransaction(connection,autoCommit); 执行者executor = configuration.newExecutor(tx,execType); 返回新的 DefaultSqlSession(配置,executor,autoCommit); } catch (Exception e){ closeConnection(连接); throw ExceptionFactory.wrapException(“打开会话错误原因:” + e,e); } finally { ErrorContext.instance()复位(); } }
这里我们分析一下这里所涉及的步骤:
(1)获取前面我们加载配置文件的环境信息,并且获取环境信息中配置的数据源。
(2)通过数据源获取一个连接,对连接进行包装代理(通过JDK的代理来实现日志功能)。
(3)设置连接的事务信息(是否自动提交,事务级别),从配置环境中获取事务工厂,事务工厂获取一个新的事务。
(4)传入事务对象获取一个新的执行器,并传入执行器,配置信息等获取一个执行会话对象。
从上面的代码我们可以得出,一次配置加载只能有且对应一个数据源。对于上述步骤,我们不难理解,我们重点看看新建执行器和DefaultSqlSession。
首先,我们看看newExecutor到底做了什么?
的Java代码 public Executor newExecutor(Transaction transaction,ExecutorType executorType){ executorType = executorType == null ?defaultExecutorType:executorType; executorType = executorType == null ?ExecutorType.SIMPLE:executorType; 执行执行人 if (ExecutorType.BATCH == executorType){ executor = new BatchExecutor(this ,transaction); } else if (ExecutorType.REUSE == executorType){ executor = new ReuseExecutor(this ,transaction); } else { executor = new SimpleExecutor(this ,transaction); } if (cacheEnabled){ executor = new CachingExecutor(executor); } executor =(Executor)interceptorChain.pluginAll(executor); 退货 执行人 }
上面代码的执行步骤如下:
(1)判断执行器类型,如果配置文件中没有配置执行器类型,则采用默认执行类型ExecutorType.SIMPLE。
(2)根据执行器类型返回不同类型的执行器(执行器有三种,分别是BatchExecutor,SimpleExecutor和CachingExecutor,后面我们再详见看看)。
(3)跟执行器绑定拦截器插件(这里也是使用代理来实现)。
DefaultSqlSession到底是干什么的呢?
DefaultSqlSession实现了SqlSession的接口,里面有各种各样的SQL执行方法,主要用于SQL操作的对外接口,它会的调用执行器来执行实际的SQL语句。
接下来我们看看SQL查询是怎么进行的
3-1).通过sqlSession直接调用封装好的crud的方法操作数据库