一、manager层是个什么鬼
传统的SpringMVC架构,分为Controller,Service,DAO三层。Controller控制页面逻辑,业务逻辑和事务在Service层,数据库操作通过编写sql在DAO层。
其实这样的架构非常简洁也容易上手,但是会有如下的一些问题:
- service层代码臃肿
- service层事务嵌套,导致问题狠多
- dao层参杂业务
- dao层sql语句复杂,关联查询比较多
- dao层经常改来改去
二、使用manager层解决
引自《阿里规约》:
Manager 层:通用业务处理层,它有如下特征:
对第三方平台封装的层,预处理返回结果及转化异常信息;
对 Service 层通用能力的下沉,如缓存方案、中间件通用处理;
与 DAO 层交互,对多个 DAO 的组合复用。
因为特色,所以在分层这块,最终还是选择阿里的架构:分为四层,如下:
- controller
- service
- manager
- dao
把manager层追加下面的功能:
- 复杂业务,service提供数据给Manager层,然后把事务下沉到Manager层
- Manager层不允许相互调用(即不同业务下的manager禁止调用,如 用户 UserManager 禁止调用 订单 OrderManager ),以避免事务嵌套
- 专注于不带业务sql语言,也可以在manager层进行通用业务的dao层封装
- 避免复杂的join查询,数据库压力比java大很多,所以要严格控制好sql,所以可以在manager层进行拆分,比如复杂查询
- 可以在manager层使用mybatis-plus的 BaseService,因为 manager层不会被其他业务调用,所以不会引起其他业务看到更多的BaseService方法
再次说明:manager层不是必须的,而是有需要的话才去使用。
三、使用举例
操作多张表进行统一事务管理
net.lab1024.sa.admin.module.system.role.manager.RoleMenuManager
net.lab1024.sa.admin.module.system.employee.manager.EmployeeManager
代码如下:
java
@Service
public class RoleMenuManager extends ServiceImpl<RoleMenuDao, RoleMenuEntity> {
@Resource
private RoleMenuDao roleMenuDao;
/**
* 更新角色权限
*
*/
@Transactional(rollbackFor = Exception.class)
public void updateRoleMenu(Long roleId, List<RoleMenuEntity> roleMenuEntityList) {
// 根据角色ID删除菜单权限
roleMenuDao.deleteByRoleId(roleId);
// 批量添加菜单权限
saveBatch(roleMenuEntityList);
}
}