MyBatis源码解析(一)介绍和搭建源码环境

发布时间:2020/04/12| 阅读:

前言

之前阅读了JDK常用容器的源码本章就开始阅读Mybatis源码。不过在阅读之前我们首先搭建一下源码阅读环境,这样有利于我们后面的阅读,更加可以一边写注释一边的Debug。

MyBatis介绍

首先我们先介绍一下MyBatis是什么,如果你比较熟悉的话可以跳过前面的部分。
本章主要概念

  • 什么是Mybatis
  • 为什么要用Mybatis
  • 如何使用mybatis
  • mybatis源码环境搭建

    介绍

    MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。同时Mybatis前身是 iBatis,iBatis 是 Apache 软件基金会下的一个开源项目。2010 年该项
    目从 Apache 基金会迁出,并改名为 MyBatis。同期,iBatis 停止维护。知道了这些之后我们就有一个问题,到底为什么要使用MyBatis

    为什么用Mybatis

    在实际的开发中我们可以使用JDBC来访问数据库,还可以使用Hibernate来访问我们的数据库,除此之外还有很多方案可以选择,那么我们为什么要使用Mybatis呢?
    我们使用JDBC和Mybatis拿来举个例子,来看一下各自的应用场景。本次项目地址‘’‘’‘’‘’‘’‘’‘’‘’‘’,这是已经整合的一套源码阅读环境,卡下来导入IDEA即可使用,同时本文中的例子也在项目中。

    JDBC连接

    创建数据库表
    create table test.student (
          id int(10),
          name varchar(20),
          primary key (id)
    )
    insert添加语句这里就不再贴了,读者可以自行添加数据。

    使用JDBC我们就不使用Model类进行演示了,然后链接数据库执行sql语句
    @Test
    public void testJDBC(){
      Connection conn = null;
      Statement stmt = null;
      try {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql://miniapp.lqcoder.com:3306/test","root","123456");
        // 执行查询
        stmt = conn.createStatement();
        String sql;
        sql = "select * from test.student";
        ResultSet rs = stmt.executeQuery(sql);
        // 展开结果集数据库
        while(rs.next()){
          // 通过字段检索
          int id  = rs.getInt("id");
          String name = rs.getString("name");
          // 输出数据
          System.out.print("ID: " + id);
          System.out.print("名称: " + name);
          System.out.print("\n");
        }
        // 完成后关闭
        rs.close();
        stmt.close();
        conn.close();
      } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
      }finally{
        // 关闭资源
        try{
          if(stmt!=null) stmt.close();
        }catch(SQLException se2){
        }// 什么都不做
        try{
          if(conn!=null) conn.close();
        }catch(SQLException se){
          se.printStackTrace();
        }
      }
    }
    输出结果:

    ID: 1名称: xiaoming
    ID: 2名称: xiaozhang

    使用Mybatis

    由于我们这里是在源码中使用的查询所以不需要添加Mybatis依赖。
    首先创建mybatis的配置文件,新建一个mybatis-config.xml文件,添加以下配置配置后期会详细解释,这里只做一个演示,在下篇文章会详细的讲解整合SpringBoot

    然后创建model类,这里使用了lombok来简化开发,可以自行了解一下。

    创建mapper文件

    创建 dao接口

    然后在 mybatis-config.xml配置文件中加入MapperXml文件的路径

    完整配置

    然后创建测试方法

    查询结果:

对比

接下来总结一下上面两种方式。因为在Java中我们访问数据库,有多种选择方案最原始的就是使用 JDBC或是通过Spring 提供的JdbcTemplate 访问数据库也可以使用Hibernate,但是为什么要使用Mybatis呢?
我们可以看一下上面使用JDBC访问数据库的步骤:

  • 加载驱动类
  • 创建数据库连接
  • 创建Statement
  • 执行SQL
  • 处理SQL执行结果
  • 关闭连接
    但是核心步骤就只有两个分别是执行SQL和处理SQL结果,从开发来说我们只需要关心这两个步骤,一个简单的查询就需要写一大堆的代码来进行连接,处理什么的特别麻烦,有人会说了那为啥不把上面重复的代码进行封装,对外仅暴露SQL执行和处理结果呢?这样当然是可以的,但是对比Mybatis来说并不是因为比较繁琐才不去使用JDBC的,刚刚也看到了使用Mybatis的话也是比较麻烦饿需要进行配置,还要创建XML文件,还要进行绑定。同样如果一个大型的项目使用Mybatis的话有多少Dao接口就要有多少XML文件,维护起来也很麻烦。

    真正的问题

