一、简介:
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
- iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
- MyBatis的前身就是iBatis,iBatis本是由ClintonBegin开发,后来捐给Apache基金会,成立了iBatis开源项目。2010年5月该项目由Apahce基金会迁移到了GoogleCode,并且改名为MyBatis。尽管如此,它的包结构仍然为ibatis。
- 访问网站
- MyBatis是一个数据持久层(ORM)框架。把实体类和SQL语句之间建立了映射关系,是一种半自动化的ORM实现。
- 所有sql语句,全部定义在xml(建议)中。也可以通过注解的方式在接口上实现。这些映射文件称之为mapper。
二、MyBatis的优点(与其他架构区别)
- MyBatis的优点:
- 基于SQL语法,简单易学。
- 能了解底层组装过程。
- SQL语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度。
- 程序调试方便。
- 与传统JDBC的比较
-
减少了61%的代码量
-
最简单的持久化框架
-
架构级性能增强
-
SQL代码从程序代码中彻底分离,可重用
-
增强了项目中的分工
-
增强了移植性
-
- 与Hibernate的对比
- Mybatis 在XML文件中配置SQL语句,实现了SQL语句和代码的分离,给程序的维护带来了很大便利
MyBatis |
Hibernate |
是一个SQL语句映射的框架(工具) | 主流的ORM(对象关系映射)框架、提供了从POJO到数据库表的全套映射机制 |
注重POJO/Map与SQL之间的映射关系。不会为程序员在运行期自动生成SQL | 会自动生成全套SQL语句。 |
自动化程度低、手工映射SQL,灵活程度高 | 因为自动化程度高、映射配置复杂,api也相对复杂,灵活性低. |
需要开发人员熟炼掌据SQL语句 | 开发人同不必关注SQL底层语句开发 |
三、Mybatis 体系结构
1.功能架构讲解:
我们把Mybatis的功能架构分为三层:
- API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
- 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
- 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
2.框架架构讲解:
-
加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个mybatis结构个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
-
SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
-
SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
-
结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
四、Mybatis 工作原理
5.配置文件与约束
其中mapper.xml 为
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper>
6
7 </mapper>
mybatis.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
3 "http://mybatis.org/dtd/mybatis-3-config.dtd">
4 <configuration>
5
6 </configuration>
这些都可以在下载的mybatis 文件夹中的pdf找到
6.MyBatis基本要素
1).基础配置文件 mybatis.xml
- configuration.xml是系统的核心配置文件,包含数据源和事务管理器等设置和属性信息,XML文档结构如下
-
configuration配置 properties可以配置在Java属性配置文件中 settings修改MyBatis在运行时的行为方式,如是否需要缓存 typeAliases 为Java类型命名一个短的名字 typeHandlers类型处理器-系统默认已经为所有类型设置OK objectFactory对象工厂–创建Bean。 plugins插件 - 拦截CRUD操作。 environments环境 -配置数据源 environment 环境变量 transactionManager事务管理器 JDBC|JNDI|JTA dataSource数据源 mappersl 映射器 XML文件|Mapper类|网络资源
-
配置环境
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
3 "http://mybatis.org/dtd/mybatis-3-config.dtd">
4 <configuration>
5 <!-- 配置运行环境 Ctrl Shift / -->
6 <environments default="mysqlEM">
7 <environment id="mysqlEM">
8 <transactionManager type="JDBC" />
9 <dataSource type="POOLED">
10 <!-- 使用的是数据库连接池 JDBC也是一种数据源 -->
11 <!-- driver url username password -->
12 <property name="driver" value="com.mysql.jdbc.Driver" />
13 <!-- jdbc:mysql:/// 就是127.0.0.1:3306 -->
14 <property name="url" value="jdbc:mysql://127.0.0.1:3306/test17182" />
15 <property name="username" value="root" />
16 <property name="password" value="123456" />
17 </dataSource>
18 </environment>
19 <environment id="testEM">
20 <transactionManager type="JDBC" />
21 <dataSource type="POOLED">
22 <!-- 使用的是数据库连接池 JDBC也是一种数据源 -->
23 <!-- driver url username password -->
24 <property name="driver" value="com.mysql.jdbc.Driver" />
25 <!-- jdbc:mysql:/// 就是127.0.0.1:3306 -->
26 <property name="url" value="jdbc:mysql://127.0.0.1:3306/test17182" />
27 <property name="username" value="root" />
28 <property name="password" value="123456" />
29 </dataSource>
30 </environment>
31 </environments>
32
33 </configuration>
- 基础配置文件—事务管理
MyBatis有两种事务管理类型:
JDBC- 这个类型直接全部使用JDBC的提交和回滚功能。它依靠使用连接的数据源来管理事务的作用域。
MANAGED- 这个类型什么不做, 它从不提交 、 回滚和关闭连接 。 而是让窗口来管理事务的全部生命周期 。(比如说 Spring或者JAVAEE服务器)
- 基础配置文件—数据源
数据源类型有三种:UNPOOLED,POOLED,JNDI。
UNPOOLED- 这个数据源实现只是在每次请求的时候简单的打开和关闭一个连接。虽然这有点慢,但作为一些不需要性能和立即响应的简单应用来说, 不失为一种好选择 。
POOLED- 这个数据源缓存JDBC连接对象用于避免每次都要连接和生成连接实例而需要的验证时间。对于并发WEB应用,这种方式非常流行因为它有最快的响应时间。
JNDI- 这个数据源实现是为了准备和Spring或应用服务一起使用,可以在外部也可以在内部配置这个数据源,然后在JNDI上下文中引用它。这个数据源配置只需要两上属性:
- 基础配置文件—SQL映射文件
SQL映射文件:
使用相对路径(还有全路径等)
<!-- 注册映射文件 mapper resource/url/class package name=""--> <mappers> <mapper resource="com/ryanxu/dao/mapper.xml" /> </mappers>
- 一些别的要点
<=1 至多一个 且按顺序
必须要有俩 且有先后顺序
>=0
2).SQL映射文件 mapper.xml
- SQL映射文件结构:(有关文件的增删改查结构将用代码来演示)
cache- 配置给定命名空间的缓存。
cache-ref– 从其他命名空间引用缓存配置。
resultMap – 最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载对象。l
sql– 可以重用的SQL块,也可以被其他语句引用。
insert– 映射插入语句
update– 映射更新语句
delete– 映射删除语句
select– 映射查询语句
- 动态SQL
MyBatis的一个强大的特性之一通常是它的动态SQL能力ifchoose(when,otherwise)trim(where,set)foreach
7.核心类的生命周期
- SqlSessionFactoryBuilder的生命周期:这个类可以被初始 、 使用和丢弃 , 如果你已经创建好了一个SqlSessionFactory后就不用再保留它。 因此 ,SqlSessionFactoryBuilder的最好作用域是方法体内,比如说定义一个方法变量。你可以重复使用SqlSessionFactoryBuilder生成多个SqlSessionFactory实例, 但是最好不要强行保留 , 因为 XML 的解析资源要用来做其它更重要的事
- SqlSession 每个线程都有自己的SqlSession实例,SqlSession实例是不能被共享,也是不是线程安全的。因此最好使用Request作用域或者方法体作用域。不要使用类的静态变量来引用一个SqlSession实例,甚至不要使用类的一个实例变更来引用。如果你正在使用WEB框架,应该让SqlSession跟随HTTP请求的相似作用域。也就是说,在收到一个HTTP请求过后,打开SqlSession,等返回一个回应以后,立马关掉这个SqlSession。关闭SqlSession是非常重要的。你必须要确保SqlSession在finally方法体中正常关闭。
- SqlSession 的获取:
1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.sql.Connection;
4 import java.sql.SQLException;
5
6 import org.apache.ibatis.io.Resources;
7 import org.apache.ibatis.session.SqlSession;
8 import org.apache.ibatis.session.SqlSessionFactory;
9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
10
11 public class SqlSessionUtil {
12 private static SqlSessionFactory ssf;// 底层对应的是Connection连接池
13 static {
14 InputStream in;
15 try {
16 in = Resources.getResourceAsStream("mybatis-config.xml");// 从classpath位置加载文件,可以使用相对路径如:cn/hncu/mybatis-config.xml
17 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
18 ssf=ssfb.build(in);
19 } catch (IOException e) {
20 e.printStackTrace();
21 }
22 }
23
24 public static SqlSessionFactory getSsf() {
25 return ssf;
26 }
27
28 public static SqlSession getSqlSession() {
29 return ssf.openSession();
30 }
31
32 public static void main(String[] args) throws SQLException {
33 //SqlSession是Connection的包装类
34 //每次获取的是不同的SqlSession对象,如果获取一个session对象且从中访问con,则就会到池中去拿一个连接。由于我们在配置文件中设置池大小只有5,因此只有前5个session对象能够顺利取出con对象,第6个session在获取con时会阻塞。
35 //一个session对象在获取con之后如果不使用,那么超过默认时间,它所持有的con连接会被收回池中。这样其它session对象又可以从池中获取
36
37 System.out.println("ssf:"+ssf);
38 //下面这段代码,在5个session获取连接之后会阻塞。过一段时间后,才继续执行6-10个session对象
39 for(int i=1;i<=10;i++){
40 SqlSession ss=getSqlSession();
41 System.out.println(i+":sqlSession:"+ss);//sqlSession不同
42 Connection con=ss.getConnection();
43 System.out.println(i+":con:"+con);//Connection相同
44 ss.close();//session对象关闭之后,它所持有的con会还回池中,被下一个session重新持有
45 }
46 }
47 }
-
SqlSession接口主要方法
新增:
int insert(String statement, Object parameter)
修改:
int update(String statement, Object parameter)
删除:
int delete(String statement, Object parameter)
查询:
List selectList(String statement, Object parameter)