查看原文
其他

从 0 开始手写一个 Mybatis 框架,三步搞定!

Java精选 2022-08-09

最近研究了一下Mybatis,给大家磕叨磕叨,MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出来可扩展,高内聚,低耦合的规范的代码。本文完成的Mybatis功能比较简单,代码还有许多需要改进的地方,大家可以结合Mybatis源码去动手完善。

一、Mybatis框架流程简介

在手写自己的Mybatis框架之前,我们先来了解一下Mybatis,它的源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,才能够更深入的理解源码。

我们对上图进行分析总结:

1、mybatis的配置文件有2类

a)mybatisconfig.xml,配置文件的名称不是固定的,配置了全局的参数的配置,全局只能有一个配置文件。

b)Mapper.xml 配置多个statemement,也就是多个sql,整个mybatis框架中可以有多个Mappe.xml配置文件。

2、通过mybatis配置文件得到SqlSessionFactory

3、通过SqlSessionFactory得到SqlSession,用SqlSession就可以操作数据了。

4、SqlSession通过底层的Executor(执行器),执行器有2类实现:

a) 基本实现

b)带有缓存功能的实现

5、MappedStatement是通过Mapper.xml中定义statement生成的对象。

6、参数输入执行并输出结果集,无需手动判断参数类型和参数下标位置,且自动将结果集映射为Java对象

a)HashMap,KV格式的数据类型

b)Java的基本数据类型

c)POJO,java的对象

二、梳理自己的Mybatis的设计思路

根据上文Mybatis流程,我简化了下,分为以下步骤:

1.读取xml文件,建立连接

从图中可以看出,MyConfiguration负责与人交互。待读取xml后,将属性和连接数据库的操作封装在MyConfiguration对象中供后面的组件调用。本文将使用dom4j来读取xml文件,它具有性能优异和非常方便使用的特点。

2.创建SqlSession,搭建Configuration和Executor之间的桥梁

我们经常在使用框架时看到Session,Session到底是什么呢?一个Session仅拥有一个对应的数据库连接。类似于一个前段请求Request,它可以直接调用exec(SQL)来执行SQL语句。从流程图中的箭头可以看出,MySqlSession的成员变量中必须得有MyExecutor和MyConfiguration去集中做调配,箭头就像是一种关联关系。我们自己的MySqlSession将有一个getMapper方法,然后使用动态代理生成对象后,就可以做数据库的操作了。

3.创建Executor,封装JDBC操作数据库

Executor是一个执行器,负责SQL语句的生成和查询缓存(缓存还没完成)的维护,也就是jdbc的代码将在这里完成,不过本文只实现了单表,有兴趣的同学可以尝试完成多表。

4.创建MapperProxy,使用动态代理生成Mapper对象

我们只是希望对指定的接口生成一个对象,使得执行它的时候能运行一句sql罢了,而接口无法直接调用方法,所以这里使用动态代理生成对象,在执行时还是回到MySqlSession中调用查询,最终由MyExecutor做JDBC查询。这样设计是为了单一职责,可扩展性更强。

三、实现自己的Mybatis

工程文件及目录:

首先,新建一个maven项目,在pom.xml中导入以下依赖:

创建我们的数据库xml配置文件:

然后在数据库创建test库,执行如下SQL语句:

创建User实体类,和UserMapper接口和对应的xml文件:

基本操作配置完成,接下来我们开始实现MyConfiguration:

用面向对象的思想设计读取xml配置后:

接下来实现我们的MySqlSession,首先的成员变量里得有Excutor和MyConfiguration,代码的精髓就在getMapper的方法里。

紧接着创建Executor和实现类:

MyExecutor中封装了JDBC的操作:

MyMapperProxy代理类完成xml方法和真实方法对应,执行查询:

到这里,就完成了自己的Mybatis框架,我们测试一下:

执行结果:

查询一个不存在的用户试试:

到这里我们就大功告成了!

作者:K'illCode

blog.csdn.net/Dome_/article/details/86525476

往期精选

Spring Boot集成 Sharding-jdbc + Mybatis-Plus 数据库中间件完美解决分库分表问题

安全框架 Spring Security 如何实现 rememberMe 自动登录

IntelliJ IDEA 中集成 SonarLint 代码规范与质量检测插件

从零开始,开发一款属于自己的 IDEA 插件,要啥功能就做啥!

MySQL 表之间关联查询时,为什么建议小表驱动大表?

Redisson 是如何实现分布式锁的?

ElasticSearch 的基本概念和集群分布式底层实现

为什么阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?

学会 IDEA REST Client 后,Postman就可以丢掉了...

Java 中回调机制,这篇文章解读的明明白白!

Java 程序员面试 10 大“潜规则”,千万不要踩坑!

点个赞,就知道你“在看”!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存