用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/m19803261706/springboot-vben-admin --skill spring-boot-4命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | spring-boot-4 |
| description | Spring Boot 4 后端开发规范。当创建 Controller、Service、Entity、Repository 或后端 API 时自动使用。 |
本项目使用 Spring Boot 4.0.1 + JPA + MySQL 8 技术栈。
| 技术 | 版本 | 用途 |
|---|---|---|
| Spring Boot | 4.0.1 | Web 框架 |
| Spring Data JPA | 3.4.x | 数据访问 |
| Hibernate | 7.x | ORM |
| MySQL | 8.0 | 数据库 |
| JSpecify | 1.0.0 | Null 安全 |
| SpringDoc | 2.8.x | API 文档 |
| Lombok | - | 简化代码 |
backend/src/main/java/com/taichu/yingjiguanli/
├── YingjiGuanliApplication.java # 启动类
├── common/ # 通用类
│ ├── ApiResponse.java # 统一响应
│ ├── BusinessException.java # 业务异常
│ └── PageResult.java # 分页结果
├── config/ # 配置类
│ ├── CorsConfig.java
│ ├── GlobalExceptionHandler.java
│ └── JpaConfig.java
├── modules/ # 业务模块
│ └── {module}/ # 模块名
│ ├── entity/ # 实体类
│ ├── repository/ # 数据访问
│ ├── service/ # 服务层
│ │ └── impl/
│ ├── controller/ # 控制器
│ ├── dto/ # 数据传输对象
│ └── vo/ # 视图对象
└── resources/
├── application.yml
└── db/migration/ # Flyway 迁移
package com.taichu.yingjiguanli.modules.{module}.entity;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Comment;
import org.jspecify.annotations.Nullable;
import java.time.LocalDateTime;
/**
* {实体描述}
*
* @author CX
* @since {date}
*/
@Data
@Entity
@Table(name = "{table_name}")
@Comment("{表描述}")
public class {EntityName} {
/**
* 主键ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Comment("主键ID")
private Long id;
/**
* {字段描述}
*/
@Column(nullable = false, length = 100)
@Comment("{字段描述}")
private String name;
/**
* 创建时间
*/
@Column(nullable = false, updatable = false)
@Comment("创建时间")
private LocalDateTime createdAt;
/**
* 更新时间
*/
@Column(nullable = false)
@Comment("更新时间")
private LocalDateTime updatedAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
}
package com.taichu.yingjiguanli.modules.{module}.repository;
import com.taichu.yingjiguanli.modules.{module}.entity.{EntityName};
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* {实体}数据访问接口
*
* @author CX
* @since {date}
*/
@Repository
public interface {EntityName}Repository extends JpaRepository<{EntityName}, Long>, JpaSpecificationExecutor<{EntityName}> {
/**
* 根据名称查询
*/
Optional<{EntityName}> findByName(String name);
}
package com.taichu.yingjiguanli.modules.{module}.service;
import com.taichu.yingjiguanli.modules.{module}.dto.{EntityName}DTO;
import com.taichu.yingjiguanli.modules.{module}.entity.{EntityName};
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.Optional;
/**
* {实体}服务接口
*
* @author CX
* @since {date}
*/
public interface {EntityName}Service {
/**
* 创建
*/
{EntityName} create({EntityName}DTO dto);
/**
* 更新
*/
{EntityName} update(Long id, {EntityName}DTO dto);
/**
* 删除
*/
void delete(Long id);
/**
* 根据ID查询
*/
Optional<{EntityName}> findById(Long id);
/**
* 分页查询
*/
Page<{EntityName}> findAll(Pageable pageable);
}
package com.taichu.yingjiguanli.modules.{module}.service.impl;
import com.taichu.yingjiguanli.common.BusinessException;
import com.taichu.yingjiguanli.modules.{module}.dto.{EntityName}DTO;
import com.taichu.yingjiguanli.modules.{module}.entity.{EntityName};
import com.taichu.yingjiguanli.modules.{module}.repository.{EntityName}Repository;
import com.taichu.yingjiguanli.modules.{module}.service.{EntityName}Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
/**
* {实体}服务实现
*
* @author CX
* @since {date}
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class {EntityName}ServiceImpl implements {EntityName}Service {
private final {EntityName}Repository repository;
@Override
@Transactional
public {EntityName} create({EntityName}DTO dto) {
log.info("创建{实体}: {}", dto);
{EntityName} entity = new {EntityName}();
// 设置属性...
return repository.save(entity);
}
@Override
@Transactional
public {EntityName} update(Long id, {EntityName}DTO dto) {
log.info("更新{实体} ID={}: {}", id, dto);
{EntityName} entity = repository.findById(id)
.orElseThrow(() -> (, ));
repository.save(entity);
}
{
log.info(, id);
(!repository.existsById(id)) {
(, );
}
repository.deleteById(id);
}
Optional<{EntityName}> findById(Long id) {
repository.findById(id);
}
Page<{EntityName}> findAll(Pageable pageable) {
repository.findAll(pageable);
}
}
package com.taichu.yingjiguanli.modules.{module}.controller;
import com.taichu.yingjiguanli.common.ApiResponse;
import com.taichu.yingjiguanli.common.BusinessException;
import com.taichu.yingjiguanli.modules.{module}.dto.{EntityName}DTO;
import com.taichu.yingjiguanli.modules.{module}.entity.{EntityName};
import com.taichu.yingjiguanli.modules.{module}.service.{EntityName}Service;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
/**
* {实体}控制器
*
* @author CX
* @since {date}
*/
@RestController
@RequestMapping("/api/{module}")
@RequiredArgsConstructor
@Tag(name = "{模块名称}", description = "{模块描述}")
public class {EntityName}Controller {
private final {EntityName}Service service;
/**
* 创建
*/
@PostMapping
@Operation(summary = "创建{实体}")
public ApiResponse<{EntityName}> create(@Valid @RequestBody {EntityName}DTO dto) {
return ApiResponse.success(service.create(dto));
}
/**
* 更新
*/
@PutMapping("/{id}")
@Operation(summary = "更新{实体}")
public ApiResponse<{EntityName}> update(@PathVariable Long id, {EntityName}DTO dto) {
ApiResponse.success(service.update(id, dto));
}
ApiResponse<Void> {
service.delete(id);
ApiResponse.success();
}
ApiResponse<{EntityName}> getById( Long id) {
ApiResponse.success(service.findById(id)
.orElseThrow(() -> (, )));
}
ApiResponse<Page<{EntityName}>> list(Pageable pageable) {
ApiResponse.success(service.findAll(pageable));
}
}
package com.taichu.yingjiguanli.modules.{module}.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
/**
* {实体}数据传输对象
*
* @author CX
* @since {date}
*/
@Data
public class {EntityName}DTO {
/**
* 名称
*/
@NotBlank(message = "名称不能为空")
@Size(max = 100, message = "名称长度不能超过100")
private String name;
// 其他字段...
}
-- V{n}__{description}.sql
-- 作者: CX
-- 日期: {date}
-- 描述: {description}
CREATE TABLE {table_name} (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
name VARCHAR(100) NOT NULL COMMENT '名称',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='{表描述}';
| 位置 | 规范 | 示例 |
|---|---|---|
| 包名 | 小写 | com.taichu.yingjiguanli.modules.user |
| 类名 | PascalCase | UserController, UserService |
| 方法名 | camelCase | findById, createUser |
| 变量名 | camelCase | userName, createdAt |
| 常量名 | UPPER_SNAKE | MAX_PAGE_SIZE |
| 表名 | snake_case | sys_user, t_order |
| 字段名 | snake_case | user_name, created_at |
ApiResponse<T>BusinessException 抛出业务错误@Valid + jakarta.validation@Slf4j 记录日志@Transactional项目: 应急管理系统 (yingjiguanli) 技术栈: Spring Boot 4.0.1 + JPA + MySQL 8