文档章节

Mybatis源码分析-读取非项目中的xml文件

傲娇字符
 傲娇字符
发布于 2018/05/17 17:24
字数 611
阅读 44
收藏 0

mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--通过这个配置文件,完成mybatis与数据库的连接  -->
<configuration>
    <environments default="development">
        <environment id="development">
            <!-- 配置事务管理 ,采用JDBC管理事务-->
            <transactionManager type="JDBC"/>
            <!-- POOLED是mybatis的 数据源 -->
            <!-- JNDI是基于tomcat的数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/demo"/>
                <property name="username" value="demo"/>
                <property name="password" value="demo"/>
            </dataSource>
        </environment>
    </environments>
    <!-- pojo的映射文件UserMapper引入到配入到配置文件中 -->
    <mappers>
        <!-- resource要写成路径 -->
        <mapper resource="/mybatis/mapper/demo.xml"/><!-- 项目中的xml文件 -->
        <mapper url="file:///D:/tmp/mybatis/mybatis/mapper/demo.xml"/><!-- 本地磁盘的xml文件 -->
        <mapper url="http://www.gongstring.com/mybatis/demo.xml"/><!-- 远程URL的xml文件 -->
    </mappers>

</configuration>

demo.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="demo" >

    <select id="findByPatientNo" resultType="java.util.Map">
        select * from base_patient where s_code = #{sCode} 
		<if test="patientNo != null">
		and d_code = #{patientNo}
		</if>
    </select>

</mapper>

java调用代码


        Map<String,Object> params = new HashMap<>();
        params.put("sCode","system");
//            params.put("patientNo","111");

        String resource = "D:\\tmp\\mybatis\\mybatis\\mybatis-config.xml";
        try (InputStream inputStream = new FileInputStream(resource)){
            Configuration configuration = new Configuration();
            
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(inputStream);
            datas = factory.openSession().selectList("demo.findBySql",params);
            System.out.println(JSON.toJSONString(datas));

        }catch (Exception e){
            e.printStackTrace();
        }

源码分析

在Mybatis的SqlSessionFactory启动时,会先读取mybatis-config.xml配置文件进行初始化。mappers标签里面配置的xml文件,在XMLConfigBuilder.parseConfiguration(XNode root)方法中进行加载,而mybatis底层提供了几种xml加载方式,支持项目中的xml读取,以及URL的方式。

private void parseConfiguration(XNode root) {
    try {
      propertiesElement(root.evalNode("properties")); //issue #117 read properties first
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      settingsElement(root.evalNode("settings"));
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers")); //加载Mappers中的配置文件
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

mapperElement方法:

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);
            InputStream inputStream = Resources.getResourceAsStream(resource);///////////// 读取本地类路径下面的xml
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            InputStream inputStream = Resources.getUrlAsStream(url);///////////// 读取URL资源中的xml
            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.");
          }
        }
      }
    }
  }

Resources.getUrlAsStream(url)方法:

public static InputStream getUrlAsStream(String urlString) throws IOException {
    URL url = new URL(urlString); ////// 说明支持多种文件读取方式
    URLConnection conn = url.openConnection();
    return conn.getInputStream();
  }

© 著作权归作者所有

共有 人打赏支持
傲娇字符
粉丝 6
博文 43
码字总数 17111
作品 0
武汉
架构师
私信 提问
自己手写一个Mybatis框架(简化)

继上一篇手写SpringMVC之后,我最近趁热打铁,研究了一下Mybatis。MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出来可扩展,高内聚,低耦合的规范的代码。本文完...

我叫刘半仙
2018/03/07
0
3
mybatis源码分析之Configuration

上一篇mybatis之SqlSessionFactory http://my.oschina.net/u/657390/blog/653637 上一篇对mybatis中SqlSessionFactory的创建过程进行了分析,从之前的分析可以看出创建过程中比较重要的一部分...

udbwcso
2016/04/18
2.9K
6
mybatis源码解读(二)——构建Configuration对象

  Configuration 对象保存了所有mybatis的配置信息,主要包括:   ①、 mybatis-configuration.xml 基础配置文件   ②、 mapper.xml 映射器配置文件 1、读取配置文件   前面例子有这...

ysocean
2018/05/07
0
0
MyBatis 源码分析——介绍

笔者第一次接触跟MyBatis框架是在2009年未的时候。不过那个时候的他并不叫MyBatis,而是叫IBatis。2010年的时候改为现在的名字——MyBatis。这几年过去了,对于笔者来讲有一点陌生了。而且那...

Java小铺
2018/08/10
0
0
手写spring+springmvc+mybatis框架篇

我们平日开发时所用的SSM框架,可是你真的了解它吗?技术革新,换代应接不暇,只有理解了源码才能保证在技术快速更迭的时代中真正站稳脚跟。 本系列文章抽丝剥茧,源码分析百度有很多,在这里...

技术小能手
2018/07/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 风扇写着先生请自爱

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @蚂蚁哈哈哈 :分享陈奕迅的单曲《落花流水》 《落花流水》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @车谷 :我发现每天上班都好困 ...

小小编辑
今天
37
5
centos7重置密码、单用户模式、救援模式、ls命令、chmod命令

在工作当中如果我们错误的配置了文件使服务器不能正常启动或者忘记密码不能登录系统,如何解决这些问题呢?重装系统是可以实现的,但是往往不能轻易重装系统的,下面用忘记密码作为例子讲解如...

李超小牛子
今天
3
0
Python如何开发桌面应用程序?Python基础教程,第十三讲,图形界面

当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?行业内专业的桌面应用程序开发一般是C++,C#来做,Java开发的也有,但是比较少。本节课会介绍Python的GUI(图形用...

程序员补给栈
今天
9
0
kafka在的使用

一、基本概念 介绍 Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统...

狼王黄师傅
今天
3
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部