Mybatis 内部执行原理概述
# 40.Mybatis内部执行原理概述
Mybatis内部原理:代理对象+execute方法
Mybatis 在使用代理dao的方式实现增删改查时做什么事呢?只有两件事:
- 第一:创建代理对象
- 第二:在代理对象中调用selectList方法
虽然只有两件事,但如果要讲解每个类的作用,还是得花点功夫的,本文就是简单讲解下这两件事 更多关于代理对象的说明,其实我们在讲解Servlet的时候已经讲解过了
# 分析
执行的流程大致如下:
读取配置文件:用到的技术就是解析XML的技术。Mybatis用的是 dom4j 解析 XML 技术,读取了数据库连接信息,mapper映射信息,以及具体的要执行的SQL的信息。
根据配置文件的信息创建Connection对象:注册驱动,获取连接
获取预处理对象PreparedSatement,此时需要SQL语句:
conn.prepareStatement(sql);
执行查询:
ResultSet resultSet = preparedStatement.executeQuery();
遍历结果集用于封装List并返回,伪代码如下:
List<E> list = new ArrayList(); while( resultSet.next() ){ E element = (E) Class.forName(配置里的全限定类名).newlnstance() /* 进行封装,把每个rs的内容都添加到element中,实体类属性和表中的列名是一致的。 此处使用反射封装,于是我们就可以把表的列名看成是实体类的属性名称。 就可以使用反射的方式来根据名称获取每个属性,并把值赋进去。 */ //把elementa入到list中 list.add(element); } return list;
1
2
3
4
5
6
7
8
9
10
11
12
13
要想让上述的步骤成功执行,我们需要给封装的方法提供两个信息:
第一个:连接信息
第二个:映射信息。包含了两部分
- 第一:执行的SQL语句
- 第二:封装结果的实体类全限定类名。这两个信息组合成一个对象,假设该对象为Mapper
然后Mybatis 可以根据 id 来获得该mapper对象,然后执行封装的方法。可以理解为是一个定义了一个map:
Map<String, Mapper> map
其中String就是全限定类名 + 方法名的字符串,通过这个key可以获取到mapper对象,mapper对象里存储了SQL语句,以及映射的实体类类名。
接下来,就是创建代理对象了
IUserDao userDao = session.getMapper(IUserDao.class);
而getMapper方法内部,也是通过动态代理来创建对象的,伪代码如下:
public <T> getMappser(Class <T> daoInterfaceClass){
Proxy.newProxyInstance(类加载器, 代理对象要实现的接口字节码数组, 增强的逻辑)
}
2
3
newProxyInstance方法的参数分析:
- 类加载器:使用的是和被代理对象相同的类加载器
- 代理对象实现的接口:和被代理对象实现相同的接口
- 增强的逻辑:就是要增强的方法,该参数是一个InvocationHandler的接口,需要写一个实现类,在实现类里调用了selectList方法
更多关于代理对象的说明,其实我们在讲解Servlet的时候已经讲解过了: JavaWeb-Filter案例 (opens new window),这里不再详细说明