在前几篇文章中我们分析了Mybatis的几个核心对象,陈述了各对象的作用以及对源码做了简单的分析。本文会将前几篇文章中提到的核心对象做一次串联,以一个简单的查询为例Debug流程,探究Mybatis是如何执行我们所编写的SQL的。
1、实体类
@Alias("Person")
public class Person {
private Long id;
private String username;
private String password;
//省略get/set toString方法
}
2、Dao接口
public interface PersonMapper {
List selectAll();
Person selectById(@Param("id")Long id);
}
3、main方法
public static void main(String[] args) throws Exception {
String resource = "mybatis-config.xml";
//读取mybatis配置文件并获取输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper mapper = session.getMapper(PersonMapper.class);
Person person = mapper.selectById(1L);
System.out.println(person);
}
}
二、开始Debug
我们在 Person person = mapper.selectById(1L);这一行上打上断点,然后进入。
我们会发现进入了一个名为MapperProxy的类**,从该类的命名中可以看出这个是一个代理类,实际上Mybatis是通过JDK动态代理来“实例化”接口的(其实是动态的创建了Mapper接口的实现类,这一部分在后文后讲解,这里只是提出这个概念)。
其中核心的代码是mapperMethod.execute(sqlSession, args),通过Debug可以看出这个 args参数就是我们传入的id = 1;继续往下Debug,我们进入了MappedMethod类中的execute方法**
首先该方法会判断我们的SQL类型,很明显本次的SQL是SELECT类型的,同时返回的是单个数据,所以我们进入了result = sqlSession.selectOne(command.getName(), param);这行代码,继续Debug,然后就进入了我们熟悉的DefaultSqlSession,同时也看到了我们熟悉的SimpleExecutor
继续Debug,然后就遇见了前文分析过的BaseExecutor中的query方法
继续Debug之后又又又又遇到了熟悉的代码StatementHandler
继续Debug,就碰到了前文分析过的ResultSetHandler,最终我们就获得了要查询的结果。
至此我们已经对Mybatis是如何执行一个SQL做了一次Debug,实际上还有很多复杂的操作,这里我们不需要了解,对于框架的学习我们更多学习的是思想,知道框架是如何运行的,不必过分在意一两个类或者一两个方法时如何执行的。下一篇文章我们会探究Mybatis中的Dao接口是如何被“实例化的”,希望对你有所帮助。



