使用xml的方式来分析mybatis的源码
一、基本使用
上面的是整个工程的架构:
1、首先创建一个Mybatis的主配置文件,如下:
2、还创建一个数据层的xml的文件,主要指向DAO接口的 3、然后将Mapper.xml文件注册到主的配置文件中 4、然后创建一个Model的模型Demo.java 5、然后创建和数据库打交道的接口DemoDao 首先将数据库连接抽象成一个环境对象,然后数据源就是用户名和密码 将这些的字段抽象出数据源,里面包含了这4个字段。
环境里面包括事务和数据源组合起来,就称之为环境。transactionManager带表的是事务,这里可以配置多环境的,也可以配置单环境的。如果是jdbc的话,这四个属性必须写出来:driver,url,username,password这时一个数据源就创建成功。
6、还需要将和dao打交道的映射文件XXXMapper.xml也注册进来,路径是相对路径 Mapper里面的内容为Dao接口的全路径,namespace的作用 ①、指向Dao的接口,注册生成之后用来创建接口的代理用的。
②、指向是哪个模块下的增删改查的。
③、创建1,2级缓存用的运行的结果如下:
分析下上面的结果该怎么产生的呢?
上面是从全局角度来看:xml文件被加载到mybatis,然后由mybatis给返回结果
也是资源set阶段,然后资源get的阶段,最后返回出自定义的结果。其他的orm框架返回的结果不可以自定义,这个返回的结果就可以自定义。
mybatis帮我们产生出数据,这个就是根,如何从xml文件获取到根对象的呢?上面的自定义的对象分为:
1、默认的实体:Model 2、集合类型 3、map 4、pojo 分析下怎么使用的暴漏出一些的api:
1、首先通过字符输入流获取mybatis的全局配置文件, 2、然后通过建造者设计模式构建出SqlSessionFactory对象,这个对象是给外部调用的接口 3、然后通过SqlSessionFactory打开SqlSession对象 4、然后通过SqlSession创建出DemoDao接口的代理类,把DemoDao接口的全路径作为key传进来,就获得代理类,这就是映射的。
5、然后调用普通自定义的方法 6、执行结果 7、返回结果 如果用spring和mybatis整合的时候,它会把1,2,3,4,5,6个步骤都给做了,然后动态去创建代理类,然后将代理类注册到IOC容器,然后进行依赖注入,所以就可以调用方法去了。这就是集成Spring的方式。
二、整体运行流程
mybatis的整体运行流程总共分为8个阶段, 1、配置资源的加载阶段:封装成一个字节输入流,一个字符输入流 2、通过SqlSessionFactoryBuilder接口来加载主配置资源,主配置资源是mybatis-config.xml,由于Java只认识对象,不认识xml,需要把xml文件转成类文件,将主配置文件抽象出Configuration对象,这个对象是由XMlConfigBuilder通过建造者设计模式来创建出Configuration对象。
3、XMLMapperBuilder这个对象用来解析子配置文件的,就是Mapper配置资源的解析阶段然后由XMLStatementBuilder对象构建出MapperStatement对象凡是框架里面的对象都是对资源文件里面的抽象,MapperStatement就是对mapper文件里面的增删改查的抽象。在mybatis中,把建造者模式用的最好的框架,基本上构建对象都是建造者设计模式4、MapperRegistry:用来注册dao,这个是核心。然后MapperProxyFactory来创建dao代理对象。前面四个阶段可以配置资源,收集阶段 5、所有的资源都放到了Configuration对象里面,通过SqlSessionFactory创建SqlSession对象。
6、通过Executor内部的执行器来将sql进行参数解析,执行sql语句 7、通过ResultSetHandler接口来处理映射的结果,通过ObjectWrapper来处理数据库的字段和返回字段的映射处理。最核心的本质是通过反射, ①、我们定义的是java实体类,而且实体类必须有set方法 从数据库将字段取出来,取出来有一个集合,根据这个集合取出每一个字段,然后在xml文件中配置的结果类型,通过字段去找model类型所对应的字段,是否存在,如果不存在就不进行映射,如果找到的话,将数据库中字段的值通过反射和字段的set方法将字段进行设置值。反射将所有的实体类当作资源。
②、如果是集合的话,没有指明类型的话,通过map方式,map不是通过反射,而是通过put方法,也需要将字段找出来,将数据库中的字段作为键和值传到map里面就可以了。这两个过程就称之为映射。参数和动态代理的时候也用到反射了 8、ResultHandler将结果处理的对象返回:集合,map,pojo 上一步只是映射单个对象,如果要返回多个对象的话,这时就要进行结果处理。默认的是list集合。
三、说下 #与$的区别:
#{}:代替参数用的,就是传进来的参数,来用这个变量进行标识,然后去动态的解析。在解析的时候就是一个?,对sql进行校验,先将sql预编译然后再传参数的方式来操作。比如对下面,如何去取字段,所以用#变量代替参数变量。
由于sql是有攻击的,传过来参数进来,需要进行校验。
功能:1、取出参数的 2、根据参数来排除sql注入
${}:不会预编译而是直接参数的值将值赋给变量,也可以防止sql注入。与Hibernate的区别:Hibernate :全是面向对象的思想实现,mybatis:映射的思维,映射结果就i行了
四、内部结构的核心api介绍:抽象出来的
1、Configuration:主配置对象:把整个主配置文件解析成Configuration对象 子标签就是Configuration的属性 2、MapperStatement:增删改查的标签声明抽象 XmlStatementBuilder对象创建出MapperStatement对象也是建造者的设计模式 3、MapperProxyFactory:创建Dao的代理 MapperProxyFactory:这个对象是如何去注册的呢?通过MapperRegistory 注册Dao. 上面的三个步骤是资源的收集阶段 4、Executor:执行SQL语句:委托下面的一些类去执行
4.1ResultSetHandler:处理sql结果的,对ResultSet的抽象 4.1.1ObjectWrapper:映射sql语句映射到model的实体类 这个是对对象的包装,定义的对象有可能是Map,还有可能是Model 对resultType的map/list/hash/mode/collections的包装
4.2 ResultHandler:将映射的结果处理成为集合对象(结果集)
明天继续分析上面的对象该怎么来的,以及分析Mybatis的插件,和一二级缓存。