• 重新学习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  */
  • 相关阅读:
    “回调地址”全攻略 java程序员
    超棒的纯Javascript实现的文件上传功能 Fine uploader java程序员
    帮助你操作数字和处理数字格式的javascript类库 Numeral.js java程序员
    正则表达式 java程序员
    一款非常棒的CSS 3D下拉式菜单实现Makisu java程序员
    Google的全新在线地图API演示网站 More than a map java程序员
    Android中的布局属性 java程序员
    整理一系列优秀的Android开发源码 java程序员
    Lambda表达式select()和where()的区别
    按公式产生随机数、java中的重载、递归、有关计算机计算的问题
  • 原文地址:https://www.cnblogs.com/gzhcsu/p/12869925.html
Copyright © 2020-2023  润新知