Mybaits 架构原理

使用到的测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void selectAllTest() throws IOException {
// 1. 将配置文件读取成输入流
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");

// 2. 解析配置文件,封装为 Configuration 对象。创建 DefaultSqlSessionFactory 对象返回
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

// 3.1 生产了 DefaultSqlSession 对象,设置了事务不自动提交
// 3.2 生产了 SimpleExecutor(extends BaseExecutor) 执行器,如果开启了缓存就包装成为 CachingExecutor 执行器
SqlSession sqlSession = factory.openSession();

// 4. 根据 statementId 从 Configuration 中获取指定的 MappedStatement,将查询任务委派给 executor(调用 executor 的 query 方法)
List<User> users = sqlSession.selectList("com.example.dao.UserDao.findAll");
for (User user : users) {
System.out.println(user);
}

sqlSession.close();
}

主要构件及其相互关系

构件 描述
SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。
Executor MyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓 存的维护。
StatementHandler 封装了JDBC Statement操作,负责对JDBC statement的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler 负责对用户传递的参数转换成JDBC Statement所需要的参数。
ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。
TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换。
MappedStatement MappedStatement维护了一条<select、update、delete、insert>节点的封装。
SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。
BoundSql 表示动态生成的SQL语句以及相应的参数信息

关系依赖

“${}” 和 “#{}” 的区别

SqlSource 会直接替换 sql 中的 “${}” 这种参数(相当于文本替换,会有 sql 注入的风险)。而 “#{}” 则替换为 “?” 生成 jdbc 可以运行的占位符 sql,同时 “#{}” 中的内容保存到 parameterMappings 中,封装到 BoundSql 对象中返回。

Mybatis 的查询流程

导入源码遇到的问题:

如果引入了 javassist 依赖,但是遇到了 Cannot find class: javassist.util.proxy.ProxyFactory,将引入的依赖的 optional 改成 false。

1
2
3
4
5
6
7
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.28.0-GA</version>
<scope>compile</scope>
<optional>false</optional>
</dependency>

报错 java.lang.NoClassDefFoundError: ognl/PropertyAccessor 也是同样处理

1
2
3
4
5
6
7
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.3.2</version>
<scope>compile</scope>
<optional>false</optional>
</dependency>