library-picturebook-activity/.claude/memory/java-backend.md
En b805f456a6 feat: 完善后端基础架构和登录功能
- 添加 Lombok 配置支持
- 完善枚举类和常量定义
- 新增工具类(TraceId、限流、OSS 等)
- 添加切面(日志、限流、TraceId)
- 更新数据库索引规范(应用层防重)
- 登录页面样式优化
- 前后端项目文档补充
2026-03-31 13:58:28 +08:00

7.1 KiB
Raw Blame History

Java 后端开发规范

本项目 Java 后端开发规范,基于 Spring Boot + MyBatis-Plus 技术栈。

JDK 版本要求(重要)

必须使用 JDK 17 进行编译和运行。

如果系统环境变量配置的是 JDK 1.8,请在编译前设置 JAVA_HOME

# Windows (Git Bash) - 根据实际安装路径调整
export JAVA_HOME="/f/Java/jdk-17"
export PATH="$JAVA_HOME/bin:$PATH"

# 编译项目
mvn clean compile -DskipTests

# 或者在启动时指定
mvn spring-boot:run -Djava.home="/f/Java/jdk-17"

核心原则

  1. OpenAPI 规范驱动 - 前后端通过接口规范对齐
  2. 类型安全优先 - 强制类型校验
  3. 约定大于配置 - 统一代码风格
  4. 自动化优先 - 能自动化的绝不手动
  5. 三层架构分离 - Controller、Service、Mapper 职责清晰

技术栈

组件 技术选型 版本
框架 Spring Boot 3.2+
持久层 MyBatis-Plus 3.5+
对象映射 MapStruct 1.5+
数据库 MySQL 8.0+
缓存 Redis -
安全 Spring Security + JWT -
API 文档 Knife4j 4.x

三层架构

层级 职责 数据接收 数据返回
Controller 接收请求、参数校验、返回响应 DTO/Request VO/Response
Service 处理业务逻辑、事务控制 DTO/Entity Entity
Mapper 数据库 CRUD 操作 Entity/条件 Entity

核心规范:

  • Service↔Mapper 之间只用 Entity禁止 DTO/VO 转换
  • 转换只在 Controller 层发生
  • Service 继承 IService<T>
  • 查询接口默认分页

消除魔法值规范

禁止在代码中使用魔法值,所有状态、类型、常量必须使用枚举定义

  • 枚举类存放在 enums 包下
  • 枚举包含 codedesc 字段
  • 提供 getCode()getDesc()valueOfCode() 方法
  • 数据库存储 code,代码中使用枚举

ORM 实体类规范

表名命名

  • t_user_* - 用户模块
  • t_sys_* - 系统模块
  • t_biz_* - 业务模块
  • t_auth_* - 权限模块

审计字段(必填)

所有表必须包含审计字段:

字段 类型 说明
id BIGINT 主键(自增)
create_by VARCHAR(50) 创建人
create_time DATETIME 创建时间
update_by VARCHAR(50) 更新人
update_time DATETIME 更新时间
deleted TINYINT 逻辑删除0-未删除1-已删除)
  • 审计字段通过 MyBatis-Plus FieldFill 自动填充
  • 禁止手动设置审计字段

日志规范

日志语言

所有日志必须使用中文

TraceId 链路追踪

  • 使用 MDC 实现 TraceId 链路追踪
  • AOP 切面在请求入口生成 TraceId
  • 日志格式包含 [%X{traceId}]

环境差异化配置

环境 日志策略
开发/测试 全量记录DEBUG 级别)
生产 精简记录INFO/WARN 级别)

AOP 日志实现

  • 拦截 Controller 层所有方法
  • 请求日志TraceId、请求方法、路径、IP、耗时
  • 异常日志TraceId、异常类型、消息、堆栈

统一响应格式

Result<T> {
    code: Integer;     // 状态码
    message: String;   // 消息
    data: T;           // 数据
    timestamp: Long;   // 时间戳
}

