skills/xu-cell/ai-engineering-init/leniu-java-code-style

leniu-java-code-style

SKILL.md

leniu-tengyun-core 代码风格规范

项目特征

特征 说明
包名前缀 net.xnzn.core.*
JDK 版本 21
Validation jakarta.validation.*
工具库 Hutool (CollUtil, ObjectUtil, BeanUtil)
异常类 LeException
国际化 I18n
租户上下文 TenantContextHolder
分页组件 PageHelper (PageMethod)

包结构规范

net.xnzn.core
├── [module]/
│   ├── controller/         # 控制器层
│   ├── service/            # 服务层
│   │   └── impl/        # 服务实现
│   ├── mapper/             # 数据访问层(含 XML)
│   ├── model/             # 数据模型
│   │   ├── entity/       # 实体类
│   │   └── po/          # 持久化对象
│   ├── vo/                # 视图对象(返回前端)
│   ├── dto/               # 数据传输对象(服务间/MQ)
│   ├── param/             # 请求参数对象
│   ├── constants/          # 常量
│   ├── enums/             # 枚举
│   ├── api/               # 对外 API 接口
│   ├── config/            # 配置类
│   ├── mq/                # 消息队列监听器
│   ├── task/              # 定时任务
│   ├── handle/            # 业务处理器(策略模式)
│   └── util/              # 工具类

类命名规范

类型 命名格式 示例
Controller XxxController OrderController
Service 接口 XxxService OrderService
Service 实现 XxxServiceImpl OrderServiceImpl
Mapper XxxMapper OrderMapper
Entity XxxXxxEntity Order
PO XxxPO OrderPO
VO XxxVO OrderVO
DTO XxxDTO OrderDTO
Param XxxParam / XxxQueryParam OrderQueryParam
Enum XxxEnum OrderStatusEnum
Converter XxxConverter OrderConverter
Handler XxxHandler OrderHandler
Api XxxApi OrderApi

方法命名规范

操作 Service 方法 Mapper 方法 Controller URL
分页查询 pageXxx pageXxx GET /list
查询列表 listXxx listXxx -
查询单个 getXxx selectById GET /{id}
新增 save / add / create insert POST /
更新 update / modify updateById PUT /
删除 delete / remove deleteById DELETE /{ids}
统计 count / summary selectCount -
导出 export - POST /export
同步 sync - -

Controller 层模板

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.xnzn.core.common.exception.LeException;
import net.xnzn.core.common.response.LeResponse;
import net.xnzn.core.order.param.OrderQueryParam;
import net.xnzn.core.order.service.OrderService;
import net.xnzn.core.order.vo.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

@Slf4j
@RequiresAuthentication
@RestController
@RequestMapping("/api/order")
@Api(value = "订单管理", tags = "订单管理")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @ApiOperation(value = "分页查询订单")
    @PostMapping("/list")
    public LeResponse<Page<OrderVO>> list(@Valid @RequestBody OrderQueryParam param) {
        return LeResponse.success(orderService.pageList(param));
    }

    @ApiOperation(value = "获取订单详情")
    @GetMapping("/{id}")
    public LeResponse<OrderVO> getById(@PathVariable Long id) {
        return LeResponse.success(orderService.getById(id));
    }

    @ApiOperation(value = "创建订单")
    @PostMapping("/")
    public LeResponse<Long> create(@Valid @RequestBody OrderParam param) {
        return LeResponse.success(orderService.create(param));
    }

    @ApiOperation(value = "更新订单")
    @PutMapping("/")
    public LeResponse<Boolean> update(@Valid @RequestBody OrderParam param) {
        return LeResponse.success(orderService.update(param));
    }

    @ApiOperation(value = "删除订单")
    @DeleteMapping("/{ids}")
    public LeResponse<Boolean> delete(@PathVariable String ids) {
        return LeResponse.success(orderService.delete(ids));
    }
}

