大家好啊,我是司空,最近在工作闲暇之余正在学springBoot,学到了关于mybatis的配置,里面涉及到几个不同层之间的使用让我有点摸不着头脑,没法,公司用的还是十年前的老框架,对于现在这些框架真没啥了解,不过MVC机制是没有变了,我也就结合我所学的内容和工作中的实际经验,谈一谈我对这几个层之间的了解吧。
基本了解
话不多说先上图
上图用的是我整理思路的时的草图,不具备专业性,大家别当真了哈,看看思路就好
dao层:用于定义操作数据库的接口方法,需要怎么调数据库就定义什么方法在这
mapper层:用于直接对数据库进行操作,sql语句就写这
service层:用于定义业务实现的接口方法,需要实现什么业务就定义什么方法在这
serviceImpl层:用于实现业务接口,可以操作管理dao层获取想要的数据
其他几个层:如controller,view,model,entity就简单过一过,分别负责数据的处理,展示,存储和封装。就不详细说了,我新学的主要是上面四个。
一些思考
根据上图我们知道,其实对于实现一个功能来说,只需要model,view,controller层就行了,那为啥还要在model到controller之间插入dao层和service层呢? 让我们带着这个问题,去看一下使用ssm框架实现一个view渲染的现实路径映射吧。
上图用的是我整理思路的时的草图,不具备专业性,大家别当真了哈,看看大体路径就好
可以看到啊,view层和controller层,controller层和service层,serivce层和dao层,都是多对多的关系。而service层和serviceImpl层,dao层和mapper层,mapper层和model层则是一对一的关系。
问题就出在这对应关系上!
试想一下,这只是一个view,就可能调用多个controller去获取数据,那两个view呢,一堆view呢。如果绕开service层和dao层以及mapper层,直接让controller层与model层进行交互,那很明显会出现一个问题,代码的大量重复以及耦合性强。如view1需要model1的userId,view2也需要,倘若绕开三层直接让controller层与model层进行交互,那么view1需要与model1建立一次连接,取一次userId。view2也需要与model1建立一次连接取一次userId,这是很蠢的行为。
一个方法,如果需要写三次以上,就应该封装起来,更别提调数据库这种如此频繁的行为。再说,如果数据库表遭到更改,难道你去每个controller里面改一次sql语句吗?
这就引出了我们第一个问题的答案:为啥还要在model到controller之间插入dao层和service层? 目的就是为了解耦,提高代码的开发效率。这也就是刚才我们提到的多对多关系的由来。
细心的朋友可能发现了,刚才我不仅说到了多对多的关系,还存在着一对一的关系。那么这个一对一的关系又是为了什么呢?
实际上,如果我们把service层与dao层合起来,在面对一些小型业务量的场景时,是完全没有问题的。起初我也搞不懂,为啥要用service的接口方法调用另外一个接口的方法去实现。可当业务量上去后,才发现这是一个多么明智的选择。
我认为建立service层和dao层最直接的好处就是单一职责化,这也是SOLID原则中的单一职责原则(Single Responsiblity Principle),非常经典的体现,service只用考虑业务如何实现,不考虑数据如何获取。dao层和mapper只用考虑数据如何获取,不用考虑数据要被拿去干什么。在多人协作开发与业务高复杂度场景中这种思想十分好用。
一些疑问:
看见网上一些博客,都说dao层一般是对应着某个表。我个人并不认同,一是表太多创建太多接口类难以管理。二是如果遇到那些多表联查的场景时,该把这些接口方法放到哪个类里面呢?
我认为较好的就是将dao层接口类与库相对应,一个库对应一个dao层接口类,然后把一些比较重要的表或者几张表单独建立dao层接口类,如用户信息,安全登录表等等。可以在方便管理的情况下又合理地保护某些重要数据。所有有人知道为什么dao层接口类要与表相对应嘛?有的话请在评论区告诉我哦。
以上就是我对这几个层的一些浅薄理解,如果有错误请大家多多指正,我们共同学习,共同进步。peace&love❥(^_-)