You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

MyBatis的底层操作封装了JDBC的APIMyBatis的工作原理以及核心流程与JDBC的使用步骤一脉相承MyBatis的核心对象SqlSessionExecutor与JDBC的核心对象ConnectionStatement相互对应。从JDBC入手并立足于JDBC才能深入的理解MyBatis的工作原理以及核心流程。

一、Mybatis工作原理

JDBC有四个核心对象
1DriverManager用于注册数据库连接 2Connection与数据库连接对象 3Statement/PrepareStatement操作数据库SQL语句的对象 4ResultSet结果集或一张虚拟表

而MyBatis也有四大核心对象
1SqlSession对象该对象中包含了执行SQL语句的所有方法【1】。类似于JDBC里面的Connection 【2】。
2Executor接口它将根据SqlSession传递的参数动态地生成需要执行的SQL语句同时负责查询缓存的维护。类似于JDBC里面的Statement/PrepareStatement。
3MappedStatement对象该对象是对映射SQL的封装用于存储要映射的SQL语句的id、参数等信息。
4ResultHandler对象用于对返回的结果进行处理最终得到自己想要的数据格式或类型。可以自定义返回类型。

在JDBC中Connection不直接执行SQL方法而是利用Statement或者PrepareStatement来执行方法。在使用JDBC建立了连接之后可以使用Connection接口的createStatement()方法来获取Statement对象也可以调用prepareStatement()方法获得PrepareStatement对象通过executeUpdate()方法来执行SQL语句。而在MyBatis中SqlSession对象包含了执行SQL语句的所有方法但是它是委托Executor执行的。从某种意义上来看MyBatis里面的SqlSession类似于JDBC中的Connection他们都是委托给其他类去执行。

虽然SqlSession对象包含了执行SQL语句的所有方法但是它同样包括了

<T> T getMapper(Class<T> type);

所以SqlSession也可以委托给映射器来执行数据的增删改查操作。如下代码所示

   // 获得mapper接口的代理对象
   PersonMapper pm = session.getMapper(PersonMapper.class);
   // 直接调用接口的方法查询id为1的Peson数据
   Person p2 = pm.selectPersonById(1);

二、MyBatis的工作原理以及核心流程详解

Mybatis的运行过程分为两大步

  • 第1步读取配置文件缓存到Configuration对象用于创建SqlSessionFactory
  • 第2步SqlSession的执行过程。相对而言SqlSessionFactory的创建还算比较容易理解而SqlSession的执行过程就不那么简单了它包括许多复杂的技术要先掌握反射技术和动态代理这里主要用到的是JDK动态代理。
public class TestMybatis {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            SqlSession session = sqlSessionFactory.openSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.findById(2);
            System.out.println("name:" + user.getName());
            session.close();
            SqlSession session1 = sqlSessionFactory.openSession();
            List<User> users = session1.selectList("findAll");
            session1.commit();
            System.out.println("allSize:" + users.size());
            session1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.1 mybatis 的主要构件

从MyBatis代码实现的角度来看MyBatis的主要的核心部件有以下几个

  • SqlSession              作为MyBatis工作的主要顶层API表示和数据库交互的会话完成必要数据库增改查功能
  • Executor                  MyBatis执行器是MyBatis 调度的核心负责SQL语句的生成和查询缓存的维护
  • StatementHandler   封装了JDBC Statement操作负责对JDBC statement 的操作如设置参数、将Statement结果集转换成List集合。
  • ParameterHandler   负责对用户传递的参数转换成JDBC Statement 所需要的参数,
  • ResultSetHandler    负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
  • TypeHandler            负责java数据类型和jdbc数据类型之间的映射和转换
  • MappedStatement   MappedStatement维护了一条<select|update|delete|insert>节点的封装,
  • SqlSource                负责根据用户传递的parameterObject动态地生成SQL语句将信息封装到BoundSql对象中并返回
  • BoundSql                 表示动态生成的SQL语句以及相应的参数信息
  • Configuration            MyBatis所有的配置信息都维持在Configuration对象之中。

!Snipaste_2023-03-02_11-05-25 1.png

2.2 mybatis 执行过程

!1745215-20201204225139159-906801326 1.png