mybatis 学习

目录

介绍mybatis
mybatis入门
从配置文件入手了解怎么使用mybatis
mapper 接口没有实现类,是怎么执行数据库操作的,原理是什么
sqlsession 内部实现的原理
阅读源码的主要几个重要类

mybatis是啥

MyBatis 世界上流行最广泛的SQL 映射框架,由 Clinton Begin 在 2002年创建,其后,捐献给了Apache 基金会,成立了iBatis 项目。
2010年 5月,将代码库迁致 Google Code,并更名为MyBatis。
关于以前的版本,请访问
关于更名后最新的版本,请访问:

MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的 JDBC 代码、手工设置参数和结果集重获。
MyBatis 只使用简单的 XML 和注解来配置和映射基本数据类型、 Map 接口和 POJO 到数据库记录

mybatis入门

官方文档

使用简介

每一个 MyBatis 应该都是以一个 SqlSessionFactory实例为中心。
一个SqlSessionFactory实例可以使用 SqlSessionFactoryBuilder 来创造。从配置类中创造的定制 SqlSessionFactoryBuilder 实例,
可以使用XML 配置文件来生成一个SqlSessionFactory实例
SqlSessionFactoryBuilder通过Java io流读取配置文件构建 SqlSessionFactory对象
ResourcesA class to simplify access to resources through the classloader.

1
2
3
String resource = "org/mybatis/example/Configuration.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(reader);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers></configuration>

SqlSessionFactory:

1
2
3
4
5
6
7
8
9
10
11
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean var1);
SqlSession openSession(Connection var1);
SqlSession openSession(TransactionIsolationLevel var1);
SqlSession openSession(ExecutorType var1);
SqlSession openSession(ExecutorType var1, boolean var2);
SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
SqlSession openSession(ExecutorType var1, Connection var2);
Configuration getConfiguration();
}

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳范围是方法范围
(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的
XML 解析资源开放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessionFactory
的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory
的最佳范围是应用范围。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的范围是请求或方法范围。
绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理范围中,
比如 Serlvet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的范围中。换句话说,
每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,
你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

下面的示例就是一个确保 SqlSession 关闭的标准模式:

1
2
3
4
5
6
7
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
}
finally {
session.close();
}

在你的所有的代码中一致性地使用这种模式来保证所有数据库资源都能被正确地关闭。

从配置文件入手了解怎么使用mybatis

主要分为 xml 配置文件和xml 映射文件,官方文档写的很详细不做赘述。

mapper 接口没有实现类,是怎么执行数据库操作的,原理是什么??

1
2
3
4
5
6
7
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
mapper.insert(Blog blog);
} finally {
session.close();
}

mybatis mapper 执行原理图(画的不好不要怪我,捂脸.jpg):


详细怎么使用动态代理来实现可以参考 Mybatis3.3.x技术内幕(二):动态代理之投鞭断流(自动映射器Mapper的底层实现原理)

sqlseesion 的实现原理

上面讲到了由mapper 接口执行方法,到sqlsession的api 的调用,下面简单的介绍一下sqlseesion 的实现原理:

sqlsession中有confirguration(配置文件信息)

配置文件的读取XML 的解析封装占了mybatis 源码的很多篇幅。简单来说就是mybatis 从xml中取得的信息全部封装在Confirguration类中,很多类都冗余了confirguration 字段。

根据configuration 调用executor

在xml 里有个defaultExecutorType是配置Excutor 的类别的

executor(有五种)

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。(可以是Statement或PrepareStatement对象)
ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。(可以是Statement或PrepareStatement对象)
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理的;BatchExecutor相当于维护了多个桶,每个桶里都装了很多属于自己的SQL,就像苹果蓝里装了很多苹果,番茄蓝里装了很多番茄,最后,再统一倒进仓库。(可以是Statement或PrepareStatement对象)
CachingExecutor:装饰设计模式典范,先从缓存中获取查询结果,存在就返回,不存在,再委托给Executor delegate去数据库取,delegate可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor。
ClosedExecutor:毫无用处,读者可自行查看其源码,仅作为一种标识,和Serializable标记接口作用相当。

Excutor内部调用statementhadler (对jdbc 的stement操作的封装)

并且用resultSethandler 封装返回结果。

阅读源码的主要几个重要类

  • 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维护了一条节点的封装,
  • SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
  • BoundSql 表示动态生成的SQL语句以及相应的参数信息
  • Configuration MyBatis所有的配置信息都维持在Configuration对象之中。
叔叔,阿姨给点钱买棒棒糖吃