一、概述
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
二、MyBatis的优缺点
优点:
- MyBatis是最简单的持久化框架,小巧并且简单易学;
- MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用;
- 提供XML标签,支持编写动态SQL语句;
- 提供映射标签,支持对象与数据库的ORM字段关系映射;
- 与JDBC相比,减少了50%以上的代码量。(对JDBC进行了封装);
缺点:
- 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此;
- SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库;
三、MyBatis功能架构
Mybatis的功能架构分为三层:
- API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
- 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
- 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
MyBatis层次架构图:
四、MyBatis工作原理
先来看看下面这个图
工作原理解析:
- 加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项;
- SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession;
- SqlSession对象完成和数据库的交互;
- 用户程序调用mybatis接口层api(即Mapper接口中的方法);
- SqlSession通过调用api的Statement ID找到对应的MappedStatement对象;
- 通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象;
- JDBC执行 SQL;
- 借助 MappedStatement 中的结果映射关系,将返回结果转化成 HashMap、JavaBean 等存储结构并返回;
五、详细流程
- MyBatis 应用程序通过 SqlSessionFactoryBuilder 从 mybatis-config.xml 配置文件中构建出 SqlSessionFactory(SqlSessionFactory是线程安全的);
- SqlSessionFactory的实例直接开启一个SqlSession,再通过 SqlSession 实例获得 Mapper 对象并运行 Mapper 映射的 SQL 语句,完成对数据库的 CRUD 和事务提交;
- 关闭SqlSession;
下面这段代码能够帮大家进一步理解这个流程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class MyBatisTest { public static void main(String[] args) { // 指定全局配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = null; SqlSessionFactory sqlSessionFactory = null; SqlSession sqlSession = null; try { // 读取配置文件 inputStream = Resources.getResourceAsStream(resource); // 构建sqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 获取sqlSession sqlSession = sqlSessionFactory.openSession(); /** * 执行SQL语句 * 第一个参数:接口全路径 + 方法名,对应mapper映射文件中的namespace和标签的id * 第二个参数:指定传入sql的参数:这里是用户id */ String str = sqlSession.selectOne("com.jack.course.mybatis.dao.UserDao.findNameById",1); System.out.println(str); }catch (IOException ie) { ie.printStackTrace(); }finally { if (null != sqlSession) { sqlSession.close(); } } } }
六、mybatis-config.xml 全局配置文件
先来看一个标准的配置,如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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> <!-- 引入数据库连接配置文件 --> <properties resource="db.properties"></properties> <!-- 环境,可以配置多个,default:指定采用哪个环境 --> <environments default="test"> <!-- id:唯一标识 --> <environment id="test"> <!-- 事务管理器,JDBC类型的事务管理器 --> <transactionManager type="JDBC"></transactionManager> <!-- 数据源,池类型的数据源 --> <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> <environment id="dev"> <!-- 事务管理器,JDBC类型的事务管理器 --> <transactionManager type="JDBC"></transactionManager> <!-- 数据源,池类型的数据源 --> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${usname}"/> <property name="password" value="${passwd}"/> </dataSource> </environment> </environments> <!-- 映射的mapper文件,SQL语句写在这类文件中 --> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration>
properties标签
- 主要作用就是引入外部的properties是文件,一般是数据库的连接配置;
environments标签
- 数据库的连接配置在该标签内,可以配置多套;
- 使用 default 来指明使用哪套环境,对应下面具体环境的 id;
mapper标签
- 指明 mapper 映射文件,具体的 SQL 语句在该文件中编写;
七、mapper.xml 映射文件
1