7.4 KiB
7.4 KiB
NL Java 编码规范
必须遵守
- 回复、代码注释、日志统一使用中文。
- 使用 Java 17、UTF-8、4 空格缩进。
- 提交前使用 IDE 格式化代码,并确保
mvn clean install通过。 - 接口返回值使用
ResultPo。 - 分页接口返回值使用
Result<PageResult>。 - 分页查询的 service 入参使用 request 对象,不要用基本类型散传。
- 参数校验使用注解,例如
@NotNull,不要在业务代码里重复判空兜底。 - 方法里面如果有校验逻辑,先校验,再做业务。
- 注入统一使用
@Resource,不要使用构造器注入。 - 默认按
id倒序,除非需求明确指定其他排序。 - 每个接口方法和每个
private方法上方都写中文注释,说明作用。 - 类里的字段、方法上方要加中文注释。
- 代码里的日志统一使用中文。
- 调用其他服务后必须判断
isSuccess,失败时抛出业务异常。 - 文字类提醒异常统一使用
ServiceException。 - 跨模块共享的数据结构放在
product-api,不要泄露product-server内部类型。 Provider或Api这类对外暴露接口,参数对象命名为XXXReq,返回对象命名为XXXResp。- 新增和编辑如果是两个接口,请求参数定义为两个对象,可以让
UpdateXXXReq继承InsertXXXReq。 - 枚举如果没有特殊要求,默认只有一个字段
code,查询方法叫getByCode;code类型根据数据库字段决定,可以是String或Integer。 - 类上非必要注解不要写,比如
@EqualsAndHashCode、@ToString;可以使用@Data和 Apifox 相关注解。 - Apifox 接口上的
example不要写。 Collectors.toMap时,如果 key 是id,value 使用Function.identity()。- 如果数据库查询出来的字段是
Boolean,并且数据库保证不为空,直接使用if (shop.getIsEnable()),不要写!Boolean.TRUE.equals(shop.getIsEnable())。 - 如果是api层的接口就别用swagger注解了,用java自带的注解就可以了
- 判断集合是否为空用CollectionUtils,ObjectUtils.isEmpty()这种工具类,别用集合对象.isEmpty()
- java枚举如果code跟名称一样,就别单独写code了
- set的时候,用reqDTO.getPrepareHouseType() != null ? reqDTO.getPrepareHouseType().getCode(): null
- 如果需要用productcompareMapper.updateById更新数据库的话,那么这个参数需要自己new出来,别用数据库查询出来的数据
- 调用第三方接口的时候,如果异常了需要打印请求参数,跟返回值,格式类似 log.error("取消出库失败,dtos={}, wms返回信息={}", JSON.toJSONString(dtos), JSON.toJSONString(stringResultVo));
- 尽量不要为了简单工具方法抽工具类对象,超过3个或者复杂的工具类才需要抽出对象
- 如果是业务方法,尽量一个接口一个对象,如果有多层对象,尽量用内部类
- service方法注解一定需要的,需要把方法的核心简单用简短干练的注释说明
- java中controller层或者feign层的方法名称是驼峰,那么请求url也驼峰把,跟方法保持一致
- 尽量不要try catch,如果是需要异常以后继续运行的,才进行try catch
- 如果是接口幂等的逻辑,不要返回正常结果,而是抛出业务异常
- 尽量不要抽方法行数在5行一下的方法
- 业务配置放在nacos里面,取值用@Value("${alibaba1688.access_token}"), 尽量不用兜底如果没有就报错,系统配置放在application里面,
- bean对象的转换用mapStruct,模仿MemberConfigConvert
- 如果在类里面定义常量,那么常量的key跟value尽量保持一致,如果是格式不一样值至少是一样的
- 如果是系统内部的类,mapper跟mapper对象的dto先不分包,manager层外部的也先不分包都放一个包里面。
- 生成的mapper跟表的结构保持一致,比如order_item, OrderItemMapper.xml
- 生成单元测试用Spring那一套,@SpringBootTest, 可以模仿ProductCompareServiceLocalSpringTest
- 发钉钉通知的话标题里面要带通知或者告警
- 允许简单 SQL 使用 MyBatis-Plus 自带查询方法,例如
.selectOne。
代码结构规范
controller、service、enum、按照业务分包、manager(外部调用包装)暂时不分包 如果是方法的参数就放在当前包里面的vo、bo、dto包里面
数据库规范
- 不要使用 MyBatis-Plus 自带查询方法,例如
.selectOne。 - 只要有查询逻辑,都写到 xxxMapper.xml 里。
- 不要使用
@Select这类注解 SQL。 - SQL 统一写在 MyBatis XML 文件里。
- 查询条件直接使用
is_deleted = 0,不要额外写默认值兜底。 - 根据
id删除时,mapper 方法命名就叫deleteById,不要加soft一类前缀。 - 操作数据库时,不需要手动指定更新时间,数据库有默认值。
- 数据库默认不为空的字段,从数据库拿到后不要再做兜底逻辑。
- 数据库有默认值的字段,查询出来后不要再判断
null,除非是审批时间这类本身允许为空的业务字段。 - 生成 DDL 时,不要追加
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci。 - 唯一索引只有在明确需要唯一约束时才添加。
- 默认不要使用联合索引,除非需求明确说明。
- 如果是根据XXXid查询的,如果是主键或者唯一索引的话返回一个对象,是关联的id,那么返回List,别用limit1兜底
- 数据库字段命名是下划线的
- 建表的时候要贴合业务,别取短而抽象的表明,要取能说明业务的表明,见名知意比名字短更重要
- 联动信息不存快照,比如更新人名称,只存关联的id
测试规范
- 如果没有明确要求生成单元测试,就不要生成测试。
- 如果要求生成测试,只生成 Spring 风格集成测试,不生成 mock 测试。
- 测试默认按本地 Spring 集成测试格式编写:使用
@SpringBootTest、@ActiveProfiles("local")。 - 测试类命名可参考
*LocalSpringTest。 - 通过
@Resource注入待测 Bean。 - 测试方法至少包含一个有效断言,例如
Assertions.assertNotNull(...)。 - 严禁生成 Mockito 风格测试骨架,例如
@Mock、@InjectMocks、Mockito.when、Mockito.verify。
禁止事项
- 禁止使用
BeanUtils.copyProperties,改为逐字段赋值,或者直接让 mapper 返回目标对象。 - 禁止无意义的
trim/null兜底。 - 禁止写
normalizeXxx、distinctNonNull、getXxxOrThrow这类辅助方法。 - 禁止类似
normalizeSourceType这种兜底方法;接口层会通过注解限制,如果注解解决不了,就在业务方法里直接校验。 - 禁止为数据库默认值手动补空值、补更新时间、补
is_deleted。 - 禁止一行代码也抽方法的过度封装。
- 禁止过度封装“查不到就抛错”的一层薄方法。
- 禁止无需求说明时省略默认排序。
- 禁止在 service 分页查询接口中散传基本类型参数。
- 禁止写列表转分页时的
instanceof Page<?>兼容分支。 - 禁止使用
@Select注解写 SQL。 - 禁止在业务代码里重复写接口参数判空兜底。
- 禁止为了一个方法去创建对象承载多个参数;如果某个地方需要返回多个参数,直接在核心业务逻辑里处理即可。
- 禁止 java8 使用 orElse
- 禁止直接用从数据库查询出来的对象,去更新数据类似productcompareMapper.updateById(existed);
- 禁止使用trim()这个方法做一些字符串的兜底