Mybatis简略工作原理。本文建立在Spring+SpringMVC+Mybatis整合的项目之上。
我将其工作原理分为六个部分:
- 读取核心配置文件mybatis-config.xml并返回InputStream流对象。
- 根据InputStream流对象解析出Configuration对象,然后创建SqlSessionFactory工厂对象。
- 根据一系列属性从SqlSessionFactory工厂中创建SqlSession。
- 从SqlSession中调用Executor执行数据库操作&&通过解析生成具体SQL指令。
- 通过TypeHandler(数据库与java类型转换)对执行结果进行二次封装。
- 提交与事务处理。
具体结合代码看:
/**
1. 人实体
*/
public class People {
private String name;// 姓名
private String sex;// 性别
private int phone;// 手机号
getter and setter ...
}
1. 读取核心配置文件
1.1配置文件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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://xxx.xxx:3306/ssm" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="PeopleMapper.xml"/>
</mappers>
</configuration>
当然,还有很多可以在XML 文件中进行配置,上面的示例指出的则是最关键的部分。要注意 XML 头部的声明,用来验证 XML 文档正确性。environment 元素体中包含了事务管理和连接池的配置。mappers 元素则是包含一组 mapper 映射器(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息)。
1.2 PeopleMapper.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="Book">
<!-- 目的:为dao接口方法提供sql语句配置 -->
<insert id="insert" >
insert into user (name,phone,sex) values (#{name},#{number},#{sex})
</insert>
</mapper>
就是一个普通的mapper.xml文件。
1.3 Main方法
从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。但是也可以使用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者 file:// 的 URL 形式的文件路径来配置。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,可使从 classpath 或其他位置加载资源文件更加容易。
public class Main {
public static void main(String[] args) throws IOException {
// 创建一个book对象
Book book = new Book();
book.setBookId(1006);
book.setName("Easy Coding");
book.setNumber(110);
// 加载配置文件 并构建SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 从SqlSessionFactory对象中获取 SqlSession对象
SqlSession sqlSession = factory.openSession();
// 执行操作
sqlSession.insert("insert", book);
// 提交操作
sqlSession.commit();
// 关闭SqlSession
sqlSession.close();
}
}
这个代码是根据Mybatis官方提供的一个不使用 XML 构建 SqlSessionFactory
的一个Demo改编的。
注意:是官方给的一个不使用 XML 构建 SqlSessionFactory
的例子,那么我们就从这个例子中查找入口来分析。
2. 根据配置文件生成SqlSessionFactory工厂对象
2.1 Resources.getResourceAsStream(resource);源码分析
```Resources```是mybatis提供的一个加载资源文件的工具类。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190320214600530.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDczOTM0OQ==,size_16,color_FFFFFF,t_70)
我们只看getResourceAsStream方法:
public static InputStream getResourceAsStream(String resource) throws IOException {
return getResourceAsStream((ClassLoader)null, resource);
}
getResourceAsStream调用下面的方法:
public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
if (in == null) {
throw new IOException("Could not find resource " + resource);
} else {
return in;
}
}
获取到自身的ClassLoader对象,然后交给ClassLoader(lang包下的)来加载:
InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
ClassLoader[] arr$ = classLoader;
int len$ = classLoader.length;
for(int i$ = 0; i$ < len$; ++i$) {
ClassLoader cl = arr$[i$];
if (null != cl) {
InputStream returnValue = cl.getResourceAsStream(resource);
if (null == returnValue) {
returnValue = cl.getResourceAsStream("/" + resource);
}
if (null != returnValue) {
return returnValue;
}
}
}
值的注意的是,它返回了一个InputStream
对象。