Skip to content

开发规范

本文档规定 MolanDev Cloud 项目的特有规范,通用规范请参考 阿里巴巴 Java 开发手册


包结构规范

标准包结构

com.molandev.{module}
├── controller/          # 控制器
├── service/             # 服务类(直接继承 ServiceImpl)
├── mapper/              # MyBatis Mapper 接口
├── entity/              # 数据库实体类
├── dto/                 # 数据传输对象
├── enums/               # 枚举类
├── constant/            # 常量定义
├── config/              # 配置类
└── utils/               # 工具类

命名规范

类命名

实体类(Entity):

java
// ✅ 正确:统一以 Entity 结尾
public class SysUserEntity { }
public class SysDeptEntity { }

// ❌ 错误:不要省略 Entity 后缀
public class SysUser { }

DTO:

java
// ✅ 正确:以 DTO 结尾
public class SysUserDTO { }
public class LoginDTO { }

Service:

java
// ✅ 正确:直接使用 Service 类,继承 ServiceImpl
@Service
public class SysUserService extends ServiceImpl<SysUserMapper, SysUserEntity> { }

// ❌ 错误:不要使用接口+实现类模式
public interface ISysUserService { }
public class SysUserServiceImpl implements ISysUserService { }

Mapper:

java
// ✅ 正确:以 Mapper 结尾
public interface SysUserMapper extends BaseMapper<SysUserEntity> { }

方法命名

Controller 方法: 使用 addeditdeletelistinfo 等方法名。

Service 方法:

java
// ✅ 正确:业务语义明确
public Page<SysUserEntity> list(SysUserQuery query) { }
public void saveUser(SysUserEntity entity, String roleIds) { }
public void deleteById(String id) { }

代码分层规范

分层架构

Controller (控制层)
    ↓ 接收请求、参数校验
Service (业务层)
    ↓ 业务逻辑、事务控制
Mapper (数据访问层)
    ↓ 数据库操作
Database (数据库)

Controller 层

  • ✅ 接收 HTTP 请求
  • ✅ 参数校验
  • ✅ 调用 Service 处理业务
  • ✅ 返回统一响应(JsonResult)
  • ❌ 不要写业务逻辑
  • ❌ 不要直接调用 Mapper

Service 层

  • ✅ 处理业务逻辑
  • ✅ 事务控制(@Transactional)
  • ✅ 调用 Mapper 操作数据
  • ❌ 不要处理 HTTP 相关逻辑
java
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserService extends ServiceImpl<SysUserMapper, SysUserEntity> {

    public void saveUser(SysUserEntity user, String roleIds) {
        // 业务逻辑
        this.save(user);  // ServiceImpl 提供的方法
    }
}

Mapper 层

  • ✅ 数据库操作
  • ✅ 使用 MyBatis Plus 内置方法
  • ✅ 自定义 SQL(使用注解)
  • ❌ 不要写业务逻辑

接口规范

基本结构

java
@Tag(name = "商品管理")
@RestController
@RequestMapping("/product")
public class ProductController {

    // 1. 查询详情
    @Operation(summary = "商品信息")
    @PostMapping("/info")
    public JsonResult<ProductEntity> info(@RequestParam String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonResult.invalid("主键不能为空");
        }
        return JsonResult.success(productService.getById(id));
    }

    // 2. 新增
    @Operation(summary = "新增商品")
    @PostMapping("/add")
    @HasPermission("product:add")
    @OpLog(title = "新增商品", type = OpTypes.ADD, module = "商品管理")
    public JsonResult<String> add(@ParameterObject ProductEntity product) {
        if (StringUtils.isNotEmpty(product.getId())) {
            return JsonResult.invalid("主键不能有值");
        }
        productService.save(product);
        return JsonResult.success(product.getId());
    }

    // 3. 编辑
    @Operation(summary = "编辑商品")
    @PostMapping("/edit")
    @HasPermission("product:edit")
    @OpLog(title = "编辑商品", type = OpTypes.UPDATE, module = "商品管理")
    public JsonResult<Void> edit(@ParameterObject ProductEntity product) {
        if (StringUtils.isEmpty(product.getId())) {
            return JsonResult.invalid("主键不能为空");
        }
        productService.saveOrUpdate(product);
        return JsonResult.success();
    }

    // 4. 删除
    @Operation(summary = "删除商品")
    @PostMapping("/delete")
    @HasPermission("product:delete")
    @OpLog(title = "删除商品", type = OpTypes.DELETE, module = "商品管理")
    public JsonResult<Void> delete(@RequestParam String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonResult.invalid("主键不能为空");
        }
        productService.removeById(id);
        return JsonResult.success();
    }

    // 5. 分页列表
    @Operation(summary = "分页查询商品")
    @PostMapping("/list")
    public JsonResult<PageResult<ProductEntity>> list(
            @ParameterObject PageQuery pageQuery,
            @ParameterObject ProductEntity product) {
        Page<ProductEntity> page = productService.page(
            DbQueryUtils.toPage(pageQuery),
            Wrappers.query(product)
        );
        return JsonResult.success(DbQueryUtils.pageResult(page));
    }
}

