重新学习MyBatis(六)

查询流程:

代码debug分析:

 1 public class MyBatisTest {
 2 
 3     public SqlSessionFactory getSqlSessionFactory() throws IOException {
 4         String resource = "mybatis-config.xml";
 5         InputStream inputStream = Resources.getResourceAsStream(resource);
 6         return new SqlSessionFactoryBuilder().build(inputStream);
 7     }
 8 
 9     /**
10      * 1、获取sqlSessionFactory对象:
11      *         解析文件的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSession;
12      *         注意:【MappedStatement】:代表一个增删改查的详细信息
13      * 
14      * 2、获取sqlSession对象
15      *         返回一个DefaultSQlSession对象,包含Executor和Configuration;
16      *         这一步会创建Executor对象;
17      * 
18      * 3、获取接口的代理对象(MapperProxy)
19      *         getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象
20      *         代理对象里面包含了,DefaultSqlSession(Executor)
21      * 4、执行增删改查方法
22      * 
23      * 总结:
24      *     1、根据配置文件(全局,sql映射)初始化出Configuration对象
25      *     2、创建一个DefaultSqlSession对象,
26      *         他里面包含Configuration以及
27      *         Executor(根据全局配置文件中的defaultExecutorType创建出对应的Executor)
28      *  3、DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy;
29      *  4、MapperProxy里面有(DefaultSqlSession);
30      *  5、执行增删改查方法:
31      *          1)、调用DefaultSqlSession的增删改查(Executor);
32      *          2)、会创建一个StatementHandler对象。
33      *              (同时也会创建出ParameterHandler和ResultSetHandler)
34      *          3)、调用StatementHandler预编译参数以及设置参数值;
35      *              使用ParameterHandler来给sql设置参数
36      *          4)、调用StatementHandler的增删改查方法;
37      *          5)、ResultSetHandler封装结果
38      *  注意:
39      *      四大对象每个创建的时候都有一个interceptorChain.pluginAll(parameterHandler);
40      * 
41      * @throws IOException
42      */
43     @Test
44     public void test01() throws IOException {
45         // 1、获取sqlSessionFactory对象
46         SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
47         // 2、获取sqlSession对象
48         SqlSession openSession = sqlSessionFactory.openSession();
49         try {
50             // 3、获取接口的实现类对象
51             //会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
52             EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
53             Employee employee = mapper.getEmpById(1);
54             System.out.println(mapper);
55             System.out.println(employee);
56         } finally {
57             openSession.close();
58         }
59 
60     }
61 
62 }
Configuration的创建过程如下:
 1 /*
 2 Configuration的创建过程:
 3 1.sqlSessionFactoryBuilder.build(inputStream)
 4 
 5 2.build(InputStream inputStream, String environment, Properties properties);
 6 
 7 3.build(parser.parse())--->parser.parse()
 8 
 9 4.parseConfiguration(parser.evalNode("/configuration"));
10 
11 5.private void parseConfiguration(XNode root) {
12     try {
13       Properties settings = settingsAsPropertiess(root.evalNode("settings"));
14       //issue #117 read properties first
15       propertiesElement(root.evalNode("properties"));       // ① 读取<properties>,并设置
16       loadCustomVfs(settings);                              // ② 读取之前<settings>,并设置
17       typeAliasesElement(root.evalNode("typeAliases"));     // ③ 读取<typeAliases>,并设置
18       pluginElement(root.evalNode("plugins"));              // ④ 读取<plugins>,并设置
19       objectFactoryElement(root.evalNode("objectFactory")); // ⑤ 读取<objectFactory>,并设置
20       objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); // ⑥ 读取<objectWrapperFactory>,并设置
21       reflectorFactoryElement(root.evalNode("reflectorFactory")); // ⑦ 读取<reflectorFactory>,并设置
22       settingsElement(settings);
23       // read it after objectFactory and objectWrapperFactory issue #631
24       environmentsElement(root.evalNode("environments"));   // ⑧ 读取<environments>,并设置
25       databaseIdProviderElement(root.evalNode("databaseIdProvider")); // ⑨ 读取<databaseIdProvider>,并设置
26       typeHandlerElement(root.evalNode("typeHandlers")); // ⑨ 读取<databaseIdProvider>,并设置
27       mapperElement(root.evalNode("mappers"));  // ⑨ 读取<mappers>,并设置
28     } catch (Exception e) {
29       throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
30     }
31   }
32 
33 // 读取xxxMapper.xml或者xxxMapperAnnotation...
34 6.private void mapperElement(XNode parent) throws Exception {
35     if (parent != null) {
36       for (XNode child : parent.getChildren()) {
37         if ("package".equals(child.getName())) {
38           String mapperPackage = child.getStringAttribute("name");
39           configuration.addMappers(mapperPackage);
40         } else {
41           String resource = child.getStringAttribute("resource");
42           String url = child.getStringAttribute("url");
43           String mapperClass = child.getStringAttribute("class");
44           if (resource != null && url == null && mapperClass == null) {
45             ErrorContext.instance().resource(resource);
46             InputStream inputStream = Resources.getResourceAsStream(resource);
47             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
48             mapperParser.parse(); // 解析mapper,xml--->configurationElement(parser.evalNode("/mapper"));
49           } else if (resource == null && url != null && mapperClass == null) {
50             ErrorContext.instance().resource(url);
51             InputStream inputStream = Resources.getUrlAsStream(url);
52             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
53             mapperParser.parse();
54           } else if (resource == null && url == null && mapperClass != null) {
55             Class<?> mapperInterface = Resources.classForName(mapperClass);
56             configuration.addMapper(mapperInterface);
57           } else {
58             throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
59           }
60         }
61       }
62     }
63   }
64 // 解析具体的mapper.xml 
65 7.private void configurationElement(XNode context) {
66     try {
67       String namespace = context.getStringAttribute("namespace");
68       if (namespace == null || namespace.equals("")) {
69         throw new BuilderException("Mapper's namespace cannot be empty");
70       }
71       builderAssistant.setCurrentNamespace(namespace);
72       cacheRefElement(context.evalNode("cache-ref"));
73       cacheElement(context.evalNode("cache"));
74       parameterMapElement(context.evalNodes("/mapper/parameterMap"));
75       resultMapElements(context.evalNodes("/mapper/resultMap"));
76       sqlElement(context.evalNodes("/mapper/sql"));
77       buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
78     } catch (Exception e) {
79       throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
80     }
81   }
82  */
原文地址:https://www.cnblogs.com/gzhcsu/p/12869925.html