错误码: 200-成功、400-参数错误、401-未授权、403-无权限、404-不存在、500-系统错误

MapStruct 对象映射

  • 使用 @Mapper 注解定义 Converter 接口
  • Entity ↔ VO 转换在 Controller 层调用
  • Service 层和 Mapper 层禁止 DTO/VO 转换
  • 命名规范:XxxConverterXxxMapStruct

工具类规范

  • 工具函数集中管理,禁止在 Controller 层编写工具方法
  • 工具类私有构造、静态方法、无状态、线程安全
  • 命名规范:XxxUtil(通用)、XxxHelper(业务)、XxxConverter(转换)

多环境配置

配置项 dev test prod
SQL 日志 开启 开启 关闭
Swagger 开启 开启 关闭
Flyway Clean 允许 禁止 禁止

快速参考

Redis Key 命名

  • auth:token:{token} - 用户 Token
  • user:info:{userId} - 用户信息缓存
  • dict:{type} - 数据字典
  • lock:{resource}:{id} - 分布式锁
  • rate_limit:{key} - 限流计数器

数据库索引规范(重要)

唯一索引处理原则

项目使用逻辑删除,唯一索引通过应用层控制,而非数据库唯一约束。

背景问题

当表有逻辑删除字段(deleted)时,数据库唯一索引会导致:

  1. 删除后无法重新添加相同数据
  2. 错误信息不友好,直接返回数据库异常

解决方案

层级 职责 实现方式
数据库层 普通索引 KEY idx_xxx (xxx) 而非 UNIQUE KEY uk_xxx (xxx)
应用层 重复校验 Service 层查询 + 悲观锁 FOR UPDATE
异常处理 兜底处理 全局异常处理器捕获 DuplicateKeyException

实现示例

1. 数据库迁移Flyway

-- ❌ 错误:使用唯一索引
UNIQUE KEY `uk_username` (`username`)

-- ✅ 正确:使用普通索引
KEY `idx_username` (`username`)

2. Mapper 层(悲观锁查询)

/**
 * 根据用户名查询用户(悲观锁,用于创建时防并发)
 */
@Select("SELECT * FROM t_user WHERE username = #{username} AND tenant_id = #{tenantId} AND deleted = 0 FOR UPDATE")
User getUserByUsernameForUpdate(@Param("username") String username, @Param("tenantId") Long tenantId);

3. Service 层(事务 + 校验)

@Transactional(rollbackFor = Exception.class)
public UserVO createUser(CreateUserDTO dto, Long tenantId, Long operatorId) {
    log.info("开始创建用户,用户名:{}", dto.getUsername());

    // 使用悲观锁检查用户名是否已存在(防止并发)
    User existingUser = userMapper.getUserByUsernameForUpdate(dto.getUsername(), tenantId);
    if (existingUser != null) {
        throw new BusinessException("用户名已存在");
    }

    // 插入用户
    User user = convert(dto);
    userMapper.insert(user);
    return convertToVO(user);
}

4. 需要应用层校验的字段

以下字段需要添加应用层重复校验:

字段 说明
t_user username, email, phone 用户名、邮箱、手机号
t_role code 角色编码
t_permission code 权限编码
t_dict code + tenant_id 字典编码
t_tenant code 租户编码
t_sys_config config_key 配置键

关联表索引规范

对于多对多关联表,使用普通索引而非唯一索引:

-- t_user_role: 用户角色关联表
KEY `idx_user_role` (`user_id`, `role_id`)

-- t_role_permission: 角色权限关联表
KEY `idx_role_permission` (`role_id`, `permission_id`)

注意:关联表的重复数据控制在应用层业务逻辑中处理。

核心环境变量

  • SPRING_PROFILES_ACTIVE - 活跃环境
  • DB_HOSTDB_PASSWORD - 数据库配置
  • REDIS_HOSTREDIS_PASSWORD - Redis 配置
  • JWT_SECRET - JWT 密钥
  • OSS_ACCESS_KEY_IDOSS_ACCESS_KEY_SECRET - OSS 配置