请求格式

场景格式注解说明
分页查询application/x-www-form-urlencoded无需注解默认格式
复杂对象application/json@RequestBody需要明确指定
文件上传multipart/form-data@RequestParam文件上传

JsonResult 统一响应

状态码定义:

状态码常量说明使用场景
0000SUCCESS成功操作成功
1000FAILED失败业务失败
2001INVALID参数不合法参数校验失败
3001NOT_LOGIN未登录用户未登录
3002NO_PERMISSION没有权限权限不足

使用示例:

java
// 成功响应
return JsonResult.success();
return JsonResult.success(data);

// 失败响应
return JsonResult.failed("操作失败");
return JsonResult.invalid("主键不能为空");

MyBatis 规范

查询规范

单表查询:使用 Wrapper

java
// ✅ 正确:单表查询使用 LambdaQueryWrapper
LambdaQueryWrapper<SysUserEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.hasText(username), SysUserEntity::getAccount, username)
       .eq(disabled != null, SysUserEntity::getDisabled, disabled);

List<SysUserEntity> list = sysUserService.list(wrapper);

多表查询:使用 SQL 注解

java
// ✅ 正确:使用 JDK 17 三引号 + @Select 注解
public interface SysUserMapper extends BaseMapper<SysUserEntity> {

    @Select("""
        SELECT u.*
        FROM sys_user u
        INNER JOIN sys_user_role ur ON u.id = ur.user_id
        WHERE r.role_code = #{roleCode}
        """)
    List<SysUserEntity> listByRoleCode(@Param("roleCode") String roleCode);
}

❌ 禁止:使用 XML 文件


数据库规范

表命名规范

规则: 以服务简称开头 + 业务名称

sql
-- ✅ 正确:系统服务表,以 sys_ 开头
sys_user        -- 用户表
sys_role        -- 角色表

-- ✅ 正确:消息服务表,以 msg_ 开头
msg_template    -- 消息模板表

实体类规范

命名规则: 表名转大驼峰 + Entity 后缀

java
// ✅ 正确:实体类以 Entity 结尾
public class SysUserEntity { }      // 对应表 sys_user
public class MsgTemplateEntity { }  // 对应表 msg_template

字段规范

逻辑删除字段: deleted

java
@Schema(description = "删除状态")
@TableField(value = "deleted", fill = FieldFill.INSERT)
@TableLogic
private Boolean deleted;  // Boolean 类型,数据库 TINYINT(1)

创建时间: create_time

java
@Schema(description = "创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;

更新时间: update_time

java
@Schema(description = "更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

实体类完整示例

java
@Getter
@Setter
@TableName("sys_dept")
@Schema(description = "部门")
public class SysDeptEntity {

    @Schema(description = "主键标识")
    @TableId(value = "id", type = IdType.ASSIGN_UUID)
    private String id;

    @Schema(description = "父节点id")
    @TableField("parent_id")
    private String parentId;

    @Schema(description = "部门名称")
    @TableField("dept_name")
    private String deptName;

    @Schema(description = "排序")
    @TableField("sort_seq")
    private Integer sortSeq;

    // 创建时间:插入时自动填充
    @Schema(description = "创建时间")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    // 更新时间:插入和更新时自动填充
    @Schema(description = "更新时间")
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    // 创建人:插入时自动填充
    @Schema(description = "创建人")
    @TableField(value = "create_user", fill = FieldFill.INSERT)
    private String createUser;

    // 逻辑删除:插入时自动填充为 false
    @Schema(description = "删除状态")
    @TableField(value = "deleted", fill = FieldFill.INSERT)
    @TableLogic
    private Boolean deleted;

    // 禁用状态:插入时自动填充为 false
    @Schema(description = "禁用状态")
    @TableField(value = "disabled", fill = FieldFill.INSERT)
    private Boolean disabled;
}

配置文件规范

配置分层

application.yml              # 主配置
application-local.yml        # 本地开发
application-dev.yml          # 开发环境
application-test.yml         # 测试环境
application-prod.yml         # 生产环境

单体模式配置示例

yaml
server:
  port: 8080

molandev:
  run-mode: single          # 单体模式
  lock:
    type: memory            # 内存锁
  datasource:
    sys:
      url: jdbc:mysql://localhost:3306/molandev_base
      username: root
      password: 123456
  security:
    mode: LOCAL             # 本地认证模式

logging:
  level:
    com.molandev: debug

代码检查清单

提交代码前,请确认以下事项:

  • [ ] 代码无编译错误和警告
  • [ ] 遵循命名规范
  • [ ] 添加必要的注释
  • [ ] 异常处理完整
  • [ ] 参数校验完整
  • [ ] 事务配置正确
  • [ ] 删除调试代码
  • [ ] 格式化代码

相关文档