本文源码:GitHub·点这里 || GitEE·点这里

一、分层策略

MVC模式与代码分层策略,MVC全名是ModelViewController即模型-视图-控制器,作为一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,这是一种开发模式,但并不是实际开发中代码的分层模式,通常SSM框架的后端代码分层如下:

  • controller控制层:定义服务端接口,入参出参,和一些入参校验;
  • service业务服务层:组装业务逻辑,业务校验,构建控制层需要的参数模型;
  • dao数据交互层:提供服务层需要的数据查询方法,处理数据交互条件相关的逻辑;
  • mapper持久层:基于mybatis框架需要的原生支持,目前很常用的持久层组件;

二、控制层

1、Rest接口风格

基于资源访问和处理的逻辑,使用不同风格的注解。例如资源新增,更新,查询,删除。

/**
* 新增
*/
@PostMapping("/insert")
public Integer insert (@RequestBody BaseInfo baseInfo){
return baseInfoService.insert(baseInfo);
}
/**
* 更新
*/
@PutMapping("/update/{id}")
public String update(@PathVariable(value = "id") Integer id,
@RequestBody BaseInfo baseInfo) {
if (id<1){
return "error";
}
baseInfo.setId(id);
return "update="+baseInfoService.update(baseInfo);
}
/**
* 主键查询
*/
@GetMapping("/detail/{id}")
public InfoModel detail(@PathVariable(value = "id") Integer id) {
return baseInfoService.detail(id) ;
}
/**
* 主键删除
*/
@DeleteMapping("/delete/{id}")
public String delete(@PathVariable(value = "id") Integer id) {
baseInfoService.delete(id) ;
return "SUS" ;
}

2、接口复用度

不建议接口高度复用,例如增删改查都各自对接接口即可,基本原则,不同的客户端端操作,对于独立的接口。

/**
* 列表加载
*/
@GetMapping("/list")
public List<BaseInfo> list() {
return baseInfoService.list(new BaseInfoExample()) ;
}
/**
* 列表搜索
*/
@PostMapping("/search")
public List<BaseInfo> search (@RequestParam("userName") String userName,
@RequestParam("phone") String phone) {
return baseInfoService.search(userName,phone) ;
}

例如常见的list接口,list通常都有会按条件加载的search机制,而且搜索的判断条件很复杂,建议分为两个接口,从实际考虑,大部分场景下都是只使用list接口,很少使用search搜索。

3、入参出参

校验客户端必须条件,例如某某条件必填必选等,如果有问题,快速阻断请求链路,做到程序入口控制层拦截返回。

@PutMapping("/update/{id}")
public String update(@PathVariable(value = "id") Integer id,
@RequestBody BaseInfo baseInfo) {
if (id<1){
return "error";
}
baseInfo.setId(id);
return "update="+baseInfoService.update(baseInfo);
}

参数在三个以下,可以直接陈列入参,参数在三个或三个以上可以使用实体类统一封装。

@PostMapping("/search")
public List<BaseInfo> search (@RequestParam("userName") String userName,
@RequestParam("phone") String phone) {
return baseInfoService.search(userName,phone) ;
}

4、参数处理

出参格式处理度基本原则,服务器作为公共资源,避免非必要操作,例如客户端可自行判断返回值是否为空,null等,或者一些常见格式处理,利用客户端适当分担服务器压力。

三、业务服务层

1、业务校验

例如传入订单号,经过数据库层查询,没有订单数据,这里称为业务性质的异常,代码本身没有问题,但是业务逻辑无法正常执行。

public InfoModel detail(Integer id){
BaseInfo baseInfo = baseInfoDao.selectByPrimaryKey(id) ;
if (baseInfo != null){
DetailInfoEntity detailInfoEntity = detailInfoDao.getById(id);
if (detailInfoEntity == null){
LOG.info("id="+id+"数据缺失 DetailInfo");
}
return buildModel(baseInfo,detailInfoEntity) ;
}
LOG.info("id="+id+"数据完全缺失");
return null ;
}

2、组装业务逻辑

通常情况下服务层作为逻辑做复杂的一块,用来拼接业务核心步骤,可以通过业务逻辑判定,一步一步执行程序,避免在程序入口做大量可能用到的对象创建和需求数据查询。

public int insert (BaseInfo record){
record.setCreateTime(new Date());
int insertFlag = baseInfoDao.insert(record);
if (insertFlag > 0){
DetailInfoEntity detailInfoEntity = new DetailInfoEntity();
detailInfoEntity.setUserId(record.getId());
detailInfoEntity.setCreateTime(record.getCreateTime());
if(detailInfoDao.save(detailInfoEntity)){
return insertFlag ;
}
}
return insertFlag;
}

3、数据模型构建

通常情况业务层是偏复杂的,如果想关快速理解业务层,可以对复杂的业务方法,在提供一个返参构建的方法,用来处理服务层要向控制层回传的参数,这样可以让重度的服务层方法变的清晰。

private InfoModel buildModel (BaseInfo baseInfo,DetailInfoEntity detailInfo){
InfoModel infoModel = new InfoModel() ;
infoModel.setBaseInfo(baseInfo);
infoModel.setDetailInfoEntity(detailInfo);
return infoModel ;
}

四、数据交互层

1、逆向工程

这里以使用mybatis框架或者mybatis-plus框架作为参考。如果是mybatis框架,建议逆向工程的模板代码不做自定义的修改,如果需要自定义方法,在mapper和xml层面再自定义一个扩展文件,用来存放自定义的方法和SQL逻辑,这样避免表结构变动大引发的强烈不适。

当然现在大部分都会mybatis-plus作为持久层组件,可以避免上述问题。

2、数据交互

