跳到主要内容

MyBatis 简单使用

1. 前言

上一节中,我们搭建了 MyBatis 实验环境。本小节,我们将一起学习如何使用 MyBatis,虽然在实际的开发中,你几乎不会按照本小节所介绍的方式去使用 MyBatis,但是这对你熟悉 MyBatis 整体结构有着重要作用,同时这也是面试的重点。

2. 编程式使用

MyBatis 官方文档中并未详细的介绍如何编程式使用 MyBatis,绝大多数情况下,我们都是通过 配置文件来拿到配置然后开启会话的。这样的方式固然很方便,但是却屏蔽了太多的细节,因此我们想从点到面,层层递进给你介绍 MyBatis 的基础用法。

接下来,我们一起来写一个简单的 demo 来使用一下 MyBatis。

2.1 启动 MyBatis

在 mybatis-primer 项目中,有一个默认的包com.imooc.mybatis,在该包下,我们新建一个包名为pattern,并在其中新建一个名为StartNoXml.java的类,并向该文件中填充如下代码:

package com.imooc.mybatis.pattern;

import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@SuppressWarnings({"SqlResolve", "SqlNoDataSourceInspection", "Duplicates"})
public class StartNoXml {
public static void main(String[] args) throws SQLException {
// 无需xml配置的方式使用MyBatis
// 准备jdbc事务类
JdbcTransactionFactory jdbcTransactionFactory = new JdbcTransactionFactory();
// 配置数据源
PooledDataSource dataSource =
new PooledDataSource("com.mysql.cj.jdbc.Driver",
"jdbc:mysql://localhost:3306/imooc?useSSL=false",
"root", "123456");
// 配置环境,向环境中指定环境id、事务和数据源
Environment environment = new Environment.Builder("development")
.transactionFactory(jdbcTransactionFactory)
.dataSource(dataSource).build();
// 新建 MyBatis 配置类
Configuration configuration = new Configuration(environment);
// 得到 SqlSessionFactory 核心类
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
// 开始一个 sql 会话
SqlSession session = sqlSessionFactory.openSession();
// 得到 sql 连接并运行 sql 语句
PreparedStatement preStatement = session
.getConnection()
.prepareStatement("SELECT \* FROM imooc\_user WHERE id = ?");
preStatement.setInt(1, 1);
ResultSet result = preStatement.executeQuery();
// 验证结果
while (result.next()) {
System.out.println("username: " + result.getString("username"));
}
// 关闭会话
session.close();
}
}

即使你不熟悉 MyBatis,也没有必要被这段代码给吓到,因为在实际的开发中,你几乎没有机会去写这段代码。但是我们仍需要介绍这段代码,它可能是你面试的重点。

书写完毕后,请在 PooledDataSource 类构造函数中更改数据用户名、密码和 url 配置以满足你所使用的数据库环境。运行一下这段代码,如果一切顺利,在控制台中你会看到以下输出内容(只截取了部分内容):

18:31:44.914 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
****
username: peter
****
18:31:45.413 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1234250905 to pool.

2.2 使用流程

在代码中,我们添加了一定量的注释说明了流程,接下来我们来总结一下。

对于 MyBatis 的基础使用可大致分为以下3步:

  1. 得到 MyBatis 配置信息,即代码中的Configuration类。Configuration 负责 MyBatis 架构中的配置部分,例如:dataSource数据源信息都会交给 Configuration 去管理;这一步其实是比较繁杂的,Environment 是 Configuration 中的一部分,而 PooledDataSource 和 JdbcTransactionFactory 又是 Environment 中的一部分,它们是属于层层递进的关系。其中 JdbcTransactionFactory 表示事务工厂,当 MyBatis 需要新建事务的时候,会通过它来新建;PooledDataSource 表示数据源,通过其构造参数,我们传入了数据库 url,数据库用户和密码等配置;Configuration 可以有多个 Environment,因此每个 Environment 都必须有唯一的 id,即代码中的 development,将这些配置搭配组合后就是一个可用的 Configuration。
  2. 通过 Configuration 来创建 SqlSessionFactory。MyBatis 是通过会话的方式来执行 SQL 的,因为我们必须拥有一个会话创建器,即会话工厂。
  3. 新建SqlSession来执行 SQL。有了 SqlSessionFactory 后,我们就可以方便地新建会话,并通过会话来执行 SQL 了。

PreparedStatement及以下的内容,其实并不属于 MyBatis,它们是 JDBC 提供的,在实际的 MyBatis 开发中,你也不会这样去执行 SQL,在这里我们只是为了展示 MyBatis 和 JDBC 的关系。

可以看到,编程式使用 MyBatis 其实是比较复杂,你需要十分熟悉 MyBatis 的 API,而且这种硬编码的方式是比较笨重的,所以绝大多数资料都推荐配置的方式使用 MyBatis。

3. 配置式使用

接下来,我们一起来看一下如何通过配置来使用 MyBatis。

3.1 配置文件

首先,我们在resources目录下新建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://localhost:3306/imooc?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>

有了上面编程式 API 的使用经验,那么你一定可以轻松的看懂配置项,configuration 标签对应 Configuration 类,environment 标签对应 Environment 类,transactionManager标签和dataSource标签分别对应 JdbcTransactionFactory 和 PooledDataSource 类。

有了配置文件后,我们无需一个挨着一个的新建类,而是在配置文件中指定即可,如driver的值指定为com.mysql.cj.jdbc.Driver。当后续需要修改的时候,也不需要去代码中找,而是直接在配置文件中修改即可。

TIPS: 注意, 请在你自己的配置文件中修改数据库配置,以满足你自己的数据库环境。

3.2 启动 MyBatis

同样地,我们在 patter 包下新建另一个类,名为StartWithXml.java,并填充以下代码:

package com.imooc.mybatis.pattern;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@SuppressWarnings({"SqlResolve", "SqlNoDataSourceInspection", "Duplicates"})
public class StartWithXml {

public static void main(String[] args) throws IOException, SQLException {
// 配置式使用MyBatis
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 按照配置文件得到 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 新建会话
SqlSession session = sqlSessionFactory.openSession();
// 执行SQL
PreparedStatement preStatement = session.getConnection().prepareStatement("SELECT \* FROM imooc\_user WHERE id = ?");
preStatement.setInt(1, 1);
ResultSet result = preStatement.executeQuery();
while (result.next()) {
System.out.println("username: " + result.getString("username"));
}
// 关闭会话
session.close();
}
}

运行代码,你会看到跟上面一样的结果。

3.3 使用流程

配置式使用 MyBatis,也可分为3步:

  1. 读取配置文件,即mybatis-config.xml
  2. 通过配置文件来创建 SqlSessionFactory
  3. 新建SqlSession来执行 SQL。

与编程式相比,配置式更为简洁,更易维护,所以使用广泛,几乎所有资料都推荐这种方式来使用 MyBatis。但是编程式并非没有意义,它可以帮助你梳理 MyBatis 结构,有了编程式的基础,你才能更加容易地看懂配置文件中的内容,在后续的学习中,我们都将默认地使用配置式。

4. 小结

  • 在实际的开发中,你都少有机会去按照本小节的方式去使用 MyBatis,但是这对你深入理解MyBatis结构有重要作用。
  • 编程式使用的 API 较多,我们没有必要去死记硬背,熟练掌握其使用流程,能在需要的时候查阅即可。