深入浅出mybatis之启动详解
深入浅出mybatis之启动详解
MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程。
目录
如何启动MyBatis
我们知道,SqlSessionFactory是MyBatis中最为核心的组件,每个基于MyBatis的应用都是以一个SqlSessionFactory实例为中心的。SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration实例构建出SqlSessionFactory的实例。

1. 从XML配置文件中构建SqlSessionFactory实例
从XML文件中构建SqlSessionFactory实例非常简单,建议使用类路径下的资源文件进行配置。也可以使用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者“file://”形式的URL文件路径来配置。通常,我们使用MyBatis包含一个名叫Resources的工具类,从classpath路径下加载资源文件。
- 从类路径下的xml配置文件中构建SqlSessionFactory
public static void main(String[] args) throws IOException {
// 使用Resources工具从类路径下的xml配置中构建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
- 从字符串形式路径下的xml配置文件中构建SqlSessionFactory
public static void main(String[] args) throws IOException {
// 从文件系统绝对路径下的xml配置文件中构建SqlSessionFactory
FileInputStream is = new FileInputStream("D:/mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
- 从"file://"形式的URL路径xml配置文件中构建SqlSessionFactory
public static void main(String[] args) throws IOException {
// 从URL路径下的xml配置文件中构建SqlSessionFactory
URL url = new URL("file:///D:/mybatis-config.xml");
InputStream is = url.openStream();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
如上所示,我们从指定路径下加载MyBatis的配置文件:mybatis-config.xml。当然,正如前面所说,我们也可以通过Java API的方式通过定制Configuration类实例来构建SqlSessionFactory实例。
2. 通过Java API构建SqlSessionFactory实例
public static void main(String[] args) throws IOException {
// 通过Java API构建SqlSessionFactory
// 数据源
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test_mybatis?characterEncoding=utf8&serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("");
// 事务管理器
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("dev", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
// 注册指定映射器
configuration.addMapper(TestMapper.class);
// 注册映射器类所在包名下的所有映射器
//configuration.addMappers("org.chench.test.mybatis.mapper.impl");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
}
如何使用MyBatis
在构建好SqlSessionFactory实例之后,我们就可以获取SqlSession实例,用于与数据库进行交互。
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession是一个与数据库交互的接口,在MyBatis中存在3个实现类,分别是:DefaultSqlSession,SqlSessionManager和SqlSessionTemplate。

其中,DefaultSqlSession是常用的SqlSession实现,而SqlSessionManager和SqlSessionTemplate都是SqlSession的代理类,用于实现事务提交和回滚。DefaultSqlSession和SqlSessionManager可用于在普通应用中集成MyBatis,而SqlSessionTemplate则用于MyBatis与Spring框架集成。注意:SqlSessionTemplate自己不实现事务回滚,而是交给Spring框架进行处理,我们可以从SqlSessionTemplate的源码中证实这一点:
/**
* {@inheritDoc}
*/
@Override
public void rollback() {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
@Override
public void rollback(boolean force) {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
获取到SqlSession实例之后,就可以执行CRUD操作了。具体来讲,对于不用的映射器配置,使用方式略有不同。
1. 使用xml映射器
所谓的xml映射器是指,将SQL语句及相关ORM映射的配置都写在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="org.chench.test.mybatis.mapper">
<!-- 查询一条数据 -->
<select id="selectOneTest" resultType="org.chench.test.mybatis.model.Test">
select * from test where id = #{id}
</select>
</mapper>
// 从xml映射配置中执行指定id的语句,并传递参数
Test test = sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);
if(logger.isDebugEnabled()) {
logger.debug((test == null) ? "test is NULL!" : test.toString());
}
2. 使用注解映射器
使用注解方式映射SQL语句是指:直接将SQL编写在映射器接口方法的注解中。
// 定义映射器接口
public interface TestMapper {
// 直接将SQL语句以注解的方式编写
@Select("select * from test where id = #{id}")
public Test selectOneTest(long id);
}
// 直接调用映射器接口方法,并传递参数
Test test = sqlSession.getMapper(TestMapper.class).selectOneTest(1);
if(logger.isDebugEnabled()) {
logger.debug((test == null) ? "test is NULL!" : test.toString());
}
如上两种映射器方式分别需要在MyBatis的xml配置文件进行相应的配置,或者在通过Java API方式构建SqlSessionFactory实例时明确进行配置。
mybatis-config.xml:
<mappers>
<!-- xml映射器:将SQL语句写在xml文件中 -->
<mapper resource="org/chench/test/mybatis/mapper/xml/TestMapper.xml" />
<!-- 注解映射器:将SQL语句写在Java代码中, 这里有2种方式: -->
<!-- 方式一: 注册每一个映射器接口,需要明确注册每一个接口 -->
<!-- 方式二: 指定映射器接口所在包,则该包下的所有映射器接口都会被注册 -->
<!-- <mapper class="TestMapper" /> -->
<package name="org.chench.test.mybatis.mapper.impl"/>
</mappers>
注意: 在使用xml配置文件方式构建SqlSessionFactory实例时,既可以配置xml映射器,也可以配置注解映射器;但是直接通过Configuration对象构建SqlSessionFactory实例时,只能配置注解映射器。
// 注册指定注解映射器
configuration.addMapper(TestMapper.class);
// 通过映射器类所在包名批量注册注解映射器
configuration.addMappers("org.chench.test.mybatis.mapper.impl");
差别在于:xml映射器最终会通过XMLConfigBuilder工具类解析为对应的Configuration配置参数。
MyBatis启动过程
SqlSessionFactory既可以通过xml配置文件构建,也可以通过Java API构建,那么它们有什么区别呢?下面,我们来一一剖析一下MyBatis的启动过程。
以从classpath路径下加载配置文件构建SqlSessionFactory实例的方式说起。
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
首先,我们先看一下MyBatis启动的时序图:

从上图我们可以很清晰地看到,在MyBatis的启动过程中涉及到三个非常核心的类,分别是:SqlSessionFactoryBuilder,XMLConfigBuilder和Configuration,我们再来进一步追踪其源码实现。
SqlSessionFactoryBuilder.java:
// 传递配置文件的输入流对象
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
// 通过XMLConfigBuilder工具类解析xml配置
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
// 通过Configuration实例构建SqlSessionFactory对象
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
XMLConfigBuilder.java:
// 调用XMLConfigBuilder工具实例的解析方法,解析xml配置信息,并组装在Configuration实例属性中
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
// 解析MyBatis配置文件,在这里我们可以很清楚的看到MyBatis的配置文件结构
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
通过上述源码阅读我们不难发现,不论以哪种方式(xml配置文件或API)构建SqlSessionFactory实例,最终都是通过Configuration实例构建SqlSessionFactory实例。只不过以xml方式配置时,是一种阅读性更好的方式,但是最终需要通过XMLConfigBuilder工具类对xml配置文件进行解析,然后再构建为一个Configuration实例。
【参考】
[1]. http://www.mybatis.org/mybatis-3/zh/getting-started.html
深入浅出mybatis之启动详解的更多相关文章
- 深入浅出 spring-data-elasticsearch - 基本案例详解(三
『 风云说:能分享自己职位的知识的领导是个好领导. 』运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+, Spring Data Elasticsearch ...
- Mybatis案例超详解(上)
Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...
- mybatis代码生成器配置文件详解
mybatis代码生成器配置文件详解 更多详见 http://generator.sturgeon.mopaas.com/index.html http://generator.sturgeon.mo ...
- MyBatis核心配置文件详解
------------------------siwuxie095 MyBatis 核心配置文件详解 1.核心 ...
- 《深入理解mybatis原理2》 Mybatis初始化机制详解
<深入理解mybatis原理> Mybatis初始化机制详解 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程 ...
- MyBatis Mapper XML 详解
MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...
- Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节
简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...
- Linux 启动详解之init
1.init初探 init是Linux系统操作中不可缺少的程序之一.init进程,它是一个由内核启动的用户级进程,然后由它来启动后面的任务,包括多用户环境,网络等. 内核会在过去曾使用过init的几个 ...
- mybatis 学习笔记 -详解mybatis 及实例demo
快速入门1 要点: 首先明白mybatis 是什么 这是一个持久层的框架.之前叫做ibatis.所以,在它的代码中出现ibatis这个词的时候,不要感到惊讶.不是写错了,它确实就是这个样子的. 首先, ...
随机推荐
- 谈谈当代大学生学习IT技术的必要性。
21世纪,人类社会已经从工业时代全面进入信息化时代,IT技术的发展正在影响人类的日常生活.比如,外卖平台给人们的用餐提供了更多的选择,移动支付颠覆了传统的支付方式.网购使得人们的购物更加方便,真正做到 ...
- (生活)Photoshop入门(不定时更新)
我可能是想找个工作以外的事情做一下. 目标:我要自学网PhotoShop商业修图. 笔记: .图层 .1总结: 1.1.1图层就好像画画的一张纸,但是每一层又互不影响. 1.1.2图层蒙版(覆盖一层玻 ...
- Django REST framework框架介绍和基本使用
Django REST framework介绍 Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API. 官 ...
- 【Linux基础】判断当前机器是虚拟机还是物理机
1.使用dmidecode命令查看(root权限) DMI (Desktop Management Interface, DMI)的主要组成部分是Management InformationForma ...
- Python开发【第四篇】函数
函数的作用 函数可以让编程逻辑结构化以及模块化 无论是C.C++,Java还是Python,函数是必不可少的知识点,也是很重要的知识点,函数是完成一个功能的代码块,使用函数可以使逻辑结构变得更加清晰以 ...
- Building Lambda Architecture with Spark Streaming
The versatility of Apache Spark’s API for both batch/ETL and streaming workloads brings the promise ...
- Java注解开发与应用案例
Java注解开发与应用案例 Annotation(注解)是JDK5.0及以后版本引入的,可以对包.类.属性.方法的描述,给被述对象打上标签,被打上标签后的类.属性.方法将被赋予特殊的“功能”:打个比喻 ...
- JSP七大动作
- 服务端监控工具:Nmon使用方法
在性能测试过程中,对服务端的各项资源使用情况进行监控是很重要的一环.这篇博客,介绍下服务端监控工具:nmon的使用方法... 一.认识nmon 1.简介 nmon是一种在AIX与各种Linux操作系统 ...
- 在SQL Server中如何进行UPDATE TOP .....ORDER BY?
前言 今天在导入数据到系统后需要根据时间排序对刚导入的TOP N条进行数据更新,之前没遇到过UPDATE TOP...ORDER BY,以此作为备忘录. SQL SERVER之UPDATE TOP.. ...