本文主要向您展示“java开发中向MVC三层架构添加管理器层的原理示例分析”,简单易懂。很清楚是为了帮你解决疑惑。让边肖带领大家学习《java开发中MVC三层架构添加管理器层原理的实例分析》一文。
MVC三层架构
我们刚成为程序员的时候,被前辈“教育”系统设计要遵循MVC(Model-View-Controller)架构。它将整个系统分为模型、视图和控制器三个层次,即把用户视图和业务处理分开,通过控制器把它们连接起来,从而实现表示和逻辑的解耦。这是一个标准的软件分层架构。
MVC分层架构是架构中最简单的分层方式。为了遵循这种分层架构,我们在构建项目时往往会设置三个目录:控制器、服务和dao,分别对应表示层、逻辑层和数据访问层。
每一层的功能如下:
控制器层:主要转发访问控制,验证各种基本参数,或者简单处理不可重用的服务。
服务层:主要处理业务逻辑和事务。
Dao层:负责与底层数据库MySQL和Oracle的数据交互。
然而,随着我们的业务逻辑变得越来越复杂,编写的代码越来越多,这种简单的三层架构的问题变得越来越明显。
MVC架构弊端
传统MVC分层存在以下明显问题:
服务层代码臃肿。
服务层容易出现大事务和嵌套事务,导致很多问题,极难排除。
Dao层参与业务逻辑。
dao层的Sql语句很复杂,有很多相关的查询。
为了解决这个问题,我们参考《alibaba java开发手册》,在Service层下分离出一个通用的业务处理层(Manager层)。
在这种分层架构中,主要增加了Manager层,其与service层的关系是Manager层提供原子Service接口,Service层负责根据业务逻辑安排原子接口。
00-1010管理器层在《alibaba java开发手册》中描述如下:
经理层:一般业务处理层,具有以下特点:
对于第三方平台封装的层,对返回结果进行预处理,对异常信息进行转换,适应层接口;服务层通用能力的下沉,如缓存方案和中间件通用处理;与DAO层交互,组合复用多个DAO。
在实际开发中,我们可以像这样使用管理器层。
复杂业务,服务向管理器层提供数据,负责业务安排,然后将事务下沉到管理器层。管理器层不允许相互调用,所以不会有事务嵌套。
专注于没有业务的sql语言,同时在经理层将一般业务封装在dao层。
避免复杂的连接查询,因为数据库的压力比java大得多,所以我们应该严格控制sql,这样我们就可以在管理器层拆分它,比如复杂的查询。
当然,对于简单的业务,可能不会使用Manager层。
Manager层的特征
这里,让我们举一个例子来说明Manager层的使用场景:
假设你有一个用户系统,它有一个获取用户信息的接口。它调用逻辑服务层中的getUser方法,getUser方法与用户数据库交互以获取数据。如下图左侧所示。
这时,产品提出了一个要求。在APP中显示用户信息时,如果用户不存在,应该自动为用户创建一个用户。同时,制作一个HTML5页面,HTML5页面要保持之前的逻辑,即不需要创建用户。
此时,按照传统的三层架构,逻辑层的边界变得不清晰,表示层也承载了部分业务逻辑,因为我们经常在表示层Controller中加入业务逻辑处理,安排用户的获取和用户界面的创建。
添加管理器层后,管理器层提供创建。
建用户和获取用户信息的接口,而 Service 层负责将这两个接口组装起来。这样就把原先散布在表现层的业务逻辑都统一到了 Service 层,每一层的边界就非常清晰了。
接下来我们看一段实际代码说明一下Service层与Manager层如何进行区分?
@Transactional(rollbackFor = Throwable.class) public Result<String> upOrDown(Long departmentId, Long swapId) { // 验证 1 DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); if (departmentEntity == null) { return Result.error("部门xxx不存在"); } // 验证 2 DepartmentEntity swapEntity = departmentDao.selectById(swapId); if (swapEntity == null) { return Result.error("部门xxx不存在"); } // 验证 3 Long count = employeeDao.countByDepartmentId(departmentId); if (count != null && count > 0) { return Result.error("员工不存在"); } // 操作数据库 4 Long departmentSort = departmentEntity.getSort(); departmentEntity.setSort(swapEntity.getSort()); departmentDao.updateById(departmentEntity); swapEntity.setSort(departmentSort); departmentDao.updateById(swapEntity); return Result.OK("success"); }
上面代码在我们在我们采用三层架构时经常会遇到,那么它有什么问题呢?
上面的代码是典型的长事务问题(类似的还有调用第三方接口),前三步都是使用 connection 进行验证操作,但是由于方法上有@Transactional 注解,所以这三个验证都是使用的同一个 connection。
若对于复杂业务、复杂的验证逻辑,会导致整个验证过程始终占用该 connection 连接,占用时间可能会很长,直至方法结束,connection 才会交还给数据库连接池。
对于复杂业务的不可预计的情况,长时间占用同一个 connection 连接不是好的事情,应该尽量缩短占用时间。
说明:对于@Transactional 注解,当 spring 遇到该注解时,会自动从数据库连接池中获取 connection,并开启事务然后绑定到 ThreadLocal 上,如果业务并没有进入到最终的 操作数据库环节,那么就没有必要获取连接并开启事务,应该直接将 connection 返回给数据库连接池,供其他使用。
所以我们在加入Manager层以后可以这样写:
DepartmentService.java public Result<String> upOrDown(Long departmentId, Long swapId) { // 验证 1 DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); if (departmentEntity == null) { return Result.error("部门xxx不存在"); } // 验证 2 DepartmentEntity swapEntity = departmentDao.selectById(swapId); if (swapEntity == null) { return Result.error("部门xxx不存在"); } // 验证 3 Long count = employeeDao.countByDepartmentId(departmentId); if (count != null && count > 0) { return Result.error("员工不存在"); } // 操作数据库 4 departmentManager.upOrDown(departmentSort,swapEntity); return Result.OK("success"); }
DepartmentManager.java @Transactional(rollbackFor = Throwable.class) public void upOrDown(DepartmentEntity departmentEntity ,DepartmentEntity swapEntity){ Long departmentSort = departmentEntity.getSort(); departmentEntity.setSort(swapEntity.getSort()); departmentDao.updateById(departmentEntity); swapEntity.setSort(departmentSort); departmentDao.updateById(swapEntity); }
将数据在 service 层准备好,然后传递给 manager 层,由 manager 层添加 @Transactional
事务注解进行数据库操作。
以上是“java开发MVC三层架构上再加一层Manager层原理的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/60902.html