MyBatis基础知识扫盲

本文不讲具体的MyBatis的一些用法,只记录一些MyBatis的基础知识

MyBatis 是什么

在移动互联网时代,MyBatis 成为了目前互联网 Java 持久框架的首选。

MyBatis 本是 Apache 的一个开源项目——iBatis,2010 年这个项目由 Apache Software Foundation 迁移到了 Google Code,并且改名为 MyBatis。

MyBatis 是一个基于 Java 的持久层框架。MyBatis 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO),它消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。

MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

目前,Java 的持久层框架产品有许多,常见的有 Hibernate 和 MyBatis。

Hibernate 和 MyBatis 的区别

1)sql 优化方面

  • Hibernate 不需要编写大量的 SQL,就可以完全映射,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)对 POJO 进行操作。但会多消耗性能。
  • MyBatis 手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。工作量相对大些。

2)开发方面

  • MyBatis 是一个半自动映射的框架,因为 MyBatis 需要手动匹配 POJO、SQL 和映射关系。
  • Hibernate 是一个全表映射的框架,只需提供 POJO 和映射关系即可。

3)Hibernate 优势

  • Hibernate 的 DAO 层开发比 MyBatis 简单,Mybatis 需要维护 SQL 和结果映射。
  • Hibernate 对对象的维护和缓存要比 MyBatis 好,对增删改查的对象的维护要方便。
  • Hibernate 数据库移植性很好,MyBatis 的数据库移植性不好,不同的数据库需要写不同 SQL。
  • Hibernate 有更好的二级缓存机制,可以使用第三方缓存。MyBatis 本身提供的缓存机制不佳。

4)Mybatis优势

  • MyBatis 可以进行更为细致的 SQL 优化,可以减少查询字段。
  • MyBatis 容易掌握,而 Hibernate 门槛较高。

总的来说,MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。

所以对于性能要求不太苛刻的系统,比如管理系统、ERP 等推荐使用 Hibernate,而对于性能要求高、响应快、灵活的系统则推荐使用 MyBatis。

MyBatis 的工作原理

在学习 MyBatis 程序之前,读者需要了解一下 MyBatis 工作原理,以便于理解程序。MyBatis 的工作原理如图所示。

下面对图中的每步流程进行说明。

1)读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2)加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

MyBatis框架的执行流程图

4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

MyBatis 的核心组件

我们先来看 MyBatis 的“表面现象”——组件,并且讨论它们的作用,然后讨论它们的实现原理。MyBatis 的核心组件分为 4 个部分。

1)SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成 SqlSessionFactory,采用的是分步构建的 Builder 模式。

2)SqlSessionFactory(工厂接口):依靠它来生成 SqlSession,使用的是工厂模式。

3)SqlSession(会话):一个既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是 MyBatis 提供的 SQL Mapper 接口编程技术,它能提高代码的可读性和可维护性。

4)SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个 Java 接口和 XML 文件(或注解)构成,需要给出对应的 SQL 和映射规则。它负责发送 SQL 去执行,并返回结果。

用一张图来展示 MyBatis 核心组件之间的关系,如图所示。

MyBatis核心组件

注意,无论是映射器还是 SqlSession 都可以发送 SQL 到数据库执行

MyBatis SqlSessionFactory

使用 MyBatis 首先是使用配置或者代码去生产 SqlSessionFactory,而 MyBatis 提供了构造器 SqlSessionFactoryBuilder。

它提供了一个类 org.apache.ibatis.session.Configuration 作为引导,采用的是 Builder 模式。具体的分步则是在 Configuration 类里面完成的,当然会有很多内容,包括你很感兴趣的插件。

在 MyBatis 中,既可以通过读取配置的 XML 文件的形式生成 SqlSessionFactory,也可以通过 Java 代码的形式去生成 SqlSessionFactory。

笔者强烈推荐采用 XML 的形式,因为代码的方式在需要修改的时候会比较麻烦。当配置了 XML 或者提供代码后,MyBatis 会读取配置文件,通过 Configuration 类对象构建整个 MyBatis 的上下文。

