# 2. MyBatis - HelloWorld

# 2.1 工程搭建

# 2.1.1 建立数据库和数据库表

DROP TABLE IF EXISTS `tbl_employee`;
CREATE TABLE `tbl_employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `last_name` varchar(45) ,
  `gender` char(1),
  `email` varchar(45),
  PRIMARY KEY (`id`)
) ;

# 2.1.2 导入 jar 包

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.5</version>
</dependency>

# 2.1.3 建立 bean 类 Employee.java

public class Employee {

    private Integer id;
    private String lastName;
    private String gender;
    private String email;
  	
  	//getter、setter
  	//toString()
    //有参构造、无参构造
}

# 2.1.4 编写 MyBatis 全局配置文件 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"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="EmployeeMapper.xml"></mapper>
    </mappers>
</configuration>

几个玩意:

  • environments:环境,比如生产环境、测试环境、部署环境等待
    • default:指定标签中的某一个环境作为默认值
  • environment:具体每一个环境的定义
    • transactionManager:事务控制,这里写 JDBC
    • dataSource:数据源
      • type:类型,这里是 POOLED,连接池
      • property:定义数据库的常规四个属性
  • mappers:该标签里面存放多个 MyBatis 的映射配置文件
  • mapper:指定每一个映射文件的所在位置

# 2.1.5 编写 Employee 的 SQL 映射配置文件 EmployeeMapper.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.hedon.mybatis.dao.EmployeeMapper">
    <select id="getEmpById" resultType="com.hedon.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>

几个玩意:

  • namespace:命名空间,指定该映射文件所指向的接口的全限定路径
  • select:表明这是一条 select 类的 sql 语句
    • id:指定方法名,唯一,该语句映射完就是映射到一个方法上
    • resultType:方法返回的类型,这里是 Employee
    • select 标签之间:写 sql 语句
      • #{id}:取参数,这里只有一个参数,#{id}、#{arg}、#{abc}都是一个效果的

# 2.1.6 编写接口 EmployeeMapper.java

public interface EmployeeMapper {

    Employee getEmpById(Integer id);

}

# 2.1.7 测试

@Test
public void test() throws IOException {
    //读取 MyBatis 全局配置文件
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    //获取 SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取 sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try{
        //反射生成 EmployeeMapper 的代理对象,这个时候 mapper 配置文件就已经映射到 getEmpById() 方法上,使其具有具体的功能了 => 接口式编程
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        //使用代理对象来执行方法
        Employee empById = mapper.getEmpById(1);
        System.out.println(empById);
    }finally {
        //关闭 sqlSession
        sqlSession.close();
    }
}

# 2.1.8 结果

# 结果如下:
Employee{id=1, lastName='null', gender=1, email='171725713@qq.com'}
# 留下的问题:
这里的 lastName 的值没有取到,原因是数据库中的字段是 last_name 而 Employee 类中的属性是 lastName。
# 注意点:
SqlSession 代表和数据库的一次会话,用完必须关闭;
SqlSession 和 connection 一样都是非线程安全的,每次使用都应该去获取新的对象;

# 2.2 功能架构

image-20200923155550440

我们把Mybatis的功能架构分为三层:

# 2.2.1 API 接口层

提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

# 2.2.2 数据处理层

负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

# 2.2.3 基础支撑层

负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。


# 2.3 总体流程

我们来根据前面的 HelloWorld 案例来梳理 MyBatis 的总体流程。

st=>start: 开始
op1=>operation: 读取配置文件 myabtis-config.xml
op2=>operation: 从 myabtis-config.xml 中的 <mappers> 标签找到 EmployeeMapper.xml 
op3=>operation: 在 EmployeeMapper.xml 中找到 getEmpById,请求生成 SQL 语句
op4=>operation: 注入 id 的值,生成完整的 SQL 语句
op5=>operation: 去数据库里面玩一圈,执行 SQL 语句
op6=>operation: 得到结果映射,并进行转换处理,得到最终的 Employee 对象
end=>end: 释放连接资源
st->op1->op2->op3->op4->op5->op6->end

# 2.3.1 加载配置并初始化

每个 MyBatis 应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。

用 xml 文件构建 SqlSessionFactory 实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何 Reader 实例,包括用文件路径或 file://开头的 url 创建的实例。MyBatis有一个实用类Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。

  • 触发条件:加载配置文件。

  • 处理过程:

    将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

# 2.3.2 接收调用请求

  • 触发条件:调用 Mybatis 提供的API
  • 传入参数:为 SQL 的 ID 和传入参数对象
  • 处理过程:将请求传递给下层的请求处理层进行处理。

# 2.3.3 处理操作请求

  • 触发条件:API 接口层传递请求过来
  • 传入参数:为 SQL 的 ID 和传入参数对象
  • 处理过程:
    • 根据 SQL 的 ID 查找对应的 MappedStatement 对象。
    • 根据传入参数对象解析 MappedStatement 对象,得到最终要执行的 SQL 和执行传入参数。
    • 获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
    • 根据 MappedStatement 对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
    • 释放连接资源。

# 2.3.4 返回处理结果将最终的处理结果返回

上次更新: 8/28/2022, 11:43:26 PM