1、什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
MyBatis 本是Apache的一个开源项目 iBatis ,2010年这个项目由 Apache Software Foundation 迁移到了Google Code,并且改名为 MyBatis ,三年之后,MyBatis 于 2013年11月迁移到 Github,最终一直扎根于 Github,并开枝散叶,发展壮大。
1.1、什么是持久化?
持久化,可以理解成数据保存在数据库或者硬盘一类可以保存很长时间的设备里面,不像放在内存中那样断电就消失了。
1.2、什么是持久层?
持久层,就是在系统逻辑层面上,专注于实现数据持久化的一个相对独立的领域,是把数据保存到数据库等存储设备中。在Java领域,最常见的持久层框架有两个:Hibernate和MyBatis。
1.3、什么是ORM?
ORM,即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
1.4、为什么要做持久化和ORM设计?
在目前的企业应用系统设计中,一般采用MVC的分层开发模式,即 Model(模型)- View(视图)- Control(控制)为主要的系统架构模式。
MVC 中的 Model 包含了复杂的业务逻辑和数据逻辑,以及数据存取机制,例如 JDBC的连接、SQL生成和Statement创建、还有ResultSet结果集的读取等等。将这些复杂的业务逻辑和数据逻辑分离,可以使系统的紧耦合关系转化为松耦合关系,从而降低系统耦合度,这是持久化要做的工作。
MVC 模式实现了表现层(即View)和数据处理层(即Model)的分离和解耦,而持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。
而ORM 作为持久化设计中的最重要也最复杂的技术,也是目前业界热点技术。
简单来说,按通常的系统设计,使用 JDBC 操作数据库,业务处理逻辑和数据存取逻辑是混杂在一起的。一般基本都是如下几个步骤:
- 1、建立数据库连接,获得 Connection 对象。
- 2、根据用户的输入组装查询 SQL 语句。
- 3、根据 SQL 语句建立 Statement 对象 或者 PreparedStatement 对象。
- 4、用 Connection 对象执行 SQL语句,获得结果集 ResultSet 对象。
- 5、然后一条一条读取结果集 ResultSet 对象中的数据。
- 6、根据读取到的数据,按特定的业务逻辑进行计算。
- 7、根据计算得到的结果再组装更新 SQL 语句。
- 8、再使用 Connection 对象执行更新 SQL 语句,以更新数据库中的数据。
- 7、最后依次关闭各个 Statement 对象和 Connection 对象。
由上可看出,代码逻辑非常复杂,这还不包括某条语句执行失败的处理逻辑。其中的业务处理逻辑和数据存取逻辑完全混杂在一块。而一个完整的系统要包含成千上万个这样重复的而又混杂的处理过程,假如要对其中某些业务逻辑或者一些相关联的业务流程做修改,要改动的代码量将不可想象。
另一方面,假如要换数据库产品或者运行环境也可能是个不可能完成的任务。而用户的运行环境和要求却千差万别,我们不可能为每一个用户每一种运行环境设计一套一样的系统。
所以就要将一样的处理代码即业务逻辑和可能不一样的处理即数据存取逻辑分离开来,另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。所以为解决 这一困难,就出现 ORM 这一个对象和数据之间映射技术。
2、Hibernate和MyBatis的区别
2.1、Hibernate 介绍
Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
2.2、MyBatis 与 Hibernate 的区别
Hibernate 会自动生成SQL 语句,而MyBatis则要求开发者编写具体的SQL 语句。相对Hibernate等全自动ORM机制而言,MyBatis 以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为全自动ORM 实现的一种有益补充,MyBatis 的出现显得别具意义。
3、MyBatis的工作原理
3.1、传统的JDBC编程
JAVA程序通过JDBC链接数据库,这样我们就可以通过SQL对数据库进行编程。JAVA链接数据库大致分为五步,如下所示:
- 1、使用JDBC编程需要链接数据库,注册驱动和数据库信息。
- 2、操作Connection,打开Statement对象。
- 3、通过Statement执行SQL语句,返回结果放到ResultSet对象。
- 4、使用ResultSet读取数据。
- 5、关闭数据库相关的资源。
JDBC 代码示例:
ini
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class JdbcDemo{
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
String username = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
Connection conn = DriverManager.getConnection(url,username,password);
String sql = "insert into t_person values('Tom', 25, '138xxxxxxxx', '北京');";
PreparedStatement pstm = conn.prepareStatement(sql);
int update = pstm.executeUpdate();
System.out.println(update);
pstm.close();
conn.close();
}
}
传统的JDBC方式存在一些弊端:
(1)工作量比较大。我们需要先建立链接,然后处理JDBC底层业务,处理数据类型。我们还需要处理Connection对象,Statement对象和Result对象去拿数据,并关闭它们。
(2)我们对JDBC编程处理的异常进行捕获处理并正确的关闭资源。
3.2、MyBatis工作原理:对JDBC进行了封装
首先我们先了解一下MyBatis的四大核心组件:
- 1、SQLSessionFactoryBuilder(构造器):它会根据配置信息或者代码生成SqlSessionFactory。
- 2、SqlSessionFactory(工厂接口):依靠工厂生成SqlSession。
- 3、SqlSession(会话):是一个既可以发送SQL去执行并且返回结果,也可以获取Mapper接口。
- 4、SQL Mapper:是由一个JAVA接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。SQL是由Mapper发送出去,并且返回结果。
MyBatis工作原理示意图:
从上面的流程图可以看出MyBatis和JDBC的执行时相似的。MyBatis的底层操作封装了JDBC的API,MyBatis的工作原理以及核心流程与JDBC的使用步骤一脉相承,MyBatis的核心对象(SqlSession,Executor)与JDBC的核心对象(Connection,Statement)相互对应。
4、MyBatis的优点
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。MyBatis是对JDBC的封装。相对于JDBC,MyBatis有以下优点:
(1)SQL统一管理,对数据库进行存取操作。
我们使用JDBC对数据库进行操作时,SQL查询语句分布在各个Java类中,这样可读性差,不利于维护,当我们修改Java类中的SQL语句时要重新进行编译。Mybatis可以把SQL语句放在配置文件中统一进行管理,以后修改配置文件,也不需要重新就行编译部署。
(3)生成动态SQL语句。
我们在查询中可能需要根据一些属性进行组合查询,比如我们进行商品查询,我们可以根据商品名称进行查询,也可以根据发货地进行查询,或者两者组合查询。如果使用JDBC进行查询,这样就需要写多条SQL语句。Mybatis可以在配置文件中通过使用<if test=""></if>
标签进行SQL语句的拼接,生成动态SQL语句。
(3)能够对结果集进行映射。
我们在使用JDBC进行查询时,返回一个结果集ResultSet,我们要从结果集中取出结果封装为需要的类型。在Mybatis中,我们可以设置将结果直接映射为自己需要的类型,比如:JavaBean对象、一个Map、一个List等等。