注意,SqlSessionFactory 是一个接口,在 MyBatis 中它存在两个实现类:SqlSessionManager 和 DefaultSqlSessionFactory。

一般而言,具体是由 DefaultSqlSessionFactory 去实现的,而 SqlSessionManager 使用在多线程的环境中,它的具体实现依靠 DefaultSqlSessionFactory,它们之间的关系如图所示。

SqlSessionFactory的生成

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的,而 SqlSessionFactory 唯一的作用就是生产 MyBatis 的核心接口对象 SqlSession,所以它的责任是唯一的。我们往往会采用单例模式处理它,下面讨论使用配置文件和 Java 代码两种形式去生成 SqlSessionFactory 的方法。

使用 XML 构建 SqlSessionFactory

首先,在 MyBatis 中的 XML 分为两类,一类是基础配置文件,通常只有一个,主要是配置一些最基本的上下文参数和运行环境;另一类是映射文件,它可以配置映射关系、SQL、参数等信息。

先看一份简易的基础配置文件,我们把它命名为 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>
    <typeAliases><!--别名-->
        <typeAliases alias="user" type="com.mybatis.po.User"/>
    </typeAliases>
    <!-- 数据库环境 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用JDBC的事务管理 -->
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <!-- MySQL数据库驱动 -->
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <!-- 连接数据库的URL -->
                <property name="url"
                    value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="1128" />
            </dataSource>
        </environment>
    </environments>
    <!-- 将mapper文件加入到配置文件中 -->
    <mappers>
        <mapper resource="com/mybatis/mapper/UserMapper.xml" />
    </mappers>
</configuration>

我们描述一下 MyBatis 的基础配置文件:

  • < typeAlias > 元素定义了一个别名 user,它代表着 com.mybatis.po.User 这个类。这样定义后,在 MyBatis 上下文中就可以使用别名去代替全限定名了。
  • < environment> 元素的定义,这里描述的是数据库。它里面的 元素是配置事务管理器,这里采用的是 MyBatis 的 JDBC 管理器方式。
  • < dataSource> 元素配置数据库,其中属性 type=“POOLED” 代表采用 MyBatis 内部提供的连接池方式,最后定义一些关于 JDBC 的属性信息。
  • < mapper> 元素代表引入的那些映射器,在谈到映射器时会详细讨论它。

有了基础配置文件,就可以用一段很简短的代码来生成 SqlSessionFactory 了,如下所示。

SqlSessionFactory factory = null;
String resource = "mybatis-config.xml";
InputStream is;
try {
    InputStream is = Resources.getResourceAsStream(resource);
    factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
    e.printStackTrace();
}

首先读取 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 的 Builder 方法去创建 SqlSessionFactory。整个过程比较简单,而里面的步骤还是比较烦琐的,只是 MyBatis 采用了 Builder 模式为开发者隐藏了这些细节。这样一个 SqlSessionFactory 就被创建出来了。

采用 XML 创建的形式,信息在配置文件中,有利于我们日后的维护和修改,避免了重新编译代码,因此笔者推荐这种方式。

使用代码创建 SqlSessionFactory

虽然笔者不推荐使用这种方式,但是我们还是谈谈如何使用它。通过代码来实现与使用 XML 构建 SqlSessionFactory 一样的功能——创建 SqlSessionFactory,代码如下所示。

// 数据库连接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword ("1128");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
dataSource.setDefeultAutoCommit(false);
// 采用 MyBatis 的 JDBC 事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment ("development", transactionFactory, dataSource);
// 创建 Configuration 对象
Configuration configuration = new Configuration(environment);
// 注册一个 MyBatis 上下文别名
configuration.getTypeAliasRegistry().registerAlias("role", Role.class);
// 加入一个映射器
configuration.addMapper(RoleMapper.class);
//使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory
SqlSessionFactory SqlSessionFactory =
new SqlSessionFactoryBuilder().build(configuration);
return SqlSessionFactory;

