从0构建新项目工程的总结

接口定义

  • 前后端分离项目,后端需要定义传输数据格式可以选择的方式有:

    1、简单一点所有接口全部使用POST传输,这样定义的数据结构既能够统一。

    2、或者GET/POST使用RESTFUL形式,GET只需要在链接后添加?token=,而POST使用统一数据体格式。

  • 接口区分版本号,选择在连接地址中明文显示出版本号,如:/v1.0/common/get ,后台在Controller或方法层使用注解来拦截版本号。同一大版本的代码都在一个Controller中,不同大版本需要重新建立Controller。另外版本标识无需在类名上体现。所有的版本信息归档都使用接口文档及代码注释来区分。
  • 提示用户的提示语一般放在前端(除非非常确定不修改就放在后端,后端修改需要重启更新的操作会影响用户正常使用),后端只返回状态码给前端(现在的三方接口一般也是这种)。


项目结构

  • 项目工程使用流行的Maven的Modules形式,如下这种:

  • Maven多项目依赖,模块及插件分项目
  1. 外面是parent的父级工程及pom.xml;
  2. 子集是每一个Modules模块项目(可以是普通Jar/可运行Jar/war包);

     其他有的是将数据库脚本(db)和运行脚本(bin)也放到项目结构中(一般开源软件的做法):

  1. 外面是总的工程名;
  2. 建一个parent子工程存放父级的pom.xml;
  3. 每个子项目都包含:/bin,/db,/src,pom.xml等内容。
  • 一般划分Modules模块的标准:
  1.  common;
  2. 如果后端只用作接口,可以只放工具类;
  3. 如果是完成的war项目,还可以放入共用的(一般是框架类)静态内容(js,css,img)。
  4. web;(多端)service/core;(也有将service和dao拆分为2个modules的)
  5. 其他utils的工具modules;
  • 当项目拆分出不同Module后,面临的问题:

  1. 尽量可抽象的内容就抽象成Modules,例如有多端应用,那么多端应用的Spring MVC相关内容就可以抽象出一个Base的Module工程;
  2. 不同Modules的所需的一些参数也需要从配置文件中获取,这时配置文件就段都集中放在最终的集成工程中,而每个工具工程、抽象工程为了不依赖于框架,通常使用Properties对象获取。
  • modules的maven项目在打包前需要在完整目录执行:mvn install。
  • 日志输出,可以选用不同功能输出到不同目录结构,便于在查询是分类查询。
  • 代码包名按功能模块区分开。(域名倒写.工程名.业务名.代码层.类名)
  • 一般系统级变量的存储有几种方式:
  1. 存储于数据库中,每次系统启动都从数据库中读取到内存。
  2. 或者使用不同环境的不同配置文件,打包时使用Maven的-P命令去指定加载的配置信息。
  • 为了便于统一规范,AOP(日志、权限等)的管理,一般接口路径名,方法名都要有标准前缀:
    service(get/query/update/add/delete)
    controller:get/add/update/qurey/delete/list
    获取select下拉,使用list开头;
    post页面使用query开头;
    所有的表、类、实体、接口文档中定义的名称要写全(做好统一,要表达全意思),由于类名已经表达了全意,所以方法名字可以简化(甚至可以只包含动词)。
    list/query方法名不用加复数s。
  • 充分理解和应用Java的三大特性:封装、继承、多态。
  • 注释/命名,规定自己“动词”在前,getObject,updateObject,listObject等。

框架选型

  • 一般选用Redis作为Session共享器,在拦截器中判断Redis中的Session是否存在,如果在Controller/Service中需要使用Session中存储的数据,可以选择在拦截器中将Session的数据放到request中,在后面直接使用,免得每次使用都要走一次Redis的网络请求和序列化操作。
  • 当时用Mybatis框架时,原生SQL返回的字段名称均是下划线的,而一般Java中属性名称均已驼峰形式展示,所以就需要将下划线字段名称转换成驼峰,直接在Mybatis拦截器中文章。
  • 当时用Mybatis框架时,可以选择mybatis-generator用作代码生成器,mybatis-pagehelper作文分页工具,通用Mapper作为减少代码编写的工具。
  • Service中一般不要出现常量数据(数字,字符串等),均使用共享常量形式引入。
  • Spring Security和Shiro可以做2件事:
  1. 身份认证(用户名、密码校验)
  2. 权限控制(检查用户是否有权限访问和操作某个资源)
        粗粒度的权限就只到url,菜单,按键,方法等;

        细粒度的权限需要自己在某些功能中自己实现,如只能访问自己所在城市的数据这类的

       其实如上2部分均可以自己实现:(资源分为三部分:菜单,菜单按键,访问接口)

  1. 登录接口直接校验用户名、密码,返回token和菜单权限(菜单,菜单按键,访问接口)给前端;
  2. 当用户访问某个后端接口时(需要带着菜单连接/按键权限),自己使用拦截器拦截访问去查询用户权限(根据用户传递的接口id,菜单连接/按键权限)。

数据操作

  • 所有数据避免物理删除,所有数据的更新需要有副本备份。
  • 关于Id主键生成策略,在一般的数量级使用数据库自增即可,如果一定要自定义(业务唯一性要求),尽量选择Long类型而非String。
  • 自定义主键Id需要考虑主键唯一和有序,主要的问题就是:
  1. 业务较多,是否每个业务的Id都自行设置生成规则;
  2. 一般流行的Id生成器都依赖于时间戳,就代表生成的主键Id位数会很长,不便于记忆和管理。
  • 数据库表名,字段名可以以数据类型开头,如表名都以t_开头,字段名以n_,c_等开头;这样数据类型一目了然,便于管理;但是也有一个问题,数据库数据需要和Java Bean绑定时,如果字段属性的get/set方法使用Lombak的@Data自动生成会出现找不到属性方法的情况。
  • 一般情况,无符号UNSIGNED在不同系统处理有别,如果需要某个数字字段不能小于0,最好通过程序逻辑控制。


猜你喜欢

转载自blog.csdn.net/sinat_37138973/article/details/80482182