上一篇文章我们了解了什么是mybatis,并通过一个用例实现了一个简单的mybatis查询数据库的数据,在文章的最后针对mybatis如何实现这些功能提出了几个问题。接下来的文章中会对这些问题做一一解答。
本篇文章中解决第一个问题,mybatis为什么调用接口方法就可以实现语句的查询?
实现该功能主要分成两块进行:
- 注册Mapper
- 通过new SqlSessionFactoryBuilder().build(inputStream);构建SqlSessionFactory。在builder方法中将配置文件中的内容转换为Configuration中的对象属性。SqlSessionFactory持有Configuration对象的引用。
- 获取Mapper,调用接口方法
mybatis查询通过以下几个关键类和代码实现
- 通过sqlSession = factory.openSession();创建SqlSession对象
- 通过TestMapper testMapper = sqlSession.getMapper(TestMapper.class);获取mapper代理对象
- 通过testMapper.queryTestDO(1));获取数据库结果集
注册部分关键代码:
XmlConfigBuilder.java
private void parseConfiguration(XNode root) {
try {
......
//(本文关注点)解析mappers标签,将mapper注册到MapperRegistry中
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
/**
*解析mappers标签下的mapper标签,可通过标签属性获取资源package、class、url、resource四种方式获取mapper资源
**/
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
//遍历获取mappers标签下的所有子标签(package/mapper)
for (XNode child : parent.getChildren()) {
//如果mappers下子标签package,则解析name属性该包下的所有类,并注册到MapperRegistry中
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
//解析mapper标签, resource、class、url属性有且只能配置一个,解析属性中的内容,注册到MapperRegistry中
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.ins