第一个问题就是我们使用JDBC的时候是需要对SQL进行拼接的,很容易就会导致拼接错误,比如多个符号少个逗号的问题第二个问题也是最知名的问题,就是要把SQL写到代码中,这样如果想要改动一下SQL就需要修改代码,同时也会降低代码的可读性,可维护性,从任何角度来说都非常致命。拼接SQL的问题也是有解决的方案使用PreparedStatement可以解决拼接问题,同时也可以解决SQL注入问题,但是后者是解决不了的。
同时现在看一下JDBC在处理查询结果的时候,需要手动从 ResultSet 中取出数据然后在进行处理,上方的例子仅仅使用了两个属性,如果是有很多属性想想就头大

为什么使用Mybatis

接下来就是为什么要使用mybatis,因为使用mybatis也是同样的麻烦,Dao层多了也是存在维护性相关的问题。想要维护的话需要付出很大的代价。想要查询数据库同样也是需要很多步骤

首先看一下mybatis的步骤

  • 读取配置文件
  • 创建 SqlSessionFactoryBuilder 对象
  • 创建SqlSessionFactory
  • 通过 SqlSessionFactory 创建 SqlSession
  • 为 Dao 接口生成代理类
  • 调用接口方法访问数据库
    如果每次都需要执行这些步骤的话那它和JDBC没啥区别,而且一点优势都没有。然而并不是,这里参考官方文档
    SqlSessionFactoryBuilderSqlSessionFactory 以及 SqlSession 等对象 的作用域和生命周期是不一样的。SqlSessionFactoryBuilder主要用于构建SqlSessionFactory工厂类,用完就可以抛弃。但是SqlSessionFactory一旦被创建 就应该在应用运行期间一直存在,不应该丢弃或重建。同时SqlSession 不是线程安全的,不能在多线程中共享,用完即销毁按照自己的需求创建。
    以上步骤中,读取配置和创建SqlSessionFactoryBuilder,构建SqlSessionFactory只需要进行一次第 4 和第 5 步需要进行多次创建。最后一步是必须的。同时也把SQL语句和代码进行了拆分,提高看可读性,同时mybatis对查询结果进行了映射,无需在手动处理ResultSet

    总结

    对于JDBC来说每一步都是必须的,至于 MyBatis,它是构建在 JDBC 技术之上的, 对访问数据库的操作进行了简化,方便用户使用。JDBC可以看作是一种基础服务,MyBatis则是在基础服务上面的框架他们的目标不同。使用Mybatis不仅简化了传统JDBC访问繁琐的问题,还解决了SQL语句与代码的高耦合的问题,同样的也有就是对结果集处理的问题(Mybatis对结果进行了映射)

    搭建源码环境

    上面介绍了mybatis是什么、为什么使用、和怎么使用接下来就开始搭建源码环境,同时上面的例子只是简单的使用一下mybatis下文将对mybatis进行整合看一下在项目中怎么使用。
    首先我们打开仓库地址

    https://github.com/mybatis/mybatis-3

    把项目clone下来,然后在拉取parent项目parent中主要就是一些环境依赖。
    https://github.com/mybatis/parent.git

    创建文件夹mybatissource,其中包含我们刚刚拉取的项目

    然后打开IDEA点击File>open然后找到mybatissource文件夹📁,选择mybatissource点击打开

    找到Pom文件


    等待依赖加载完毕即可
    完整项目目录

    然后打开Mybatis-3项目在项目src下可自行创建目录

注意测试需要使用junit进行测试

以上就搭建好了源码阅读环境,你
也可以自行发挥。
同时不建议直接在实际项目中进行debug查询,最好搭建一个源码环境,这样可以一遍debug一遍写笔记。便于后期复习

参考


📚相关文章