针对业务层的需要,提供相应的数据查询方法,只处理与数据库交互的逻辑,避免出现业务逻辑,尤其在分布式架构下,不同服务的数据查询和组装,不应该出现在该层。

public interface BaseInfoDao {

    int insert(BaseInfo record);

    List<BaseInfo> selectByExample(BaseInfoExample example);

    int updateByPrimaryKey(BaseInfo record);

    BaseInfo selectByPrimaryKey(Integer id);

    int deleteByPrimaryKey(Integer id);

    BaseInfo getById (Integer id) ;
}

五、源代码地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent

推荐阅读:编程体系整理

序号 项目名称 GitHub地址 GitEE地址 推荐指数
01 Java描述设计模式,算法,数据结构 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
02 Java基础、并发、面向对象、Web开发 GitHub·点这里 GitEE·点这里 ☆☆☆☆
03 SpringCloud微服务基础组件案例详解 GitHub·点这里 GitEE·点这里 ☆☆☆
04 SpringCloud微服务架构实战综合案例 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
05 SpringBoot框架基础应用入门到进阶 GitHub·点这里 GitEE·点这里 ☆☆☆☆
06 SpringBoot框架整合开发常用中间件 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
07 数据管理、分布式、架构设计基础案例 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆
08 大数据系列、存储、组件、计算等框架 GitHub·点这里 GitEE·点这里 ☆☆☆☆☆

编码风格:Mvc模式下SSM环境,代码分层管理的更多相关文章

  1. MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  2. 交互模式下测试python代码及变量的四则运算

    在交互模式下,python代码可以立即执行,所以这很方便我们进行代码测试 1.命令窗口,输入python (如果没配置环境变量则需带python安装目录的绝对路径) >>> 这个就是 ...

  3. 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表

    提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...

  4. 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  5. MVC模式下My97DatePicker日期控件引用注意事项

    My97DatePicker日期控件之前在用webform模式开发的时候,只要 <script language="javascript" type="text/j ...

  6. 卡卡游戏引擎之MVC模式下的事件处理

    前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...

  7. 解决Ubuntu(乌班图)vi/vim模式下粘贴的代码内容会多出的空格的问题

    vi/vim模式下的粘贴 因为linux系统和win系统的差异性,有时候在win环境运行的python代码会放在Linux系统上执行,这个时候就需要把win系统上IDE上的代码copy下来,在Linu ...

  8. Android:MVC模式(下)

    在上一篇文章中,我们将 View 类单独出来并完成了设计和编写.这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序. 模型(Model)就是程序中封装了数 ...

  9. MVC模式下unity配置,报错“No connection string named '**Context' could be found in the application config file”

     写在前面: 第一次配置时好好的,后来第二次改到MVC模式,把依赖注入写成字典的单例模式时,由于新建的ORM(数据库映射模型EF),怎么弄都不用,一直报错"No connection str ...

随机推荐

  1. python基础-面向对象opp

    上述是实例化对象的一个过程. 类的定义和实例化: class Role(object): #定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法,必须这样写,以后再讲 ...

  2. 《C++primerplus》第9章练习题

    1.(未使用原书例题)练习多文件组织.在一个头文件中定义一种学生的结构体,存储姓名和年龄,声明三个函数分别用于询问有多少个学生,输入学生的信息和展示学生的信息.在另一个源文件中给出所有函数的定义.在主 ...

  3. P4821 [中山市选]生成树

    题目链接 我们可以看一下题目中给的这张图. 首先,树是没有环的,所以我们要把所有的环上的边都删去一条. 我们可以现在每个五边形上删去一条边. 但删完之后我们会发现,里面还有一圈. 这时候,我们就要在这 ...

  4. Windows7 提示“无法访问您可能没有权限使用网络资源”的解决办法

    大家经常会碰到,电脑A(Windows7)访问局域网打印机的时候出现提示"无法访问你可能没有权限使用网络资源",导致无法正常使用打印机. 那么出现这种情况该如何解决呢? 解决方法: ...

  5. 多测师讲解python_模块间的调用_高级讲师肖sir

    案例1: 在aaa.py  文件A类中定义一个函数sadp: 在bbb.py文件中导入aaa模块,导入类 ,调用函数 案例2: aaa模块中定义一个A类, 在定义一个sadp的函数, 在bbb模块中导 ...

  6. c# 常用帮助类

    C#常用帮助类 因为小土现在还是处于小白阶段,所以自己的知识技术还达不到要求,但是小土在网上找到一个大神的,等以后小土技术有了一定提升以后,在走自己的路,啥也不说了上货. 地址 :https://gi ...

  7. 【C语言/C++程序员编程】一小时做出来的数字雨(一颗开花的树)!

    相信大家看过许许多多的关于计算机黑客.骇客.人工智能.AI方面的电影,每当黑客入侵某个五角大楼,某个网站时,都会出现这样一副画面: 入侵 或者这样的: 数字雨 然后就轻而易举的成功入侵夺取管理员权限了 ...

  8. kafka+zookeeper快速启动

    vim zookeeper.sh   #!/bin/bash /usr/local/zookeeper/bin/zkServer.sh restart /usr/local/zookeeper/con ...

  9. spring boot:接收数组参数及多文件混合json参数(spring boot 2.3.4)

    一,生产环境中的复杂参数上传的场景 1,保存排序值 : 例如:某一件商品的多张展示图片排序,提交的排序值要和图片的id相对应 2,上传多张图片,图片要和指定的变量相对应 例如:在添加商品sku时, 需 ...

  10. 一文秒懂!Python字符串格式化之format方法详解

    format是字符串内嵌的一个方法,用于格式化字符串.以大括号{}来标明被替换的字符串,一定程度上与%目的一致.但在某些方面更加的方便 1.基本用法 1.按照{}的顺序依次匹配括号中的值 s = &q ...