开发规范
本文档规定 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 方法: 使用 add、edit、delete、list、info 等方法名。
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 统一响应
状态码定义:
| 状态码 | 常量 | 说明 | 使用场景 |
|---|---|---|---|
0000 | SUCCESS | 成功 | 操作成功 |
1000 | FAILED | 失败 | 业务失败 |
2001 | INVALID | 参数不合法 | 参数校验失败 |
3001 | NOT_LOGIN | 未登录 | 用户未登录 |
3002 | NO_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代码检查清单
提交代码前,请确认以下事项:
- [ ] 代码无编译错误和警告
- [ ] 遵循命名规范
- [ ] 添加必要的注释
- [ ] 异常处理完整
- [ ] 参数校验完整
- [ ] 事务配置正确
- [ ] 删除调试代码
- [ ] 格式化代码