bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">则一后端开发注意事项
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">数据库
目前数据库1个主库,2个读库,应用服务使用写库以及读库1,报表服务使用读库2
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">创建表
必须字段
主键: id varchar(36)
删除标识: delete_flag tinyint(1)
创建时间:create_time datetime
创建人:create_user varchar(255) 创建人
修改时间:modify_time datetime 修改时间
修改人: modify_user varchar(255)修改人
一般还需要业务主键、状态、备注等等字段
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">索引
创建表必须加一个主键索引id
一般需要加一个业务主键,索引类型为唯一索引,保证数据不能重复添加(例如派车单号,运单号,账单号)
where后面查询字段要设置索引
SQL写完一定要在生产环境执行一下,看下执行计划有没有走索引,执行时间一般控制在1-2秒以内
大量数据的查询要控制时间范围,例如运单,派车单一次最多查询3个月的数据据
事务内的查询会走主库
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">常见生产问题⭐⭐⭐⭐⭐
- 慢SQL导致大量会话阻塞,系统查询慢或者无法查询
- 关联查询或主子查询创建了大数据量临时表,导致数据库临时表空间暴增,数据库无法读写
- 事务中的查询SQL直接走主库,SQL的where条件没加索引,大数据量查询导致了主库的CPU飙高
- 数据更新事务长时间未提交,导致其他事务无法操作,造成数据库死锁 例如开启事务之后http请求超时未响应
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">后台接口
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">接口设计
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">命名规范⭐⭐⭐⭐
类名一般为名词或名词组合,需要使用大驼峰命名法(UpperCamelCase) 风格
方法名、参数名、成员变量、局部变量需要使用小驼峰命名法(lowerCamelCase)
常量、枚举名称需要使用蛇形命名法(snake_case),常量以及枚举名称需要全部大写 例如:OUT_INVITE
包名统一使用小写,尽量使用单个单词作为包名,各个单词通过"."分隔符连接,并且各个单词必须为单数
POJO类中布尔类型的变量,都不要加is前缀,否则部分框架解析会引起序列化错误
如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式
抽象类命名使用Abstract开头
异常类命名使用Exception结尾
测试类命名以它要测试的类的名称开始,以Test结尾
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">接口定义⭐⭐⭐⭐
单一职责原则(Single Responsibility Principle) 开闭原则(Open Closed Principle) 里氏替换原则(Liskov Substitution Principle) 迪米特法则(Law of Demeter)又叫"最少知道法则" 接口隔离原则(Interface Segregation Principle) 依赖倒置原则(Dependence Inversion Principle)
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">方法定义⭐⭐⭐⭐
方法名的第一个单词应该是动词,首字母应小写。参数的名字必须和变量的命名规范一致。使用有意义的参数命名。参数尽量简化,不要定义方法中用不到的参数。超过5个则定义成对象类型
注意:方法职责一定要拎清楚,代码乱最根本的原因就是接口或者方法的定义的有问题,职责没有拎清楚
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">注释⭐⭐⭐
接口方法注释一定要写清楚
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">缓存⭐⭐⭐
基础数据最好加缓存,减小数据库压力,提高查询效率
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">事务⭐⭐⭐⭐
增删改方法一定要加事务注解
嵌套事务注意用try catch包住内部事务方法的异常
定时任务需要注意如果其中一条数据异常是否需要全部回滚
bb37431ec4ac4befed25266822e47ad252555fe7/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("创建派车单异常!");
}
}
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">异常
检查性异常处理一定要打日志
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐
直接catch掉异常,异常信息无法定位
try {
//业务逻辑
} catch (Exception e) {
log.error("钉钉审批回调消费异常!");
throw new BusinessException("钉钉审批回调消费异常!");
}
正确示例
try {
//业务逻辑
} catch (Exception e) {
log.error("钉钉审批回调消费异常!", e);
throw new BusinessException("钉钉审批回调消费异常!", e);
}
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">定时任务
要注意定时任务事务回滚问题。理清楚当有异常产生时,是要全部回滚还是正常执行完。
常见问题⭐⭐⭐⭐
定时任务异常未处理,导致整个事务回滚,任务执行失败!
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">版本兼容
APP后台开发要注意版本兼容问题,APP前端版本上线后不一定所有用户都能及时更新版本。要保证老版本使用的接口也能做出准确的响应
外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方造成影响。接口过时加@Deprecated注解,并清晰地说明新接口或新服务是什么
bb37431ec4ac4befed25266822e47ad252555fe7/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到上线分支,所有人都得重新合代码了,直接影响上线。一定要注意!!!!!
bb37431ec4ac4befed25266822e47ad252555fe7/guide/notice/则一后端开发注意事项.md#">常见问题⭐⭐⭐⭐⭐
push时把别人不上线的代码push到上线分支