MyBatis 执行原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HrSkp5Zv-1619069868981)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1602741526732.png)]
(1)读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接。
(2)加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。
(3)构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。
(4)创建 SqlSession 对象。由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL的所有方法。
(5)MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
(6)在 Executor 接口的执行方法中,包含一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等。Mapper.xml文件中一个SQL对应一个MappedStatement对象,SQL的id即是MappedStatement的id。
(7)输入参数映射。在执行方法时,MappedStatement 对象会对用户执行 SQL 语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型),Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。
(8)输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型),Executor执行器会通过MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。
二,执行过程中比较重要的类
- Configuration:用于描述MyBatis主配置文件信息,MyBatis框架在启动时会加载主配置文件,将配置信息转换为Configuration对象。
- SqlSession:面向用户的API,是MyBatis与数据库交互的接口。
- Executor:SQL执行器,用于和数据库交互。SqlSession可以理解为Executor组件的外观,真正执行SQL的是Executor组件。
- MappedStatement:用于描述SQL配置信息,MyBatis框架启动时,XML文件或者注解配置的SQL信息会被转换为MappedStatement对象注册到Configuration组件中。
- StatementHandler:封装了对JDBC中Statement对象的操作,包括为Statement参数占位符设置值,通过Statement对象执行SQL语句。
- TypeHandler:类型处理器,用于Java类型与JDBC类型之间的转换。
- ParameterHandler:用于处理SQL中的参数占位符,为参数占位符设置值。
- ResultSetHandler:封装了对ResultSet对象的处理逻辑,将结果集转换为Java实体对象。
三、创建工具类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bCaWsmtr-1619069868984)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1602752378269.png)]
/**
* @author Giles
* MyBatis的工具类
*/
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
InputStream in=null;
try {
in=Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
}
/**
* 获取SqlSession的方法
* @return
*/
public static SqlSession getSqlSession() {
SqlSession sqlSession=sqlSessionFactory.openSession();
return sqlSession;
}
/**
* 关闭sqlSession
* @param sqlSession
*/
public static void closeSqlSession(SqlSession sqlSession) {
if(sqlSession!=null) {
sqlSession.close();
}
}
}
使用SqlSession对象提供的API完成CRUD操作
3.1.映射文件
<?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="com.woniuxy.mapper.UserMapper">
<select id="selectAllUser" resultType="com.woniuxy.entity.User">
SELECT * FROM users
</select>
<!--
增加操作使用insert元素,常用属性如下
id:唯一的标识
parameterType:入参的类型,类型可以使用简单数据类型(8种基本数据类型,String),对象数据类型
如果是简单类型 :可以包装类全名java.lang.Integer也可以写int
如果对象类型的:可以写类型全名,也可以写类的别名(别名设置后面讲)
-->
<insert id="insertUser" parameterType="com.woniuxy.entity.User">
INSERT INTO users(name,age)VALUES(#{
name},#{
age})
</insert>
<!--
在进行传递数据的使用parameterType表示入参的类型
在指定入参类型的时候,可以写这个类型全名,也可以写入参类型的别名,(可以大写小写混写)但是不能写错
建议写的使用还是写成类全名
-->
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM users WHERE id=#{
id}
</delete>
<update id="updateUser" parameterType="com.woniuxy.entity.User">
UPDATE users SET NAME=#{
name} WHERE id=#