mybatis基础流程_SqlSessionFactory的引出
Mybatis源码_SqlSessionFactory的引出
1. SqlSessionFactory的引出,作为Mybatis的入口
a. 直接调用SqlSessionFactoryBuilder.build(参数)方式引出SqlSessionFactory对象,其实在此处已经比较明了的看出了 2种设计模式, 1 : 构建者模式 2. 工厂模式
b. 这里参数 InputStrem是我们常说的 mybatis.Xml ,Mybais的主配置文件. 作为输入流传输进去.
2. XMLConfigBuilder
a .此对象的引出,是为了解析mybtis的主配置文件. 这里继续采用着建造者模式
b. 需要注意的是,mybatis解析XML的方式与Spring一样,都是将其转为Document对象解析的,此处不特殊说明
源码继续,重要看作为参数的 parse.parse()方法
a . 可以看到,此处创建了布尔类型的parsed变量,作为是否已经解析过此配置文件的标志位,只允许解析一次,如果已经解析,直接throw 异常
b. 同时可以看到Mybatis的根节点是<configuraton/>标签,从根节点开始解析
a . 从源码上的 parseConfiguration()方法可以看出, 这里面就是Mybatis的主配置文件,可以配置的所有标签.
b . <environments> 标签内可以配置和数据源,不过现在基本上都是与spring框架联合使用,所以现在已经不需要配置了,交由spring管理.
c . 如果mybatis使用的话,这里比较关键的还有<mappers>标签,因为里面会引出 xxMapper.Xml文件.
源码继续 , 直接查看 this.MapperElement(XXX)
a. 首先比较明显的可以看到, 这里引入mubtis.xml的方式有四种. package resource url class .
b. 也可以说是2大类 , package 和 class为引入 Mapper的接口文件 (XXMapper.java) , 其余两个自然就为根据xml引入(XXMapper.xml)
c. 可以比较明确在截图上看到的是,这里引入了XmlMapperBuilder对象,与XmlConfigBuilder对象差不多,只不过此对象是用来解析 XXMapper.xml的
根据Mapper.xml来完善Configuration对象
a. 同样 ,这句话是告诉我们将要开始解析 Mapper.xml的配置文件 ,一样是使用构建者模式
a . 同样可以看到 Mapper.Xml的根标签是 <mapper/>
b . 根据if里面的内容,得到mybatis这里采用了一个 protected final Set<String> loadedResources; set集合来存储所有已经解析过的Mapper.xml的name. 防止重复解析.
a .根据解析的标签可以看到mapper.xml中允许配置的标签.当然其中最重要的肯定还是 增删改查标签
b. 根据else可以看出, namespace是必不可少的.否则将会抛出异常.
c .resulrtMap 和 resultType 区别在于,当表结构与创建的实体对象属性不一致的时候(一般是属性名不一样),这里可以进行映射.基础数据类型用resultType接收还有 java.lang.string
d. 这里重点看增删改查的处理.
a. 与mybatis一贯作风一样的是, 这里引入了 XmlStatementBuilder对象来 解析这几个标签,解析完成会生成statemeng对象
a. 这里调用了configuration.addMapperStatement(statement)方法 ,
a . 点进去,其实是封装了一个map , key为sql语句的id ,value为mapperStatemnt对象 .
继续回到mapper.Xml解析的parse()方法
a . 第二行代码比较容易理解, 这里是将此配置文件放入到set集合内,防止重复解析
b . 重点是圈里的代码,将mapper与namespace绑定,顾名思义,这里是要将mapper接口与mapper.xml文件绑定了 , 点进去 .
a. 根据mapper.xml的namespace属性,利用反射来得到类的Class对象. (从侧面说明了,mapper.xml的namespace必须为类的全限定名)
b. 这里注意看一下this.configuration.addMapper(boundType) 方法.
a . 点进去发现,调用了MapperRegistry.addMapper(Class<T> type) 方法,注意红圈内的这行代码
b. 出现了第二个map ,key为Class对象,Value为MapperProxyFactory.(Mybatis采用了JDK的动态代理为接口创建代理对象来调用里面的方法,具体可见下面截图)
a . 上面的2张截图可以说明采用的是JDK的动态代理,其中是mapperProxy实现了InvocationHandler.
重点: 截止到目前,根据mybatis的主配置文件 和 Mapper.xml文件,获取到的所有配置信息都要封装到Configuration对象内.
根据Class对象来完善Configuration对象,拿Class来看代码
a . 根据类全限定名,直接反射获取到Class对象, 调用了 this.configuration.addMapper(Class)方法
b . 接下来就是熟悉的代码. knowMappers开始封装元素. key为Class对象.Value为MapperProxyFactory.
c . 但是此处Mapper.Xml尚未加载,那就继续往下看
a . 根据类的名字得到mapper.xml的名字
b . 还记得配置为Mapper.Xml时,Configuration.loadResources()中的set集合,这里就是根据set集合是否存在此Mapper.xml,如果不存在,开始加载. 当然这里肯定不包含 .xml后缀
a . 在这里拼接上了Xml后缀,拿到InputStream后, XmlMapperBuilder对象引出,这里就和根据Mapper.xml引出是一样的了.
总结 : 截止到目前,Configuration对象基本上就封装完了. SqlSessionFactory也根据Configuration参数封装完成了.