mybatis运行原理--sqlSessionFactory

根据mybayis-config.xml的Resources经过解析,把所有的mapper.xml解析封装成MappedStatement,所有结果统一放入Configuration,最后得到defaultSqlSessionFactory.

这里第五步通过mappers的配置的方法有两种,一种是package,将包下的class也就是我们的mapperInterface添加到configuration中,因为mybatis要求我们将接口和xml文件在同一路径下,后续根据class和xml中的namespace对应就可以找到对应的xml配置文件了。

另外一种就是列举所有的xml路径。通过resouce、url、class三种,resouce、url需要的是mapper.xml,在这个过程中也就会解析xml中定义的namespace、resultMap、sql标签等。sql标签封装成mappedStatement,后续通过namespace就可以找到对应的mapper接口,通过sql的id找到对应接口的方法。class的方式同package性质类似。

private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
        for (XNode child : parent.getChildren()) {
            if ("package".equals(child.getName())) {
                String mapperPackage = child.getStringAttribute("name");
                configuration.addMappers(mapperPackage);
            } else {
                String resource = child.getStringAttribute("resource");
                String url = child.getStringAttribute("url");
                String mapperClass = child.getStringAttribute("class");
                if (resource != null && url == null && mapperClass == null) {
                    ErrorContext.instance().resource(resource);
                    try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource,
                                                                             configuration.getSqlFragments());
                        mapperParser.parse();
                    }
                } else if (resource == null && url != null && mapperClass == null) {
                    ErrorContext.instance().resource(url);
                    try (InputStream inputStream = Resources.getUrlAsStream(url)) {
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url,
                                                                             configuration.getSqlFragments());
                        mapperParser.parse();
                    }
                } else if (resource == null && url == null && mapperClass != null) {
                    Class<?> mapperInterface = Resources.classForName(mapperClass);
                    configuration.addMapper(mapperInterface);
                } else {
                    throw new BuilderException(
                        "A mapper element may only specify a url, resource or class, but not more than one.");
                }
            }
        }
    }
}

posted @ 2023-05-10 17:44  源灬点  阅读(25)  评论(0编辑  收藏  举报