注意代码中的注释,它和 XML 方式实现的功能是一致的,只是方式不太一样而已。但是代码冗长,如果发生系统修改,那么有可能需要重新编译代码才能继续,所以这不是一个很好的方式。

除非有特殊的需要,比如在配置文件中,需要配置加密过的数据库用户名和密码,需要我们在生成 SqlSessionFactory 前解密为明文的时候,才会考虑使用这样的方式。

MyBatis SqlSession简介

在 MyBatis 中,SqlSession 是其核心接口。在 MyBatis 中有两个实现类,DefaultSqlSession 和 SqlSessionManager。

DefaultSqlSession 是单线程使用的,而 SqlSessionManager 在多线程环境下使用。SqlSession 的作用类似于一个 JDBC 中的 Connection 对象,代表着一个连接资源的启用。具体而言,它的作用有 3 个:

  • 获取 Mapper 接口。
  • 发送 SQL 给数据库。
  • 控制数据库事务。

先来掌握它的创建方法,有了 SqlSessionFactory 创建的 SqlSession 就十分简单了,如下所示。

SqlSession sqlSession = SqlSessionFactory.openSession();

注意,SqlSession 只是一个门面接口,它有很多方法,可以直接发送 SQL。它就好像一家软件公司的商务人员,是一个门面,而实际干活的是软件工程师。在 MyBatis 中,真正干活的是 Executor,我们会在底层看到它。

SqlSession 控制数据库事务的方法,如下所示。

//定义 SqlSession
SqlSession sqlSession = null;
try {
    // 打开 SqlSession 会话
    sqlSession = SqlSessionFactory.openSession();
    // some code...
    sqlSession.commit();    // 提交事务
} catch (IOException e) {
    sqlSession.rollback();  // 回滚事务
}finally{
    // 在 finally 语句中确保资源被顺利关闭
    if(sqlSession != null){
        sqlSession.close();
    }
}

这里使用 commit 方法提交事务,或者使用 rollback 方法回滚事务。因为它代表着一个数据库的连接资源,使用后要及时关闭它,如果不关闭,那么数据库的连接资源就会很快被耗费光,整个系统就会陷入瘫痪状态,所以用 finally 语句保证其顺利关闭。

MyBatis实现映射器的2种方式

映射器是 MyBatis 中最重要、最复杂的组件,它由一个接口和对应的 XML 文件(或注解)组成。它可以配置以下内容:

  • 描述映射规则。
  • 提供 SQL 语句,并可以配置 SQL 参数类型、返回类型、缓存刷新等信息。
  • 配置缓存。
  • 提供动态 SQL。

本节阐述两种实现映射器的方式,XML 文件形式和注解形式。不过在此之前,先用以下 SQL 语句创建 role 表。

