# 工程分层与数据访问 ## 分层与依赖 - **必须**:遵循项目既有模块边界和依赖方向;领域层不得反向依赖 Web、ORM 或具体基础设施实现。 - **必须**:Controller/Endpoint 负责协议适配与边界校验,不承载核心业务编排。 - **必须**:持久化对象、领域对象和 API DTO 的转换边界明确;不得把 ORM 实体直接作为外部契约。 - **推荐**:使用构造器注入表达必需依赖并支持测试;字段注入仅在项目框架约束明确时使用。 - **推荐**:工具类无状态、职责单一且构造器不可见;不要创建混杂业务逻辑的通用 `Utils`。 - **必须**:循环依赖表示边界问题,不以延迟注入作为默认解决方案。 ## 数据访问 - **必须**:禁止字符串拼接用户输入生成 SQL;MyBatis 默认使用 `#{}`,`${}` 只允许经过严格白名单的元数据。 - **必须**:明确查询列,不使用 `SELECT *` 作为生产查询默认写法。 - **必须**:分页总数为零时避免继续执行无意义的数据查询;限制最大页大小和排序字段。 - **必须**:批量查询、写入和 `IN` 参数有明确上限并按数据库能力分批。 - **必须**:避免循环中逐条远程或数据库调用;检查 N+1 查询和不受控懒加载。 - **必须**:更新语句只更新预期字段;乐观锁、版本号或条件更新必须检查受影响行数。 - **必须**:事务内查询和更新基于明确隔离假设;不能用应用层 `if` 代替数据库唯一约束或原子条件。 - **推荐**:索引设计与真实查询条件、排序和基数一致;新增查询必须评估执行计划或沿用已验证索引。 - **推荐**:数据库约束与应用校验共同保护核心不变量,不机械套用“禁止所有外键”;服从项目的数据治理策略。 ## Spring、Jakarta 与 ORM - **必须**:Bean Validation 放在真实入口并确保级联校验生效;内部调用仍需保护领域不变量。 - **必须**:`@Transactional`、缓存、异步和权限注解必须考虑代理边界、自调用、方法可见性和异常回滚语义。 - **必须**:JPA 实体的 `equals/hashCode` 不得依赖会变化的数据库生成标识造成集合异常。 - **推荐**:默认避免 Open Session in View 带来的隐式查询;在服务边界显式获取所需数据。 - **必须**:MyBatis/JPA 映射字段、枚举、时区和 null 语义必须有测试,不能仅凭同名假设自动映射正确。 ## 构建与依赖 - **必须**:新增或升级依赖前确认项目 BOM、dependency management、版本锁定和许可证/安全要求。 - **必须**:生产发布不依赖不可复现的 SNAPSHOT 或动态版本,除非项目流程明确批准。 - **必须**:依赖变更检查传递依赖、冲突、打包体积和运行时兼容;不要只确认“能编译”。 - **推荐**:优先使用 JDK 与项目已有库;为一个简单方法引入大型依赖通常不合理。 - **必须**:生成代码和资源遵循构建目录约定,不手改会被生成器覆盖的文件。