要点

  • 统一使用 @PostMapping(部分查询也可以用 @GetMapping
  • 需要 @RequiresAuthentication 认证注解
  • 使用 LeResponse<T> 封装返回结果
  • 参数校验使用 @Valid 触发

Service 层模板

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import net.xnzn.core.common.exception.LeException;
import net.xnzn.core.order.mapper.OrderMapper;
import net.xnzn.core.order.model.Order;
import net.xnzn.core.order.param.OrderParam;
import net.xnzn.core.order.vo.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    @Lazy
    private ProductService productService;

    @Transactional(rollbackFor = Exception.class)
    public Long create(OrderParam param) {
        // 业务逻辑
        Order order = BeanUtil.copyProperties(param, Order.class);
        orderMapper.insert(order);
        return order.getId();
    }

    public OrderVO getById(Long id) {
        Order order = orderMapper.selectById(id);
        if (ObjectUtil.isNull(order)) {
            throw new LeException("订单不存在");
        }
        return BeanUtil.copyProperties(order, OrderVO.class);
    }

    public List<OrderVO> list(OrderQueryParam param) {
        List<Order> orders = orderMapper.selectList(buildWrapper(param));
        return BeanUtil.copyToList(orders, OrderVO.class);
    }
}

要点

  • 使用 @Slf4j 日志注解
  • 循环依赖使用 @Lazy
  • 事务使用 @Transactional(rollbackFor = Exception.class)
  • 使用 Hutool 工具类:BeanUtilObjectUtil

Entity 实体类模板

import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName(value = "order_table", autoResultMap = true)
public class Order {

    @TableId
    @ApiModelProperty(value = "订单ID")
    private Long id;

    @ApiModelProperty(value = "用户ID")
    private Long userId;

    @ApiModelProperty(value = "订单金额(分)")
    private Long amount;

    @ApiModelProperty(value = "删除标识(1-删除,2-正常)")
    private Integer delFlag;

    @TableField(fill = FieldFill.INSERT)
    @ApiModelProperty(value = "创建人")
    private String crby;

    @TableField(fill = FieldFill.INSERT)
    @ApiModelProperty(value = "创建时间")
    private LocalDateTime crtime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(value = "更新人")
    private String upby;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(value = "更新时间")
    private LocalDateTime uptime;
}

要点

  • 使用 @TableName 指定表名
  • 主键使用 @TableId
  • 字段使用 @TableField 映射
  • 审计字段:delFlag(1=删除,2=正常)、crbycrtimeupbyuptime

VO/DTO 类模板

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@ApiModel("订单信息")
@Accessors(chain = true)
public class OrderVO {

    @ApiModelProperty("订单ID")
    private Long id;

    @ApiModelProperty("用户ID")
    @NotNull(message = "用户ID不能为空")
    private Long userId;

    @ApiModelProperty("订单金额(元)")
    @NotNull(message = "订单金额不能为空")
    @DecimalMin(value = "0.01", message = "金额必须大于0.01")
    private BigDecimal amount;

    @ApiModelProperty("订单状态")
    private Integer status;
}

要点

  • 使用 @ApiModel 类注解
  • 使用 @ApiModelProperty 字段注解
  • 参数校验使用 jakarta.validation.constraints.* 注解
  • 使用 @Accessors(chain = true) 支持链式调用

枚举类模板

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum OrderStatusEnum {

    CREATED(1, "已创建"),
    PAID(2, "已支付"),
    COMPLETED(3, "已完成"),
    CANCELLED(4, "已取消");

    private final Integer key;
    private final String desc;

    public static OrderStatusEnum getByKey(Integer key) {
        if (key == null) {
            return null;
        }
        for (OrderStatusEnum status : values()) {
            if (status.getKey().equals(key)) {
                return status;
            }
        }
        return null;
    }

    public static boolean isExistKey(Integer key) {
        return getByKey(key) != null;
    }
}

要点

  • 使用 @Getter@AllArgsConstructor
  • 提供 getByKey 静态方法
  • 提供 isExistKey 校验方法

依赖注入规范

// 推荐:字段注入
@Autowired
private OrderService orderService;

