MyBatis的四种资源加载方式以及优先级
什么是MyBatis资源加载?
MyBatis资源加载指的就是如何加载我们定义好的映射文件(可能使用的是XML方式,也可能是注解方式),只有这样,MyBatis才能解析我们写的SQL以及将XML中的SQL和接口中的方法关联起来等等。
其实所有的资源加载都差不多,Spring也有这样的资源加载机制,例如支持URL方式的资源加载、支持classpath方式的资源加载、支持文件方式的资源加载等等。
MyBatis的资源加载方式有几种?
我们可以首先查看MyBatis官方文档。在官方文档中给出了四种资源加载的方式:
分别是类路径下的资源加载、URL资源加载、全限定名资源加载、包路径资源加载。但是在官方文档中并没有给出这四种方式的优先级,这一点,我们可以从源码中得到答案。
通常我们都会编写一个mybatis-config.xml文件来配置MyBatis,而解析这个XML则是由XMLConfigBuilder来完成,在其parse方法中完成了XML解析。
public Configuration parse() {if (parsed) {throw new BuilderException("Each XMLConfigBuilder can only be used once.");}parsed = true;// 获取<configuration>根元素parseConfiguration(parser.evalNode("/configuration"));return configuration;
}
private void parseConfiguration(XNode root) {try {// 解析<properties>标签propertiesElement(root.evalNode("properties"));// 解析<settings>标签Properties settings = settingsAsProperties(root.evalNode("settings"));loadCustomVfs(settings);loadCustomLogImpl(settings);// 解析<typeAliases>标签typeAliasesElement(root.evalNode("typeAliases"));// 解析<plugins>标签pluginElement(root.evalNode("plugins"));// 解析<objectFactory>标签objectFactoryElement(root.evalNode("objectFactory"));// 解析<objectWrapperFactory>标签objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));// 解析<reflectorFactory>标签reflectorFactoryElement(root.evalNode("reflectorFactory"));settingsElement(settings);// 解析<environments>标签environmentsElement(root.evalNode("environments"));// 解析<databaseIdProvider>标签databaseIdProviderElement(root.evalNode("databaseIdProvider"));// 解析<typeHandlers>标签typeHandlerElement(root.evalNode("typeHandlers"));// 本次分析重点!!! 解析<mappers>标签mapperElement(root.evalNode("mappers"));} catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);}
}
通过以上分析,我们也可以得知为什么在mybatis-config.xml文件中那些标签的顺序是那样的,因为在源码中已经规定了解析的顺序。
在mapperElement方法中,我们就可以找到四种资源加载方式的优先级问题答案。
private void mapperElement(XNode parent) throws Exception {if (parent != null) {for (XNode child : parent.getChildren()) {// 首先解析的资源加载方式是<package>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");// 其次,解析的资源加载方式是<resource>if (resource != null && url == null && mapperClass == null) {ErrorContext.instance().resource(resource);InputStream inputStream = Resources.getResourceAsStream(resource);XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());mapperParser.parse();// 否则,解析的资源加载方式是<url >} else if (resource == null && url != null && mapperClass == null) {ErrorContext.instance().resource(url);InputStream inputStream = Resources.getUrlAsStream(url);XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());mapperParser.parse();// 最后,解析的资源加载方式是<class>} 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.");}}}}
}
这四种资源加载方式的优先级为:package->resource->url->class。
如果同时指定了这四种方式,只有package方式生效。如果同时指定了resource、url、class,那么这三种都不会生效,而是抛出异常。因为在解析resource、url、class这三种方式中任何一种方式时,都要求另外两种必须为null,如果不为null,则不会解析。
MyBatis的四种资源加载方式以及优先级相关推荐
- Unity游戏开发——新发教你做游戏(三):3种资源加载方式
文章目录 一.前言 二.Unity的目录结构规范 1.Resources(不是很推荐把资源放这个目录) 2.RawAssets(存放生资源) 3.GameRes(存放熟资源) 4.StreamingA ...
- Unity中的三种资源加载和卸载
前言 内容转载自: https://www.cnblogs.com/zhoujiangyue/articles/7066070.html. Unity中三种资源加载方式: 1.静态引用.具体操作:创建 ...
- VELOCITY三种属性加载方式
一.velocity默认的加载方式(文件加载方式) package com.velocity.test; import java.io.StringWriter; import java.util.P ...
- Unity资源加载方式
一.Unity特殊资源目录 Resources:逻辑资源目录,这个目录中的资源会打入到包中,不允许热更.在打包时会被压缩和加密. 加载方式:Resources.Load(常用) . AssetData ...
- Creator3D:入门一定要会的几种资源加载
前言 今天菜鸟整理了一些Creator3D最常见的资源加载方面的东西和大家分享一下,希望对大家有所帮助, 正文 菜鸟今天写的主要是项目中常见的动态加载图片显示和json读取. 在Creator3D中进 ...
- Node四种动态加载JS代码方法性能对比
背景 我们运行node程序的时候,一般情况下,js代码都是事先写好在js文件里,然后启动的时候加载到内存中执行的.在一些特殊的需求下,我们可能会执行一些动态的js代码. 四种方法 目前我能想到的方法有 ...
- 动态网页常用的两种数据加载方式ajax和js动态请求
欢迎关注"生信修炼手册"! 对于静态网页,我们只需要访问对应的URL就可以获得全部的数据了,动态网页则没有这么简单.比如以下网站 http://q.10jqka.com.cn/zj ...
- Android图片加载之认识bitmap的四种加载方式
Android的Bitmap有四种高效加载方式 从获取方式分: (1)以文件流的方式 假设在sdcard下有 test.png图片 FileInputStream fis = new FileInpu ...
- composition java_阿里P7架构师通过源码浅析Java中的资源加载
一. 前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 二. 什么是类加载器 虚 ...
- Unity资源加载入门
写在前面 本文转载自:https://gameinstitute.qq.com/community/detail/123460,供自己学习用,如有疑问,请移步原创. 引言 Unity的资源加载及管理, ...
最新文章
- linux中-i选项的作用,linux – find中的-prune选项有什么作用?
- git fetch和git pull
- webclient 和 webrequest获取网页源码的
- 某公司有一台打印、复印一体机,需要将购买成本分年均摊到隔年的费用中。请编写一个程序,根据用户输入的购买金额和预计使用年限计算每年的分摊费用。要求对输入异常进行适当的处理。
- putty自动登录设置
- 各种排序(数据结构复习之内部排序算法总结)
- django配置随时执行的脚本,使用运行时的manage环境执行程序
- 人员梯度培养_人员管理 | 生产班组员工队伍管理及制度建立
- 推荐下载使用:功能强大的光盘刻录软件NERO 9.0中文版(最新官方原版+有效序列号)(转)...
- 中文输入纠错任务整理
- Docker(八)Container无法正常启动Restarting (1) Less than a second ago的原因及解决办法
- K-armed Bandit
- Scroller的使用
- 【弄nèng - Zookeeper】Zookeeper入门教程(三)—— 客户端Curator的基本API使用(Curator framework)
- 【顺序表】顺序表的就地逆置
- 手游代理平台怎么挑选?
- 纸板表的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- Unit nginx.service entered failed state(nginx启动失败)
- 03——axios配置对象以及默认配置
- 调程序就恶心,怎么办?
热门文章
- 训练 AI 创作诗歌 6 NLP 从零到英雄 Training an AI to create poetry
- tl-wdr5620千兆版设置虚拟服务器,TL-WDR5620路由器如何设置 TL-WDR5620路由器上网设置步骤【介绍】...
- wsl2 Ubuntu安装Anaconda3
- Git工程区域与文件状态
- Sudoku-Java
- python中List和Tuple的区别
- python压缩算法_Python实现压缩和解压缩ZIP文件的方法分析
- Linux 查找满足条件的文件并复制
- 凸优化第二章凸集 2.2重要例子
- Java编写网络爬虫