浅谈对Mybatis的理解

一、Mybatis的概述

      MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,由谷歌托管,并且改名为MyBatis 。2013年11月迁移到Github。

        MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML格式或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

Mybatis的特点:

    1、简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

    2、灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

    3、解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

    4、提供映射标签,支持对象与数据库的orm字段关系映射

    5、提供对象关系映射标签,支持对象关系组建维护 6、提供xml标签,支持编写动态sql。

Mybatis的功能架构分为三层:

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

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

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

浅谈对Mybatis的理解_第1张图片

使用jdbc问题总结 

  jdbc程序

    浅谈对Mybatis的理解_第2张图片

浅谈对Mybatis的理解_第3张图片浅谈对Mybatis的理解_第4张图片浅谈对Mybatis的理解_第5张图片 

jdbc问题总结如下:

    1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    2、Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。 

    3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。

    4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

jdbc编程步骤

   1、加载数据库驱动

   2、 创建并获取数据库链接

   3、 创建jdbc statement对象

   4、 设置sql语句

   5、 设置sql语句中的参数(使用preparedStatement)

   6、 通过statement执行sql并获取结果

   7、 对sql执行结果进行解析处理

   8、 释放资源(resultSet、preparedstatement、 connection)

Mybatis框架架构及运行原理

    MyBatis作为持久层框架,其主要思想是将程序中的大量sql语句剥离出来,配置在配置文件中,实现sql的灵活配置。这样做的好处是将sql与程序代码分离,可以在不修改程序代码的情况下,直接在配置文件中修改sql。

Mybatis运行原理:

   (1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

   (2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。

  (3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。

  (4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。

Mybatis运行总体流程

     (1)加载配置并初始化 触发条件:加载配置文件 处理过程:将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

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

   (3)处理操作请求 触发条件:API接口层传递请求过来 传入参数:为SQL的ID和传入参数对象 处理过程:

           (A)根据SQL的ID查找对应的MappedStatement对象。

           (B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

          (C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

          (D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

         (E)释放连接资源。

    (4)返回处理结果将最终的处理结果返回。

操作users表的CRUD

   当执行CRUD操作时, insert、delete、update都执 行正常,但是,select查不到 数据,原因是实体类中没有提 供无参构造函数。没有提供任 何构造函数时,系统会提供一 个默认的无参构造函数,但是, 当提供了有参构造函数时,系统 就不会提供,需要显式的定义。

动态SQL

     MyBatis 最强大的特性之一就是它的动态语句功能。如果以前有使用JDBC或者类似框架的经历,就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。

    MyBatis确实能通过在任何映射SQL语句中使用强大的动态SQL来改进这些状况。动态SQL元素对于任何使用过JSTL或者类似于XML之类的文本处理器的人来说,都是非常熟悉的。在上一版本中,需要了解和学习非常多的元素,但在MyBatis 3 中有了许多的改进,现在只剩下差不多二分之一的元素。MyBatis使用了基于强大的OGNL表达式来消除了大部分元素。

MyBatis中可用的动态SQL标签

   if 

   choose(when,otherwise)

   trim(where,set)

   foreach

二、Mybatis缓存

    正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持

      1.一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。

       SqlSession级别的缓存,缓存数据存储在HashMap中,在进行第一次查询时,首先会从数据库中查询出结果,然后将结果存在一级缓存中;当我们第二次查询时,首先会查询一级缓存,如果一级缓存没有在查询数据库。在进行CUD操作并执行了commit或关闭Sqlsession后会将缓存清空,如果二级缓存是开启的那么会将数据缓存到二级缓存中。默认一级缓存是开启的。

      2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache(EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点)。

       Mapper级别的缓存,拥有多个SqlSession,执行同一Mapper中的SQL语句,数据也存储在HashMap中,并且每个SqlSession中的缓存内容共享。Java类若要使用二级缓存则需要实现Serializable接口。

     在进行第一次查询时,首先会从数据库中查询出结果,然后将结果存在二级缓存中;当我们第二次查询时,先在二级缓存中查询,没有就查询一级缓存,最后才会进行数据库的查询。在进行CUD操作并执行了commit,缓存会被清空,默认不开启,开启需要在配置文件中设置“

    3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

   补充:

      1. 映射语句文件中的所有select语句将会被缓存。

      2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。

      3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

      4. 缓存会根据指定的时间间隔来刷新。

      5. 缓存会存储1024个对象

你可能感兴趣的:(mybatis)