mybatis工作原理通俗理解,mybatis真实原理

首页 > 经验 > 作者:YD1662022-10-29 11:27:50

作者:vivo互联网服务器团队-Zhang Peng

一、MyBatis 完整示例

这里,我将以一个入门级的示例来演示 MyBatis 是如何工作的。

注:本文后面章节中的原理、源码部分也将基于这个示例来进行讲解。完整示例源码地址

1.1. 数据库准备

在本示例中,需要针对一张用户表进行 CRUD 操作。其数据模型如下:

CREATE TABLE IF NOT EXISTS user ( id BIGINT(10) UNSIGNED NOT AUTO_INCREMENT COMMENT 'Id', name VARCHAR(10) NOT DEFAULT '' COMMENT '用户名', age INT(3) NOT DEFAULT 0 COMMENT '年龄', address VARCHAR(32) NOT DEFAULT '' COMMENT '地址', email VARCHAR(32) NOT DEFAULT '' COMMENT '邮件', PRIMARY KEY (id)) COMMENT = '用户表';
INSERT INTO user (name, age, address, email)VALUES ('张三', 18, '北京', 'xxx@163.com');INSERT INTO user (name, age, address, email)VALUES ('李四', 19, '上海', 'xxx@163.com');

1.2. 添加 MyBatis

如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:

<dependency> <groupId>org.Mybatis</groupId> <artifactId>Mybatis</artifactId> <version>x.x.x</version></dependency>

1.3. MyBatis 配置

XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。

本示例中只是给出最简化的配置。【示例】MyBatis-config.xml 文件

<?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="com.mysql.cj.jdbc.Driver" /> <property name="url" value="JDBC:mysql://127.0.0.1:3306/spring_tutorial?serverTimezone=UTC" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <mappers> <mapper resource="Mybatis/mapper/UserMapper.xml" /> </mappers></configuration>

说明:上面的配置文件中仅仅指定了数据源连接方式和 User 表的映射配置文件。

1.4 Mapper

1.4.1 Mapper.xml

个人理解,Mapper.xml 文件可以看做是 MyBatis 的 JDBC SQL 模板。【示例】UserMapper.xml 文件。

下面是一个通过 MyBatis Generator 自动生成的完整的 Mapper 文件。

<?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="io.github.dunwu.spring.orm.mapper.UserMapper"> <resultMap id="BaseResultMap" type="io.github.dunwu.spring.orm.entity.User"> <id column="id" jdbcType="BIGINT" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="Integer" property="age" /> <result column="address" jdbcType="VARCHAR" property="address" /> <result column="email" jdbcType="VARCHAR" property="email" /> </resultMap> <delete id="deleteByPrimaryKey" parameterType="java.lang.Long"> delete from user where id = #{id,jdbcType=BIGINT} </delete> <insert id="insert" parameterType="io.github.dunwu.spring.orm.entity.User"> insert into user (id, name, age, address, email) values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{address,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}) </insert> <update id="updateByPrimaryKey" parameterType="io.github.dunwu.spring.orm.entity.User"> update user set name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER}, address = #{address,jdbcType=VARCHAR}, email = #{email,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} </update> <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> select id, name, age, address, email from user where id = #{id,jdbcType=BIGINT} </select> <select id="selectAll" resultMap="BaseResultMap"> select id, name, age, address, email from user </select></mapper>

1.4.2 Mapper.java

Mapper.java 文件是 Mapper.xml 对应的 Java 对象。【示例】UserMapper.java 文件

public interface UserMapper {
int deleteByPrimaryKey(Long id);
int insert(User record);
User selectByPrimaryKey(Long id);
List<User> selectAll;
int updateByPrimaryKey(User record);
}

对比 UserMapper.java 和 UserMapper.xml 文件,不难发现:UserMapper.java 中的方法和 UserMapper.xml 的 CRUD 语句元素( <insert>、<delete>、<update>、<select>)存在一一对应关系。

在 MyBatis 中,正是通过方法的全限定名,将二者绑定在一起。

