则一后端开发注意事项.md 7.55 KB

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">则一后端开发注意事项

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">数据库

目前数据库1个主库,2个读库,应用服务使用写库以及读库1,报表服务使用读库2

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">创建表

必须字段

主键: id varchar(36)

删除标识: delete_flag tinyint(1)

创建时间:create_time datetime

创建人:create_user varchar(255) 创建人

修改时间:modify_time datetime 修改时间

修改人: modify_user varchar(255)修改人

一般还需要业务主键、状态、备注等等字段

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">索引

创建表必须加一个主键索引id

一般需要加一个业务主键,索引类型为唯一索引,保证数据不能重复添加(例如派车单号,运单号,账单号)

where后面查询字段要设置索引

SQL写完一定要在生产环境执行一下,看下执行计划有没有走索引,执行时间一般控制在1-2秒以内

大量数据的查询要控制时间范围,例如运单,派车单一次最多查询3个月的数据据

事务内的查询会走主库

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">常见生产问题⭐⭐⭐⭐⭐

  • 慢SQL导致大量会话阻塞,系统查询慢或者无法查询
  • 关联查询或主子查询创建了大数据量临时表,导致数据库临时表空间暴增,数据库无法读写
  • 事务中的查询SQL直接走主库,SQL的where条件没加索引,大数据量查询导致了主库的CPU飙高
  • 数据更新事务长时间未提交,导致其他事务无法操作,造成数据库死锁 例如开启事务之后http请求超时未响应

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">后台接口

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">接口设计

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">命名规范⭐⭐⭐⭐

类名一般为名词或名词组合,需要使用大驼峰命名法(UpperCamelCase) 风格

方法名、参数名、成员变量、局部变量需要使用小驼峰命名法(lowerCamelCase)

常量、枚举名称需要使用蛇形命名法(snake_case),常量以及枚举名称需要全部大写 例如:OUT_INVITE

包名统一使用小写,尽量使用单个单词作为包名,各个单词通过"."分隔符连接,并且各个单词必须为单数

POJO类中布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误

如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式

抽象类命名使用Abstract开头

异常类命名使用Exception结尾

测试类命名以它要测试的类的名称开始,以Test结尾

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">接口定义⭐⭐⭐⭐

单一职责原则(Single Responsibility Principle) 开闭原则(Open Closed Principle) 里氏替换原则(Liskov Substitution Principle) 迪米特法则(Law of Demeter)又叫"最少知道法则" 接口隔离原则(Interface Segregation Principle) 依赖倒置原则(Dependence Inversion Principle)

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">方法定义⭐⭐⭐⭐

方法名的第一个单词应该是动词,首字母应小写。参数的名字必须和变量的命名规范一致。使用有意义的参数命名。参数尽量简化,不要定义方法中用不到的参数。超过5个则定义成对象类型

注意:方法职责一定要拎清楚,代码乱最根本的原因就是接口或者方法的定义的有问题,职责没有拎清楚

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">注释⭐⭐⭐

接口方法注释一定要写清楚

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">缓存⭐⭐⭐

基础数据最好加缓存,减小数据库压力,提高查询效率

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">事务⭐⭐⭐⭐

增删改方法一定要加事务注解

嵌套事务注意用try catch包住内部事务方法的异常

定时任务需要注意如果其中一条数据异常是否需要全部回滚

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐

未加事务注解导致数据不一致

@Override
@Transactional
public String createDispatch(CreateDispatchRequestDto createDispatchRequestDto) {
    waybillService.createWaybill(dispatchCode, waybillCode);
    dispatchStopOverStationService.createDispatchStation(createDispatchStationRequestDto);
    dispatchVehicleService.createDispatchVehicle(createDispatchRequestDto);
    dispatchPriceService.createDispatchPrice(createDispatchRequestDto);
    dispatchSupplierPriceService.createDispatchSupplierPrice(createDispatchRequestDto);
    try {
        //带事务方法
        dispatchOperationRecordService.createDispatchOperationRecord(createDispatchRequestDto);
    } catch (Exception e) {
        log.error("创建派车单异常!");
    }
}
12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">异常

检查性异常处理一定要打日志

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐

直接catch掉异常,异常信息无法定位

try {
    //业务逻辑
} catch (Exception e) {
    log.error("钉钉审批回调消费异常!");
    throw new BusinessException("钉钉审批回调消费异常!");
}

正确示例

try {
    //业务逻辑
} catch (Exception e) {
    log.error("钉钉审批回调消费异常!", e);
    throw new BusinessException("钉钉审批回调消费异常!", e);
}

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">定时任务

要注意定时任务事务回滚问题。理清楚当有异常产生时,是要全部回滚还是正常执行完。

常见问题⭐⭐⭐⭐

定时任务异常未处理,导致整个事务回滚,任务执行失败!

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">版本兼容

APP后台开发要注意版本兼容问题,APP前端版本上线后不一定所有用户都能及时更新版本。要保证老版本使用的接口也能做出准确的响应

外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方造成影响。接口过时加@Deprecated注解,并清晰地说明新接口或新服务是什么

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐

APP未做版本兼容,导致老版本APP无法正常使用

直接改外部正在调用的接口,导致别的服务不可用

废弃的接口直接抛业务异常

@PostMapping("/add")
public Response<Void> addDriverVehicleLicense(@RequestBody @Validated DriverVehicleLicenseAddRequestDto driverVehicleLicenseAddRequestDto) {
    throw new BusinessException("请下载最新APP版本!");
}

新老版本并行的接口加版本区分

/**
* 新增
*/
@PostMapping("/add")
public Response<Void> addDriverVehicleLicense(@RequestBody @Validated DriverVehicleLicenseDiscernAddRequestDto driverVehicleLicenseAddRequestDto) {
    driverVehicleLicenseService.addDriverVehicleLicense(driverVehicleLicenseAddRequestDto);
    return returnSuccess();
}

/**
* 新增(接口兼容:增加行驶证背面传递到副页字段)
*/
@PostMapping("/add/v1")
public Response<Void> addDriverVehicleLicenseV1(@RequestBody @Validated DriverVehicleLicenseDiscernAddRequestDto driverVehicleLicenseAddRequestDto) {
    driverVehicleLicenseService.addDriverVehicleLicenseV1(driverVehicleLicenseAddRequestDto); 
    return returnSuccess();
}

git

分支:开发分支,测试分支,上线分支,master
开发分支: 开发功能时要创建自己的开发分支,开发分支从master创建分支,一般一个需求对应一个分支
测试分支: 测试环境部署的分支,功能开发完通过单元测试后就可以把代码合并到测试分支进行测试
上线分支: 每周会有一个上线版本,上线之前需要把要上线的代码合并到上线分支,从自己的开发分支合并到上线分支
master: 生产环境部署分支,由上线部署人员从上线分支合并到master

push之前一定拉下代码,push时一定要看下是不是自己的代码,一定要看全部内容,注意提交内容多时会有省略号,要一直点到最后没有省略号为止。如果把不上线的代码push到上线分支,所有人都得重新合代码了,直接影响上线。一定要注意!!!!!

12fb21996d3cec9a8a64d55607de03b7977e7ae1/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐

push时把别人不上线的代码push到上线分支