1.session.selectList执行过程
在测试方法中调用实现类的findAll()方法,接着看findAll()的实现;
public List<User> findAll() {
SqlSession session = sessionFactory.openSession();
List<User> users = session.selectList("cn.edu.hdu.dao.IUserDao.findAll");
session.close();
return users;
}
可以发现findAll其实是由session的selectList来实现的,接着进入selectList方法
根据打断点的方式,发现SqlSession接口走的selectList方法是由DefaultSqlSession实现的,下面是源码

可以看到最后走到了三个参数的selectList,接着往下走看executor的query方法
Executor是个接口,接着用打断点Debug的方式,可以发现走的是实现类CatchingExecutor实现方法

可以发现在四个参数的query中最后调用6个参数的query方法,且在这个方法,在执行了第一条语句后执行跳转到了最后一行delegate.query执行,并且可以发现这个delegate对象是Executor的实现类SimpleExecutor;
在SimpleExecutor中没有找到query方法,发现它由父类BaseExecutor,进入到这个类中;

可以看到最后又调用了queryFromDatabase这个发发,接着往下走

其实最后调用的是doQuery方法,在BaseExecutor中doQuery方法是个抽象方法,所以从它的子类SimpleExecutor中查看

这里的handler是RoutingStatementHandler,进去查看

它调用的是PreparedStatementHandler类的query方法

在这个方法中,我们发现,熟悉的PrepareStatement类出现了,之后只是在对结果的封装罢了。下面来讲一下PreparedStatement对象的执行方法;
PreparedStatement对象的执行方法
- execute:它能执行CRUD中的任意一种语句。它的返回值是一个boolean类型,表示是否有结果集。true代表有,false代表没有。
- executeUpdate:它只能执行CUD语句,查询语句无法执行。他的返回值是影响数据库记录的行数。
- executeQuery:他只能执行SELECT语句,无法执行增删改。执行结果封装的结果集ResultSet对象。
所以Mybatis在这里调用了execute方法。
2.session.selectOne方法
其实进入到DefaultSqlSession后就可以发现,该方法是由selectList实现的

3.session.update(insert,delete)方法
在Debug执行过程很有趣的是,发现这三个方法最后都去到了一个相同的方法;
在DefaultSqlSession中


也就是说insert和delete最后执行的都是update方法

进入CachingExecutor后发现该方法又调用了SimpleExecutor的update方法

同样和query一样没有找到,去父类BaseExecutor寻找

最后又找回来,执行了SimpleExecutor的doUpdate方法

进入RoutingStatementHandler查看

又执行了PreparedSatementHandler的update方法
最后发现还是用PrepareStatement实现的

总结
SqlSession的方法由DefaultSqlSesssion实现,selectOne调用SelectList实现,insert,delete调用update实现,再调用一系列的Exeacutor的实现类,最后在PreparedSatementHandler中由PreparedStatement类实现。所以Mybatis底层还是由jdbc实现的。
本文深入解析MyBatis框架的底层实现,详细介绍了session.selectList、selectOne、update等核心方法的执行流程,揭示了MyBatis如何通过Executor、PreparedStatementHandler等组件最终调用JDBC完成数据库操作。

3万+

被折叠的 条评论
为什么被折叠?



