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
步:
- 得到 MyBatis 配置信息,即代码中的
Configuration
类。Configuration 负责 MyBatis 架构中的配置部分,例如:dataSource数据源信息都会交给 Configuration 去管理;这一步其实是比较繁杂的,Environment 是 Configuration 中的一部分,而 PooledDataSource 和 JdbcTransactionFactory 又是 Environment 中的一部分,它们是属于层层递进的关系。其中 JdbcTransactionFactory 表示事务工厂,当 MyBatis 需要新建事务的时候,会通过它来新建;PooledDataSource 表示数据源,通过其构造参数,我们传入了数据库 url,数据库用户和密码等配置;Configuration 可以有多个 Environment,因此每个 Environment 都必须有唯一的 id,即代码中的 development,将这些配置搭配组合后就是一个可用的 Configuration。 - 通过 Configuration 来创建
SqlSessionFactory
。MyBatis 是通过会话的方式来执行 SQL 的,因为我们必须拥有一个会话创建器,即会话工厂。 - 新建
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
步:
- 读取配置文件,即
mybatis-config.xml
。 - 通过配置文件来创建
SqlSessionFactory
。 - 新建
SqlSession
来执行 SQL。
与编程式相比,配置式更为简洁,更易维护,所以使用广泛,几乎所有资料都推荐这种方式来使用 MyBatis。但是编程式并非没有意义,它可以帮助你梳理 MyBatis 结构,有了编程式的基础,你才能更加容易地看懂配置文件中的内容,在后续的学习中,我们都将默认地使用配置式。
4. 小结
- 在实际的开发中,你都少有机会去按照本小节的方式去使用 MyBatis,但是这对你
深入理解MyBatis
结构有重要作用。 - 编程式使用的 API 较多,我们没有必要去死记硬背,熟练掌握其使用流程,能在需要的时候查阅即可。