为了理清楚ibatis一次sql过程中发生了什么,本文将对ibatis一次sql过程做简要的分析。
首先分析下SqlSession session = ssf.openSession(); 这条语句里面发生了什么,其实这条语句就是通过SqlSessionFactory工厂获取一次查询的Session。其中上一句SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader); 这句代码通过xml文件获取到SqlSessionFactory工厂,深入进去发现最终获取色SqlSessionFactory最终调用的是下面这个方法
拿到SqlSessionFactory后我们再去看看SqlSession session = ssf.openSession();这句代码究竟干了什么?深入代码发现ssf.openSession()最终调用了一下方法。
可以从方法中看出,首先获取加载配置文件的环境信息,为后面获取环境信息中配置的数据源做准备,从环境配置中获取事务工厂。以JDBD事务为例。在JdbcTransaction中封装了数据库连接操作,因此此处并没有
创建数据库连接。接着根据获取到的事务和执行类型以及是否提交获取Executor实例。其中newExecutor(tx, execType, autoCommit)代码如下所示;
这里主要做了三件事
(1)判断执行器类型,如果配置文件中没有配置执行器类型,则采用默认执行类型ExecutorType.SIMPLE。
(2)根据执行器类型返回不同类型的执行器(执行器有三种,分别是 BatchExecutor、SimpleExecutor和CachingExecutor,后面我们再详细看看)。
(3)跟执行器绑定拦截器插件。
最后将返回DefaultSqlSession(configuration, executor)。 DefaultSqlSession实现了SqlSession接口,而SqlSession接口装封装了大量跟数据操作有关的方法,可以断言,所有的操作将在
DefaultSqlSession中发生,例子中UserInfo user = (UserInfo) session.selectOne("User.selectUser", "1"); 为例进去看看,这个代码最终会执行以下几个方法。
其中MappedStatement ms = configuration.getMappedStatement(statement);这句话是根据“User.selectUser”找到在Mapper配置文件的信息。
接着根据配置文件信息也就是MappedStatement 去执行executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
进入到executor.query()方法中可以看出:首先调用BaseExecutor中这个方法;
这个方法中我着重看下这个语句list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);意思是从数据库中获取查询,具体如下所示:
暂时还没有看到时如何查询,进一步深入到doQuery(ms, parameter, rowBounds, resultHandler, boundSql);这个方法中是个抽象方法在子类中有实现,我们挑选其中一个实现看了下具体如下所示:
后面基本就是JDBC操作数据库的内容了。到此一次SQL语句到此完毕。