CREATE TABLE `role` (
    `id` bigint(20) NOT NULL,
    `role_name` varchar(20) DEFAULT NULL,
    `note` varchar(20) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

并且定义一个 POJO,它十分简单,如下所示。

package com.mybatis.po;
public class Role {
    private Long id;
    private String roleName;
    private String note;
/**setter and getter**/
}

映射器的主要作用就是将 SQL 查询到的结果映射为一个 POJO,或者将 POJO 的数据插入到数据库中,并定义一些关于缓存等的重要内容。

注意,开发只是一个接口,而不是一个实现类。初学者可能会产生一个很大的疑问,那就是接口不是不能运行吗?

是的,接口不能直接运行。MyBatis 运用了动态代理技术使得接口能运行起来,入门阶段只要懂得 MyBatis 会为这个接口生成一个代理对象,代理对象会去处理相关的逻辑即可。

用 XML 实现映射器

用 XML 定义映射器分为两个部分:接口和 XML。先定义一个映射器接口,如下所示。

package com.mybatis.mapper;
import com.mybatis.po.Role;
public interface RoleMapper {
    public Role getRole(Long id);
}

在用 XML 方式创建 SqlSession 的配置文件中有这样一段代码:

<mapper resource="com/mybatis/mapper/RoleMapper.xml" />

它的作用就是引入一个 XML 文件。用 XML 方式创建映射器,如下所示。

<?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.mybatis.mapper.RoleMapper">
    <select id="getRole" parameterType="long" resultType="role">
        SELECT id,role_name as roleName,note FROM role WHERE id =#{id}
    </select>
</mapper>

有了这两个文件,就完成了一个映射器的定义。XML 文件还算比较简单,我们稍微讲解一下:

< mapper> 元素中的属性 namespace 所对应的是一个接口的全限定名,于是 MyBatis 上下文就可以通过它找到对应的接口。

< select> 元素表明这是一条查询语句,而属性 id 标识了这条 SQL,属性 parameterType=“long” 说明传递给 SQL 的是一个 long 型的参数,而 resultType=“role” 表示返回的是一个 role 类型的返回值。而 role 是之前配置文件 mybatis-config.xml 配置的别名,指代的是 com.mybatis.po.Role。

这条 SQL 中的 #{id} 表示传递进去的参数。

注意,我们并没有配置 SQL 执行后和 role 的对应关系,它是如何映射的呢?

其实这里采用的是一种被称为自动映射的功能,MyBatis 在默认情况下提供自动映射,只要 SQL 返回的列名能和 POJO 对应起来即可。

这里 SQL 返回的列名 id 和 note 是可以和之前定义的 POJO 的属性对应起来的,而表里的列 role_name 通过 SQL 别名的改写,使其成为 roleName,也是和 POJO 对应起来的,所以此时 MyBatis 就可以把 SQL 查询的结果通过自动映射的功能映射成为一个 POJO。

注解实现映射器

除 XML 方式定义映射器外,还可以采用注解方式定义映射器,它只需要一个接口就可以通过 MyBatis 的注解来注入 SQL,如下所示。

package com.mybatis.mapper;
import org.apache.ibatis.annotations.Select;
import com.mybatis.po.Role;
public interface RoleMapper2 {
    @Select("select id,role_name as roleName,note from t_role where id=#{id}")
    public Role getRole(Long id);
}

这完全等同于 XML 方式创建映射器。也许你会觉得使用注解的方式比 XML 方式要简单得多。如果它和 XML 方式同时定义时,XML 方式将覆盖掉注解方式,所以 MyBatis 官方推荐使用的是 XML 方式,因此本教程以 XML 方式为主讨论 MyBatis 的应用。

在工作和学习中,SQL 的复杂度远远超过我们现在看到的 SQL,比如下面这条 SQL。

select * from t_user u
left join t_user_role ur on u.id = ur.user_id
left join t_role r on ur.role_id = r.id
left join t_user_info ui on u.id = ui.user_id
left join t_female_health fh on u.id = fh.user_id
left join t_male_health mh on u.id = mh.user_id
where u.user_name like concat('%', ${userName},'%')
and r.role_name like concat('%', ${roleName},'%')
and u.sex = 1
and ui.head_image is not null;

显然这条 SQL 比较复杂,如果放入 @Select 中会明显增加注解的内容。如果把大量的 SQL 放入 Java 代码中,显然代码的可读性也会下降。

如果同时还要考虑使用动态 SQL,比如当参数 userName 为空,则不使用 u.user_name like concat(’%’,userName,{userName},'%')作为查询条件;当 roleName 为空,则不使用 r.role_name like concat('%',{roleName},’%’)作为查询条件,但是还需要加入其他的逻辑,这样就使得这个注解更加复杂了,不利于日后的维护和修改。

此外,XML 可以相互引入,而注解是不可以的,所以在一些比较复杂的场景下,使用 XML 方式会更加灵活和方便。所以大部分的企业都是以 XML 为主,本教程也会保持一致,以 XML 方式来创建映射器。当然在一些简单的表和应用中使用注解方式也会比较简单。

这个接口可以在 XML 中定义,我们仿造在 mybatis-config.xml 中配置 XML 语句:

<mapper resource="com/mybatis/mapper/RoleMapper.xml" />

把它修改为下面的形式即可。

<mapper resource="com/mybatis/mapper/RoleMapper2" />

也可以使用 configuration 对象注册这个接口,比如:

configuration.addMapper(RoleMapper2.class);

MyBatis执行SQL的两种方式

本节主要介绍 MyBatis 执行 SQL 语句的两种方式和它们的区别。

SqlSession 发送 SQL

有了映射器就可以通过 SqlSession 发送 SQL 了。我们以 getRole 这条 SQL 为例看看如何发送 SQL。

Role role = (Role)sqlSession.select("com.mybatis.mapper.RoleMapper.getRole",1L);

selectOne 方法表示使用查询并且只返回一个对象,而参数则是一个 String 对象和一个 Object 对象。这里是一个 long 参数,long 参数是它的主键。

String 对象是由一个命名空间加上 SQL id 组合而成的,它完全定位了一条 SQL,这样 MyBatis 就会找到对应的 SQL。如果在 MyBatis 中只有一个 id 为 getRole 的 SQL,那么也可以简写为:

Role role = (Role)sqlSession.selectOne("getRole",1L);

这是 MyBatis 前身 iBatis 所留下的方式。

用 Mapper 接口发送 SQL

SqlSession 还可以获取 Mapper 接口,通过 Mapper 接口发送 SQL,如下所示。

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); Role role = roleMapper.getRole(1L);