1.4.3 数据实体.java

【示例】User.java 文件

public class User { private Long id;
private String name;
private Integer age;
private String address;
private String email;
}

<insert>、<delete>、<update>、<select> 的 parameterType 属性以及 <resultMap> 的 type 属性都可能会绑定到数据实体。这样就可以把 JDBC 操作的输入输出和 JavaBean 结合起来,更加方便、易于理解。

1.5. 测试程序

【示例】MyBatisDemo.java 文件

public class MyBatisDemo {
public static void main(String[] args) throws Exception { // 1. 加载 MyBatis 配置文件,创建 SqlSessionFactory // 注:在实际的应用中,SqlSessionFactory 应该是单例 InputStream inputStream = Resources.getResourceAsStream("MyBatis/MyBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder; SqlSessionFactory factory = builder.build(inputStream);
// 2. 创建一个 SqlSession 实例,进行数据库操作 SqlSession sqlSession = factory.openSession;
// 3. Mapper 映射并执行 Long params = 1L; List<User> list = sqlSession.selectList("io.github.dunwu.spring.orm.mapper.UserMapper.selectByPrimaryKey", params); for (User user : list) { System.out.println("user name: " user.getName); } // 输出:user name: 张三 }
}

说明:SqlSession 接口是 MyBatis API 核心中的核心,它代表 MyBatis 和数据库一次完整会话。

二、MyBatis 生命周期

mybatis工作原理通俗理解,mybatis真实原理(1)

2.1. SqlSessionFactoryBuilder

2.1.1 SqlSessionFactoryBuilder 的职责

SqlSessionFactoryBuilder 负责创建

SqlSessionFactory 实例。

SqlSessionFactoryBuilder 可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

Configuration 类包含了对一个 SqlSessionFactory 实例你可能关心的所有内容。

mybatis工作原理通俗理解,mybatis真实原理(2)

SqlSessionFactoryBuilder 应用了建造者设计模式,它有五个 build 方法,允许你通过不同的资源创建 SqlSessionFactory 实例。

SqlSessionFactory build(InputStream inputStream)SqlSessionFactory build(InputStream inputStream, String environment)SqlSessionFactory build(InputStream inputStream, Properties properties)SqlSessionFactory build(InputStream inputStream, String env, Properties props)SqlSessionFactory build(Configuration config)

2.1.2 SqlSessionFactoryBuilder 的生命周期

SqlSessionFactoryBuilder 可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。

你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

2.2. SqlSessionFactory

2.2.1 SqlSessionFactory 职责

SqlSessionFactory 负责创建 SqlSession 实例。

mybatis工作原理通俗理解,mybatis真实原理(3)

SqlSessionFactory 应用了工厂设计模式,它提供了一组方法,用于创建 SqlSession 实例。

SqlSession openSessionSqlSession openSession(boolean autoCommit)SqlSession openSession(Connection connection)SqlSession openSession(TransactionIsolationLevel level)SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level)SqlSession openSession(ExecutorType execType)SqlSession openSession(ExecutorType execType, boolean autoCommit)SqlSession openSession(ExecutorType execType, Connection connection)Configuration getConfiguration;

方法说明:

默认的 openSession 方法没有参数,它会创建具备如下特性的 SqlSession:

1)事务作用域将会开启(也就是不自动提交)。

2)TransactionIsolationLevel 表示事务隔离级别,它对应着 JDBC 的五个事务隔离级别。

3)ExecutorType 枚举类型定义了三个值:

2.2.2 SqlSessionFactory 生命周期

SQLSessionFactory 应该以单例形式在应用的运行期间一直存在。

2.3. SqlSession

2.3.1 SqlSession 职责

MyBatis 的主要 Java 接口就是 SqlSession。它包含了所有执行语句,获取映射器和管理事务等方法。详细内容可以参考:「 MyBatis 官方文档之 SqlSessions 」 。

SQLSession 类的方法可按照下图进行大致分类:

mybatis工作原理通俗理解,mybatis真实原理(4)

首页 123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.