MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
JDBC编程存在的问题
在此之前我们了解的JDBC的操作为: 1. 首先创建数据库连接池DataSource 2. 通过DataSource获取数据库连接Connection 3. 编写要执行带“?”占位符的SQL语句 4. 通过Connection及SQL创建操作命令对象Statement 5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值 6. 执行SQL语句 7. 处理结果集 8. 释放资源存在问题:
对用不同业务来说,他的CRUD操作类型基本上都是以上的步骤,只有如下部分是不一样的:
- 带占位符的SQL语句
- 替换占位符:一般使用基础类型或Java对象,需要明确替换哪个占位符,哪个值来替换
- 如果是查新。一般会将结果集转换为Java对象,需要提供转换的急Java类型,及与结果集字段的映射关系
可以看出少量的代码真正用于业务功能,大部分的代码都是样板代码。不过,这些样板代码非常重要,清理资源和处理错误确保了数据访问的健壮性,避免了资源的泄露。
解决方案
- 最简单的,涉及工具类提供统一的功能:获取数据库连接,释放资源
- 使用模版设计模式,父类的模板方法提供统一的逻辑,子类提供不同实现。但这部分统一代码逻辑都会比较复杂。
- 更进一步的考虑,其实可以通过 AOP 技术,自动的生成代理类,代理类的方法中织入了统一的样板代码。
框架会采用第三种解决方案,自动的生成样板代码,我们只需要提供 sql ,要替换占位符的数据,返回结果集要转换的 java 类型
ORM框架
ORM(Object Relational Mapping),即对象关系映射。在面向对象编程语言中,将关系型数据库中的数据与对象建立起映射关系,进而自动的完成数据与对象的互相转换:
- 将输入数据(即传入对象)+SQL 映射成原生 SQL
- 将结果集映射为返回对象,即输出对象
ORM 把数据库映射为对象:
数据库表(table)–> 类(class)
记录(record,行数据)–> 对象(object)
字段(field) --> 对象的属性(attribute)
常见的ORM框架
常见的ORM框架有Mybatis和Hibernate
Mybatis
Mybatis是一种典型的半自动的 ORM 框架,所谓的半自动,是因为还需要手动的写 SQL 语句,再由框
架根据 SQL 及 传入数据来组装为要执行的 SQL。其优点为:
- 因为由程序员自己写 SQL,相对来说学习门槛更低,更容易入门。
- 更方便做 SQL的性能优化及维护。
- 对关系型数据库的模型要求不高,这样在做数据库模型调整时,影响不会太大。适合软件需求变更
比较频繁的系统,因此国内系统大部分都是使用如 Mybatis 这样的半自动 ORM 框架。
其缺陷为:
不能跨数据库,因为写的 SQL 可能存在某数据库特有的语法或关键词
Hibernate
Hibernate是一种典型的全自动 ORM 框架,所谓的全自动,是 SQL 语句都不用在编写,基于框架的
API,可以将对象自动的组装为要执行的 SQL 语句。其优点为:
- 全自动 ORM 框架,自动的组装为 SQL 语句。
- 可以跨数据库,框架提供了多套主流数据库的 SQL 生成规则。
其缺点为:
学习门槛更高,要学习框架 API 与 SQL 之间的转换关系
对数据库模型依赖非常大,在软件需求变更频繁的系统中,会导致非常难以调整及维护。可能数据
库中随便改一个表或字段的定义,Java代码中要修改几十处。
很难定位问题,也很难进行性能优化:需要精通框架,对数据库模型设计也非常熟悉。
Mybatis的使用
- 首先创建一个Maven项目 mybatis-study,在pom.xml中引入SpringBoot及Mybatis需要的依赖包,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 默认使用的Spring Framework版本为5.2.10.RELEASE -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>mybatis-study</artifac