# 基本概念

# 1. MyBatis 的体系结构

MyBatis 中的常用对象有 SqlSessionFactorySqlSession

SqlSessionFactory 对象是 MyBatis 的关键对象,它对应着单个数据库。

XML 配置文件
└── SqlSessionFactoryBuilder
    └── SqlSessionFactory
        └── SqlSession

整个关系可以如下述这样『反推』:

  • 最终是需要获得一个 SqlSession 对象来操作数据库。SqlSession 对象代表着与数据库之间的连接。

  • 要『弄』到 SqlSession 对象,首先要先『弄』到一个 SqlSessionFactory 对象。

  • 要『弄』到 SqlSessionFactory 对象,首先要先『弄』到一个 SqlSessionFactoryBuilder 对象。

  • 而在这个整个过程中,需要用到 1 + N 个配置文件。

// 这是一个相对于 classpath 的文件路径名。而且,不需要使用 / 。
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
SqlSession session = factory.openSession(true);

...

注意:使用完 SqlSession 之后『关闭 Session 很重要』,应该确保使用 finally 块来关闭它。

  • 一个 MyBatis 应用程序只需要一个 SqlSessionFactory 的对象。因此,SqlSessionFactory 对象应该是『单例对象』。在将 Mybatis 和 Spring 整合后,毫无疑问,SqlSessionFactory 单例对象的创建工作就交到了 Spring 手里。 `
  • SqlSession 是线程不安全的,所以 SqlSession 对象是非单例的。

# 2. 使用 XML 构建 SqlSessionFactory

MyBatis 中的 XML 文件分为两类,一类是『基础配置文件(也叫『核心配置文件』),它只有一个。另一类是『映射文件』,它至少有一个。合计是 1 + N 个配置文件

基础配置文件』通常叫做 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>
    <typeAlias alias="dept" type="com.xja.scott.bean.Department"/>
  </typeAliases>
-->
  <!-- 数据库环境。必须。-->
  <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://localhost:3306/scott?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=UTC"/>
        <property name="username" value="root" />
        <property name="password" value="123456" />
      </dataSource>
    </environment>
  </environments>

  <!-- 映射文件。必须。-->
  <mappers>
    <!--这是一个相对于 classpath 的路径名。另外,不需要使用 / 。 -->
    <mapper resource="mapper/DeptMapper.xml" />
  </mappers>

</configuration>
  • <typeAlias> 元素为一个类定义了一个别名,这样在后续使用该类时,可以直接使用别名,而不是它的完全限定名。

  • <environment> 元素描述了一个数据库相关信息。

    • 它里面的 <transactionManager> 元素配置了『事务管理器』 ,这里采用的是 MyBatis 的 JDBC 管理器方式。

    • 它里面的 <dataSource> 元素配置了数据库连接的相关信息,其中属性 type="POOLED" 表示采用 MyBatis 内部提供的连接池方式。

  • <mapper> 元素代表引入指定的 Mapper 配置文件。

为了加载 XML 配置文件来构建 SqlSessionFactory 对象。MyBaits 专门提供了 Resources 类来加载配置文件。

String resource = "mybatis-config.xml";
SqlSessionFactory factory = null;
InputStream is = null;

try {
    is = Resources.getResourceAsStream(resource);
    factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
    e.printStackTrace();
}

注意

Mybatis 对核心配置文件中的内容(子元素) 出现的『先后顺序有要求』,你可以没有使用到某个子元素,但是如果你用到了,那么必须符合固定的先后顺序:

  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
    • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

# 3. SqlSession

SqlSession 是 MyBatis 的核心接口。SqlSession 的作用类似于 JDBC 中的 Connection 对象,代表着一个数据库的连接。

它的作用有 3 个:

  • 获取 Mapper 接口。

  • 发送 SQL 给数据库。

  • 控制数据库事务。

有了 SqlSessionFactory 创建 SqlSession 就十分简单了:

SqlSession sqlSession = factory.openSession();
// 相当于
SqlSession sqlSession = factory.openSession(false);

由此可见,SqlSession 默认『未开启』事务的自动提交(autoCommit)功能。因此需要程序员手动操作事务。

另外,如果在建表时,有意或无意使用的是 MyIsam 引擎,那么此处无论是 true ,或者 false ,都无法回滚,因为 MyIsam 数据库引擎本身就不支持事务功能(这是它与 InnoDB 引擎的重要区别之一)

对初学者而言,建表是错误地使用了数据库引擎,而导致『事务不回滚』的常见原因。

SqlSession session = null;

try {
    session = factory.openSession();
    // some code ...
    session.commit();		// 提交事务
} catch (Exception e) {
    session.rollback();		// 回滚事务
} finally {
    if (session != null)
        session.close();	// 务必确保关闭 session
}

# 4. 默认的别名

别名 Java 类型 是否支持数组 别名 Java 类型 是否支持数组
_byte byte Y byte Byte Y
_short short Y short Short Y
_int int Y int Integer Y
_integer int Y integer Integer Y
_long long Y long Long Y
_float float Y float Float Y
_double double Y double Double Y
_boolean boolean Y boolean Boolean Y
decimal BigDecimal Y bigdecimal BigDecimal Y
string String Y date Date Y
object Object Y collection Collection
map Map —— hashmap HashMap ——

# 5. 补充

<environments default="...">
  <environment id="...">
    <transactionManager type="..."/>
      <dataSource type="...">
        <property name="driver" value="..."/>
        <property name="url" value="..."/>
        <property name="username" value="..."/>
      <property name="password" value="..."/>
    </dataSource>
  </environment>
</environments>

<transactionManager type="..."/> 表示事务管理器配置,可选值有:JDBCMANAGED

属性值 说明
JDBC 这个配置表示 MyBatis 底层使用 JDBC 中的 Connection 对象进行事务的提交和回滚。
MANAGED 这个配置表示 MyBatis 底层不进行任何事物的提交和回滚操作,而是由『别人』(容器)来进行事务的操作。
不过,默认情况下它会关闭连接,而有些容器并不希望如此,
所以通常使用子元素 <property name=closeConnection" value="false"/> 来取消这种行为。

在整合 Spring 和 MyBaits 时,不需要在此配置事务管理器,因为 Spring 会使用其自身的事务管理器来覆盖此处的配置。

<dataSource type="..."> 表示数据源配置,其可选值有:UNPOOLEDPOOLEDJNDI

属性值 说明
UNPOOLED 表示不使用连接池,因此每次请求都会打开/关闭连接。
POOLED 表示使用 MyBatis 内部的数连接池功能,此时在底层 Connection 对象会被复用。
JNDI 这表示这数据库连接由容器维护。使用较少。