揭秘Mybatis(一)_Mybatis架构

引:从JDBC到Hibernate再到Mybatis,你可能会使用很多框架,但是你却不知道框架为你解决什么了或是不知道它的整个架构,我们这里就是帮你解决这些问题!

为什么要使用Mybatis

JDBC的使用

每一个人学Java的数据库操作应该都是从JDBC开始,它基本有以下7个步骤:

  1. 加载JDBC驱动
  2. 建立并获取数据库连接
  3. 创建 JDBC Statements 对象
  4. 设置SQL语句的传入参数
  5. 执行SQL语句并获得查询结果
  6. 对查询结果进行转换处理并将处理结果返回;
  7. 释放相关资源(关闭Connection,关闭Statement,关闭ResultSet);

JDBC相应的问题

  1. 数据库连接频繁的开启和关闭本身就造成了资源的浪费,影响系统的性能
  2. SQL语句基本都散落在各个JAVA类中可读性很差,不利于维护以及做性能调优。
  3. 在后台代码中自己需要根据请求的传入参数(参数个数和顺序都不确定)去拼凑相应的SQL语句。
  4. 执行SQL语句后,返回的是一个ResultSet结果集,这个时候我们就需要将ResultSet对象的数据取出来,不然等到释放资源时就取不到这些结果信息了。
  5. SQL重复的问题,不利于维护和复用。

Mybatis相应的解决

  1. 数据库连接的获取和关闭我们可以使用数据库连接池来解决资源浪费的问题。通过连接池就可以反复利用已经建立的连接去访问数据库了。减少连接的开启和关闭的时间。(数据库连接池以及数据源的配置)
  2. 将这些SQL语句统一集中放到配置文件或者数据库里面(以key-value的格式存放)。然后通过SQL语句的key值去获取对应的SQL语句。(Mapper文件)
  3. 使用一种有别于SQL的语法来嵌入变量(比如使用#变量名)。这样,SQL语句经过解析后就可以动态的生成符合上下文的SQL语句。(Mapper文件里面的SQL语句)
  4. 将结果不做任何处理就直接返回,也有可能将结果转换成一个JavaBean对象返回、一个Map返回、一个List返回等,而且可以将SQL语句和传入参数两部分合起来可以作为数据缓存的key值。(语句标签返回结果的配置)
  5. 将重复的代码抽离出来成为独立的一个类,然后在各个需要使用的地方进行引用(SQL代码块)

Mybatis架构

mybatis

这张图超级棒,可以在后面的参考找到出处。我们就按照这个4层进行分析:

接口层

接口调用方式主要有以下两种:

  1. 基于StatementId(命名空间+语句id),范例如下:

    1
    List<?>|int|void sqlSession select|update|delete|insert(statementId,params)
  2. 基于Mapper接口

    MyBatis 将配置文件中的每一个 节点抽象为一个 Mapper 接口,这个接口中声明的方法和 节点中的 节点项对应,即 节点的id值为Mapper 接口中的方法名称,parameterType 值表示Mapper 对应方法的入参类型,而resultMap 值则对应了Mapper 接口表示的返回值类型或者返回结果集的元素类型。范例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <mapper namespace="com.todorex.UserMapper">
    <select id="selectList" resultType="com.todorex.User">
    select * from user
    </select>
    </mapper>

    public interface UserMapper {

    List<User> selectList();

    }

    根据MyBatis 的配置规范配置好后,通过SqlSession.getMapper(UserMapper.class)方法,MyBatis会根据相应的接口声明的方法信息,通过动态代理机 制 生成一个Mapper 实例,我们调用Mapper接口的某一个方法时,MyBatis会根据这个方法的方法名和参数类型,确定StatementId,底层还是通过StatementId来实现对数据库的操作,MyBatis引用Mapper接口这种调用方式是为了满足面向接口编程的需 要。(其实还有一个原因是在于,面向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件)

数据处理层

数据处理层可以说是MyBatis的核心,它要完成两个功能:

  1. 通过传入参数构建动态SQL语句

    MyBatis 通过传入的参数值,使用 OGNL表达式 来动态地构造SQL语句,使得MyBatis有很强的灵活性和扩展性。参数映射指的是对于java 数据类型和jdbc数据类型之间的转换:这里有包括两个过程:

    1. 查询阶段,我们要将java类型的数据,转换成jdbc类型的数据,通过 preparedStatement.setXXX() 来设值
    2. 返回阶段,我们要对resultset查询结果集的jdbcType 数据转换成java 数据类型
  2. SQL语句的执行以及封装查询结果集成List

    动态SQL语句生成之后,MyBatis 将执行SQL语句,并将可能返回的结果集转换成List 列表。MyBatis 在对结果集的处理中,支持结果集关系一对多和多对一的转换,并且有两种支持方式,一种为嵌套查询语句的查询,还有一种是嵌套结果集的查询。

框架支持层

  1. 事务管理机制

    事务管理机制对于ORM框架而言是不可缺少的一部分,事务管理机制的质量也是考量一个ORM框架是否优秀的一个标准。

  2. 连接池管理机制

    由于创建一个数据库连接所占用的资源比较大,对于数据吞吐量大和访问量非常大的应用而言,连接池的设计就显得非常重要。

  3. 缓存机制
    为了提高数据利用率和减小服务器和数据库的压力,MyBatis 会对于一些查询提供会话级别的数据缓存,会将对某一次查询,放置到SqlSession 中,在允许的时间间隔内,对于完全相同的查询,MyBatis会直接将缓存结果返回给用户,而不用再到数据库中查找。

  4. SQL语句的配置方式
    传统的MyBatis 配置SQL语句方式就是使用XML文件进行配置的,但是这种方式不能很好地支持面向接口编程的理念,为了支持面向接口的编程,MyBatis 引入了Mapper接口的概念,面向接口的引入,对使用注解来配置SQL语句成为可能,用户只需要在接口上添加必要的注解即可,不用再去配置XML文件了,但是,目前的MyBatis 只是对注解配置SQL语句提供了有限的支持,某些高级功能还是要依赖XML配置文件配置SQL 语句。

引导层

引导层是配置和启动MyBatis配置信息的方式。MyBatis 提供两种方式来引导MyBatis:

  • 基于XML配置文件的方式

  • 基于Java API 的方式

范例可以查看官方使用手册:Mybatis官方使用手册

参考

  1. 终结篇:MyBatis原理深入解析(一)