简单了解Mybatis

来源:互联网 发布:开淘宝上卖花卉好赚吗 编辑:程序博客网 时间:2024/04/29 17:27

                来公司已有一段时间,公司在持久层选用的框架是Mybatis,这个框架的使用很简单,这里就不讲了,这篇主要讲讲Mybatis我们需要知道的几个点。

              做为一个ORM框架,Mybatis学习成本很低,相比同类框架例如Hibernate更容易上手。ORM:Object Relation Mapping,本质上是一种思想,主要完成抽象数据到实体对象的转化,是一种面向对象的思想。所有的ORM框架都是为了解决数据库记录与业务对象的映射,帮助业务层与数据库完成交互。

              1.Mybatis能做到的事情,JDBC都能,为什么还要用Mybatis?

             这应该是刚使用Mybatis的同学经常会提出的一个疑问。在项目比较小的情况下,确实二者区别不大,可是项目业务一复杂你会发现,使用   JDBC会让操作数据库的代码混杂在业务代码中,且每次操作数据库都需要手动的建立连接,释放资源等一系列必须的操作,不说别的,单就建立连接、释放连接这一组操作就会很耗时,这对QPS比较高的服务来说,这很低效。如果有时忘了手动释放数据库链接那就更致命了,轻则频繁触发gc,重则可能会内存泄漏最终导致服务崩溃,这都是有可能的。 (当然,一般jdbc在实际应用时都会使用数据库连接池来解决数据库连接的使用效率问题。虽然使用数据库接连池解决了建立连接、释放连接的低效问题,但也得手动释放数据库连接。) 

              上面说完了JDBC不好的地方,我们来看看Mybatis相比有哪些优点:a) 解藕:Mybatis的sql语句都是写在配置文件中,这样大大降低了DAO层代码的复杂性,特别是当Mybatis与Spring结合起来,我们只需定义接口,这样做,完成了业务代码与sql语句的解藕,有利于项目的维护。b)sql的优化:Mybatis写在配置文件中的sql都是原生sql,这很方便sql语句的优化,特别是互联网公司,QPS比较高的服务都很注重sql的优化,这就要求框架对数据库有很强的可控性。使用过Hibernate的同学可能深有体会,因为Hibernate对sql封装的很到位,所以sql语句在DAO层出现的很少,这从sql调优的角度讲,很不方便。当然,Hibernate也很强大,只是二者适用场景不同,Hibernate在类似ERP的企业级项目中应用很广泛。  


2. Mybatis解藕了业务与数据库操作,只需将sql写在配置文件中,特别是与Spring结合的时候,只需用定义接口即可,那么, 

Mybatis是如何做到这一点的呢?

Github上Mybatis的项目:https://github.com/mybatis/mybatis-3/ 我们把它拉到本地,直接看代码,通过写注释来讲解。

2.1.当没有与Spring整合时,我们使用mybatis操作数据库,一般需要先拿到SqlSession,如下。

             分三步:

a)首先需要加载配置文件,得到文件的流。

b) SqlSessionFactoryBuilder类的build方法加载配置文件,将配置加载到内存中也就是configuration对象中,

build方法主要干了这件事:

          c)build方法返回的就是sqlSession的工厂对象,这样我们就可以拿到sqlSession从而与数据库进行交互了。



2.2.与Spring整合时,我们只需定义操作数据库的接口即可,这是如何做到的。

2.2.1)将配置加载到内存:配置一个Spring+Mybatis项目时,对于Mybatis部分,我们一定是需要配置SqlSessionFactoryBean的:

            根据Spring的知识我们可以知道,Spring容器会在一启动时就实例化所有Bean,也就是说启动时便会创建一个SqlSessionFactory,

根据刚才的内容,我们可以知道创建SqlSessionFactory需要调build方法,build方法会去加载配置文件,

也就是说项目启动时便会加载所有的配置文件(mybatis配置+sql语句的*.xml)

       2.2.2)建立接口的关联关系:当我们调用接口时(userMapper.getUser()),mybatis是如何知道调哪个配置文件中的哪个sql语句?

而且我们的接口没有实现类,他为什么就可以调用正常不报错?

        a.加载配置文件时,也就是项目启动时便会根据mapper文件建立对应接口的绑定关系,但这里不是将mapper文件与接口绑定。


b.继续往下跟绑定操作,addMapper()方法

c.我们刚才弄清楚了mybatis是通过mapper配置文件先拿到对应接口,再建立接口与代理工厂关联关系。

现在我们继续弄清楚当我们调用具体的方法是,mybatis是如何运作的?

       1)拿到接口对应的代理实例

     

       2)通过JDK动态代理来代理接口

        

        3)具体的代理实现类

      4)分析invoke方法做了哪些事?

      先跟invoke方法体中的cachedMapperMethod(Method method)方法,主要做了两件事情

       a.找到配置文件中对应的sql

b.解析方法的返回值


5)取到了执行方法所需的信息,现在我们可以真正代替接口的方法开始执行了。


继续往里跟

 


       最终的执行,实际上是调用sqlsession对应的方法

       

总结:

       至此,我们了解了我们为什么仅仅定义接口而没有具体的实现类就可以完成一次方法的调用,核心是通过动态代理完成的,围绕着代理Mybatis做了许多的准备工作,包括加载配置文件,确定唯一id等,可能有些细节我没有讲到,如果有不明白的地方可以自己把代码拉下来照着我的思路去看代码。那么了解了这些对我们有什么帮助呢?1.首先可以锻炼自己阅读代码的能力,这很重要,工作中往往我们会中途接手一个项目,这就要求我们能够快速了解项目,Mybatis虽然是一个很优秀的开源项目,但是我们不需要对他各处的代码都关注,要锻炼自己抽出核心内容的能力,比如Mybatis,我们就不需要把精力放在他如何解析配置文件之类的操作,这无非是围绕解析DOM树做操作,这些是非核心的,我们只需知道Mybatis会把配置文件加载到内存中就够了,有时间兴趣的话我们再去了解这些分支。2.Mybatis一个很大的特性就是解藕,我们至此算是了解了Mybatis是通过把sql写到配置文件中,再通过动态代理来实现业务与sql的解藕,所以这就给我们一些启示,我们以后考虑解藕时又多了一种思路,可以借鉴Mybatis,把一些东西写到配置文件中,想办法把配置文件与代码关联起来。所以我们阅读了这些优秀的代码后,要时刻思考他对我们有什么业务价值,如何利用这些提高自己的生产力,开拓自己的思路,把接收到的好的思想、好的方法体现到业务中,这很关键。

        后面我们还会继续研究Mybatis,分享关于在Mybatis上写插件的一些东西。


1 0
原创粉丝点击