Mybatis作为一款优秀的持久层框架,在各大互联网公司占据了重要地位,相信你在日常工作中或多或少都接触过,但是如果让我们说个一二却又无从下手。本系列文章将从0开始构建Mybatis知识体系,分别从基本使用篇、架构原理篇、源码分析篇、成神篇(根据源码实现简易版Mybatis)来击破Mybatis各个细节。希望本系列文章完结之后我们对Mybatis有一个深刻的认识。
一、传统JDBC操作数据库
在没有Mybatis或者其他的持久层框架以前我们都是使用原生JDBC来进行数据库操作,具体源码如下:
@Test
public void jdbcHandle() throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// A. 加载驱动,可以省略此步骤,如果省略则默认加载驱动包下的
// META-INF/services/java.sql.Driver的内容具体分析见
// 《JVM系列之类加载器》
Class.forName("com.mysql.jdbc.Driver");
// B. 获取connection
connection = DriverManager.getConnection(
"jdbc:mysql://127.0.0.1:3306/mybatis_learn",
"root",
"123456"
);
// C. 定义sql
String sql = "select * from user";
// D. 获取预编译对象
preparedStatement = connection.prepareStatement(sql);
// E. 执行sql
resultSet = preparedStatement.executeQuery();
// F. 遍历结果集
while (resultSet.next()) {
String userName = resultSet.getString("name");
System.out.println("userName::" + userName);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// G. 释放资源
if (null != preparedStatement) {
preparedStatement.close();
}
if (null != connection) {
connection.close();
}
}
}
1. 传统JDBC存在的问题:
我们通过上面的代码大概可以知道,原始JDBC操作数据库大概要分为A~G,7个步骤,在这七步中存在以下问题:
- A、B步骤存在硬编码问题,数据库的连接信息和数据库驱动类写死在代码中;获取数据库连接资源频繁,每次都要开启新的连接导致资源浪费
- C、D、E步骤存在SQL硬编码问题,每次改动SQL都需要重新编译代码;如果SQL语句有参数还需要手动设置参数
- F步骤需要手动设置返回参数
- G步骤需要开发人员手动释放连接资源
2. 传统JDBC问题解决思路:
抛开市面上已有的一些持久层框架,单从解决问题的角度出发,针对原生JDBC操作数据库存在的以上问题我们可以思考用以下方案来解决:
- 数据库信息硬编码:我们可以采用配置文件的方式,将数据库信息和代码分离
- 数据库连接资源浪费:可以采用通用的“池化资源”的方法解决,创建数据库连接池,反复利用连接资源
- SQL语句硬编码:同样跟数据库配置信息一样采用配置文件
- 手动设置请求参数与响应结果集:采用反射或者内省的方式
- 在这里我们只是提出了一种解决思路,具体如何实现,每一个开源框架或者个人思考都会不同,接下来我们就看看Mybatis是如何解决这些问题的
二、Mybatis基本概念
1. 对象、关系映射(ORM):
在介绍Mybatis之前我们必须先了解一个概念,那就是ORM:ORM全称Object Relation Mapping: 表示对象关系映射的缩写,ORM完成面向对象的编程语言到关系数据库的映射。当ORM框架完成映射后,开发者可以利用面向对象的简单易用性,又可以利用关系数据库的优势,进行数据库操作。即ORM框架是面向对象设计语言和数据库发展不同步的中间解决方案。
2. Mybatis介绍:
Mybatis是一款优秀的基于ORM的半自动、轻量级持久层框架。它支持定制化SQL、存储过程以及高级映射。Mybatis可以使用简单的XML或者注解来配置生成原生类、接口、POJO(Plain Old Java Object, 普通老式Java对象)来映射数据库中的记录。
3. Mybatis的特点:
Mybatis是一个半自动化的持久层框架。对开发人员而言,核心SQL还需要自己优化。SQL和Java编码分开,功能边界清晰,一个专注于业务,一个专注于数据。
半自动化正是Mybatis与Hibernate等完全ORM框架的不同,现在有的开发人员为了不编写SQL使用了Mybatis Generator生成的各种Example查询,其实在笔者看来这是违背了Mybatis的最初设计宗旨。这里例举几个笔者认为Example的不优雅之处(个人观点):
- 违背了Mybatis的半自动ORM框架设计初衷
- SQL语句完全交给Example,放弃了SQL语句调优的可能性,容易出现性能问题
- 持久层代码繁琐、冗余,代码侵入性大,其实大多数持久层几乎可以不用写一行代码
- 抛弃手写xml并不代表抛弃xml,其实Mybatis mapper.xml方式有很多高级功能,比如sql片段,动态sql等,我们完全可以托管给generator生成简单xml,这个之后会具体介绍
三、快速入门
1. Mybatis开发文档:
Mybatis官方网址:https://mybatis.org/mybatis-3/ ,访问官方网址之后我们可以切换为中文进行查阅

2.添加Mybatis相关依赖:
我们项目采用Maven来进行管理,所以这里需要引入Mybatis相关依赖、数据库连接驱动、单元测试Junit,完整依赖如下:
<properties>
<!-- 设置编码以及Java编译环境 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql 连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3. 创建用户数据库表 && POJO:
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `mybatis_learn`.`user`(`id`, `name`) VALUES (1, '小明');
INSERT INTO `mybatis_learn`.`user`(`id`, `name`) VALUES (2, '小红');
INSERT INTO `mybatis_learn`.`user`(`id`, `name`) VALUES (3, '小李子');
public class User {
private Long id;
private String name;
// get、set方法
...
}
4. 创建sql映射文件UserMapper.xml:
UserMapper.xml中配置了Mybatis与数据库操作的SQL语句,在resources包下创建UserMapper.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace: 命名空间,与sql id组成唯一标识 -->
<mapper namespace="user">
<!-- resultType:返回值类型 -->
<select id="selectList" resultType="com.polar.pojo.User">
select * from user
</select>
</mapper>
5. 创建Mybatis核心配置文件sqlMapConfig.xml:
sqlMapConfig.xml是Mybatis的核心配置文件,里面配置了环境信息、数据源、事务等信息。后面会详细介绍,这里只需要知道这是Mybatis最核心的配置文件。在resources包下创建sqlMapConfig.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置不同的环境: 比如dev、qa、pro -->
<environments default="dev">
<environment id="dev">
<!-- 事务管理器:当前事务交给JDBC事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据源:POOLED-使用Mybatis提供的连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_learn?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 引入sql配置文件 -->
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>
6. 编写测试类:
public class MybatisTest {
@Test
public void test1() throws IOException {
// 读取核心配置文件
InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 创建session工厂 builder设计模式
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
// 创建session, 工厂设计模式
SqlSession session = sqlSessionFactory.openSession();
// 查询user list user.selectList = namespace + sqlId
List<User> list = session.selectList("user.selectList");
list.forEach(user -> System.out.println(user.getId() + "::" + user.getName()));
session.close();
}
}
// 测试结果
1::小明
2::小红
3::小李子
下一章节我们继续分享如何利用Mybatis进行数据库的增、删、改、查操作,敬请期待~
四、自述
一入码农深似海,再回头是百年身。笔者平时热爱技术,喜欢分享,探讨技术问题,有兴趣的伙伴可以关注笔者技术公共号,共同探讨技术问题~


1531

被折叠的 条评论
为什么被折叠?