// 解决循环依赖
@Resource
@Lazy
private ProductService productService;

异常处理

import net.xnzn.core.common.exception.LeException;
import net.xnzn.core.common.i18n.I18n;

// 简单异常
throw new LeException("订单不存在");

// 国际化异常
throw new LeException(I18n.getMessage("order.not.exists"));

// 带参数的国际化
throw new LeException(I18n.getMessage("order.status.invalid", status));

Hutool 工具类速查

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.bean.BeanUtil;

// 集合操作
if (CollUtil.isEmpty(list)) {
    throw new LeException("列表不能为空");
}
if (CollUtil.isNotEmpty(list)) {
    // 处理列表
}

// 对象判空
if (ObjectUtil.isNull(user)) {
    throw new LeException("用户不存在");
}
if (ObjectUtil.isNotNull(user)) {
    // 处理用户
}

// 字符串操作
if (StrUtil.isBlank(name)) {
    throw new LeException("名称不能为空");
}
String trimmed = StrUtil.trim(name);
String joined = StrUtil.join(",", list);

// 对象拷贝
TargetDTO target = BeanUtil.copyProperties(source, TargetDTO.class);
List<TargetDTO> targets = BeanUtil.copyToList(sources, TargetDTO.class);

常用注解

Jakarta Validation

重要:项目使用 JDK 21,必须使用 jakarta.validation.constraints.*

import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
  • @NotNull - 不能为 null
  • @NotBlank - 字符串不能为空
  • @NotEmpty - 集合不能为空
  • @Valid - 触发参数校验

Lombok

  • @Data - 生成 getter/setter
  • @Slf4j - 日志
  • @Builder - 建造者模式
  • @AllArgsConstructor - 全参构造
  • @Accessors(chain = true) - 链式调用

MyBatis-Plus

  • @TableName - 表名映射
  • @TableId - 主键
  • @TableField - 字段映射
  • @TableField(fill = FieldFill.INSERT) - 插入时自动填充
  • @TableField(fill = FieldFill.INSERT_UPDATE) - 更新时自动填充

类注释规范

推荐使用 JavaDoc 标准格式:

/**
 * 类功能描述
 *
 * @author xujiajun
 * @date 2026-02-20
 */
public class OrderService {
    // ...
}

说明

  • @author 使用实际作者名称
  • @date 使用代码创建日期(格式:YYYY-MM-DD

常见错误

错误1:使用 RuoYi 的包名

// ❌ 错误:使用 RuoYi 的包名
package org.dromara.system.service;

// ✅ 正确:使用 leniu 的包名
package net.xnzn.core.order.service;

错误2:使用 javax.validation

// ❌ 错误:使用 javax.validation(JDK 21 应该用 jakarta)
import javax.validation.constraints.NotNull;

// ✅ 正确:使用 jakarta.validation
import jakarta.validation.constraints.NotNull;

错误3:使用 MapstructUtils

// ❌ 错误:使用 RuoYi 的工具类
import org.dromara.common.core.utils.MapstructUtils;
Target target = MapstructUtils.convert(source, Target.class);

// ✅ 正确:leniu 使用 Hutool
import cn.hutool.core.bean.BeanUtil;
Target target = BeanUtil.copyProperties(source, Target.class);

错误4:使用 LeException 不使用 I18n

// ❌ 不推荐:直接硬编码中文
throw new LeException("订单不存在");

// ✅ 推荐:使用国际化
throw new LeException(I18n.getMessage("order.not.exists"));

错误5:使用 RuoYi 的 ServiceException

// ❌ 错误:使用 RuoYi 的异常
import org.dromara.common.core.exception.ServiceException;

// ✅ 正确:使用 leniu 的异常
import net.xnzn.core.common.exception.LeException;

参考文档

详见:leniu-tengyun-core 源码

Weekly Installs
4
GitHub Stars
9
First Seen
9 days ago
Installed on
gemini-cli4
github-copilot4
codex4
kimi-cli4
cursor4
amp4