前言:
mybatis是一个半自动的ORM框架,用于实现面向对象编程语言里的不同类型系统的数据之间转换。那么我们怎么实现一个mybatis一个框架,首先我们对mybatis要有一个深刻的认识,底层源码以及底层原理有个熟悉的掌握,那么我先说一下mybatis的大致执行流程:
我们要执行的话,首先要将磁盘上的xml文件,读到内存中,通过java文件去解析。首先通过输入
流从磁盘上读取,通过SqlSessionFactoryBuilder的build方法读取流,并创建SqlSessionFactory
对象,SqlSessionFactory对象的openSession方法创建sqlSession对象,再通过SqlSession对象
执行数据库增删改查,这是最基本的操作。
接下来再分析一下底层的整个原理:
首先通过SqlSessionBuilder方法里的parse方法解析Configuration文件,然后通过该类的build的方
法去创建SqlSessionFactory工厂,然后再创建SqlSession对象,再通过SqlSessionFactory的
openSession()方法去创建SqlSession对象。获取执行器Executor,这是真正执行sql语句的
执行器。然后在执行器里面执行一级、二级缓存,以及一级缓存是在BaseExecutor执行,二级
缓存时是通过CachingExecutor类执行器执行的,默认一级缓存是开启的,是SqlSession级别的。
二级缓存是默认关闭的,需要在配置文件中配置CacheEnabled=true,二级缓存开启。通过执行器之
后,我们在StatementHandler中的获取Sql语句,执行Sql语句,通过执行器去执行。然后再在
ResultSetHandler中获取执行结果,返回结果集。
接下来我们就开始实行真正的的手写mybatis,然后我们就根据上面的思路进行:
- 首先创建一个session包里面创建SqlSession接口,接口里面写执行sql语句的执行器,两个
2.再创建一个SqlSession实现类DefaultSqlSession类:
在这个类里面,写个配置类的属性Configuration类的属性和Executor执行器类的属性。封装getter方法。默认的构造方法。我们是否还记得,mybatis的sql语句是如何生成的呢?通过MapperMethod方法里面封装两个属性一个String的sql属性和要入参的类型Class type.生成getter和setter方法。
3.再创建一个binding包,里面创建三个类,MapperMethod、MapperProxy,
MapperRegistry。
我们再分别看一下这几个类如何实现:
上面就是MapperMethod类的实现,里面一个是sql语句,一个是入参类型。
下面我们再看MapperRegisitry类,里面封装了一个Map集合,我们最终将Mapper注册到了Map集合中。
然后我们再看这个MapperProxy代理类实现InvocationHandler类,这个类最终执行的是生成代理对象,
在这个方法里面实现了invoke方法,在invoke方法里创建了method1对象,判断Mappermethod对象是否为空,如果不为空的话,执行查询操作,返回值method.invoke(proxy,args)传入代理对象,和参数值,创建mapper实例。
进行到这里,其实我们还没有执行完毕,其实我们还得执行器去包装,所以说我们还得用执行器,我们上面传参传入了Executor.所以说这里我们创建执行器,先创建一个包executor,里面创建Executor和SimpleExecutor接口和实现类的执行器,下图:
里面是一个query方法,参数是MapperMethod对象和入参类型parameter.里面创建了一个StatementHandler对象,然后再调用StatementHandler对象的query方法。其实这两个接口的方法都一样,只不过又进行了一层包装。然后再在executor包下创建一个包statement,包里面写创建一个接口StatementHandler和一个实现类SimpleStatementHandler,在这个实现类里面进行执行操作数据库的最终执行。
上图我们看到了执行数据库的PreparedStatement类的预编译执行。操作数据库。饭hi结果集。然后我们再在executor包下创建resultset包,里面创建执行一个接口ResultSetHandler和实现类DefaultResultSetHandler,在这个类里面返回查询的结果集。如下图:
最终返回结果,这就是我们整个mybatis底层实现的一个原理以及底层代码如何实现的。
上面我们讲到需要用到Configuration类,所以要在session包下创建Configuration类,mybatis主类,然后再创建一个工厂类和工厂的构建类:SqlSessionFactory和SqlSessionFactoryBuilder类。如下:
在SqlSessionFactoryBuilder类中获取流,操作。
接下来我们进行测试:
然后我们测试的时候就和我们平时的一样了,通过流加载主配置文件,通过SqlSessionFactoryBuilder类来解析配置文件,获取SqlSessionFactory工厂,通过工厂的openSession方法获取SqlSession对象。执行结果的获取。至此我们的整个流程就到此结束了。
但是我们还要注意两个点:
1.主配置文件mybatis.xml文件和Mapper.xml文件都不要dtd文件:
如上图不需要加命名空间和dtd文件
到此,这就是我对mybatis的一个整体认识。如要源码可以评论留言。自己也是一个转换过来的程序员,希望大佬们不要喷。后面我会慢慢分享一些我学习的干活,望大家多多参与噢!