通过 SqlSession 的 getMapper 方法来获取一个 Mapper 接口,就可以调用它的方法了。因为 XML 文件或者接口注解定义的 SQL 都可以通过“类的全限定名+方法名”查找,所以 MyBatis 会启用对应的 SQL 进行运行,并返回结果。

对比两种发送 SQL 方式

上面分别展示了 MyBatis 存在的两种发送 SQL 的方式,一种用 SqlSession 直接发送,另外一种通过 SqlSession 获取 Mapper 接口再发送。笔者建议采用 SqlSession 获取 Mapper 的方式,理由如下:

使用 Mapper 接口编程可以消除 SqlSession 带来的功能性代码,提高可读性,而 SqlSession 发送 SQL,需要一个 SQL id 去匹配 SQL,比较晦涩难懂。使用 Mapper 接口,类似roleMapper.getRole(1L)则是完全面向对象的语言,更能体现业务的逻辑。

使用 Mapper.getRole(1L)方式,IDE 会提示错误和校验,而使用sqlSession.selectOne(“getRole”,1L)语法,只有在运行中才能知道是否会产生错误。

目前使用 Mapper 接口编程已成为主流,尤其在 Spring 中运用 MyBatis 时,Mapper 接口的使用就更为简单,所以本教程使用 Mapper 接口的方式讨论 MyBatis。

MyBatis 核心组件的生命周期

我们已经掌握了 MyBatis 组件的创建及其基本应用,但这是远远不够的,还需要讨论其生命周期。

生命周期是组件的重要问题,尤其是在多线程的环境中,比如互联网应用、Socket 请求等,而 MyBatis 也常用于多线程的环境中,错误使用会造成严重的多线程并发问题,为了正确编写 MyBatis 的应用程序,我们需要掌握 MyBatis 组件的生命周期。

所谓生命周期就是每一个对象应该存活的时间,比如一些对象一次用完后就要关闭,使它们被 Java 虚拟机(JVM)销毁,以避免继续占用资源,所以我们会根据每一个组件的作用去确定其生命周期。

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。

SqlSessionFactory

SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。

由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。

因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域。

SqlSession

如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。

所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。

所以 SqlSession 的最佳的作用域是请求或方法作用域。

Mapper

Mapper 是一个接口,它由 SqlSession 所创建,所以它的最大生命周期至多和 SqlSession 保持一致,尽管它很好用,但是由于 SqlSession 的关闭,它的数据库连接资源也会消失,所以它的生命周期应该小于等于 SqlSession 的生命周期。Mapper 代表的是一个请求中的业务处理,所以它应该在一个请求中,一旦处理完了相关的业务,就应该废弃它。

以上,我们讨论了 MyBatis 组件的生命周期,如图所示。

MyBatis组件的生命周期

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章