后端项目结构
本文档详细介绍 youlai-boot 项目的目录结构和各模块职责。
整体结构
youlai-boot
├── sql/ # SQL 脚本
│ └── youlai.sql # 数据库表结构和初始数据
├── src/
│ ├── main/
│ │ ├── java/com/youlai/boot/
│ │ │ ├── common/ # 公共模块
│ │ │ ├── core/ # 核心模块
│ │ │ ├── system/ # 系统模块
│ │ │ └── YoulaiBoot Application.java
│ │ └── resources/
│ │ ├── mapper/ # MyBatis XML 映射文件
│ │ ├── application.yml # 主配置文件
│ │ ├── application-dev.yml # 开发环境配置
│ │ └── application-prod.yml # 生产环境配置
│ └── test/ # 测试代码
├── target/ # 编译输出目录
├── pom.xml # Maven 配置
└── README.md # 项目说明核心模块详解
1. common 模块(公共模块)
公共模块包含项目中通用的配置、工具类和基础组件。
common/
├── annotation/ # 自定义注解
│ ├── PreventDuplicateResubmit.java # 防重复提交
│ ├── RepeatSubmit.java # 防重复提交(旧)
│ └── Log.java # 操作日志注解
├── base/ # 基础类
│ ├── BaseEntity.java # 实体基类
│ ├── BasePageQuery.java # 分页查询基类
│ └── IBaseEnum.java # 枚举接口
├── config/ # 全局配置
│ ├── RedisConfig.java # Redis 配置
│ ├── WebMvcConfig.java # Web MVC 配置
│ ├── MybatisPlusConfig.java # MyBatis-Plus 配置
│ ├── JacksonConfig.java # Jackson 配置
│ └── Knife4jConfig.java # 接口文档配置
├── constant/ # 常量定义
│ ├── RedisConstants.java # Redis 键常量
│ ├── SecurityConstants.java # 安全常量
│ └── SystemConstants.java # 系统常量
├── enums/ # 枚举类
│ ├── StatusEnum.java # 状态枚举
│ ├── GenderEnum.java # 性别枚举
│ └── ResultCode.java # 响应码枚举
├── exception/ # 异常处理
│ ├── BusinessException.java # 业务异常
│ ├── GlobalExceptionHandler.java # 全局异常处理器
│ └── ServiceException.java # 服务异常
├── model/ # 公共模型
│ ├── Result.java # 统一响应结果
│ ├── PageResult.java # 分页结果
│ └── Option.java # 下拉选项
└── util/ # 工具类
├── JwtUtils.java # JWT 工具
├── SecurityUtils.java # 安全工具
├── BeanUtils.java # Bean 工具
└── JsonUtils.java # JSON 工具关键类说明
BaseEntity.java - 实体基类
java
@Data
public class BaseEntity {
@TableId(type = IdType.AUTO)
private Long id;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
}Result.java - 统一响应结果
java
@Data
public class Result<T> {
private String code;
private String msg;
private T data;
public static <T> Result<T> success() {
return success(null);
}
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMsg(ResultCode.SUCCESS.getMsg());
result.setData(data);
return result;
}
public static <T> Result<T> failed(String msg) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SYSTEM_EXECUTION_ERROR.getCode());
result.setMsg(msg);
return result;
}
}2. core 模块(核心模块)
核心模块包含安全认证、过滤器等核心功能。
core/
├── security/ # 安全配置
│ ├── SecurityConfig.java # Spring Security 配置
│ ├── JwtAuthenticationTokenFilter.java # JWT 认证过滤器
│ ├── RestAuthenticationEntryPoint.java # 认证入口点
│ └── RestfulAccessDeniedHandler.java # 访问拒绝处理器
├── filter/ # 过滤器
│ ├── TraceIdFilter.java # 链路追踪过滤器
│ └── XssFilter.java # XSS 过滤器
└── handler/ # 处理器
├── MyMetaObjectHandler.java # 字段自动填充
└── GlobalResponseHandler.java # 全局响应处理SecurityConfig.java - 安全配置
java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/auth/**").permitAll()
.requestMatchers("/doc.html", "/webjars/**", "/v3/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthenticationTokenFilter(),
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}3. system 模块(系统模块)
系统模块包含用户、角色、菜单、部门等业务功能。
system/
├── controller/ # 控制器层
│ ├── AuthController.java # 认证控制器
│ ├── UserController.java # 用户控制器
│ ├── RoleController.java # 角色控制器
│ ├── MenuController.java # 菜单控制器
│ ├── DeptController.java # 部门控制器
│ └── DictController.java # 字典控制器
├── service/ # 服务层
│ ├── AuthService.java # 认证服务
│ ├── UserService.java # 用户服务
│ ├── RoleService.java # 角色服务
│ ├── MenuService.java # 菜单服务
│ └── impl/ # 实现类
│ ├── AuthServiceImpl.java
│ ├── UserServiceImpl.java
│ └── ...
├── mapper/ # 数据访问层
│ ├── UserMapper.java
│ ├── RoleMapper.java
│ ├── MenuMapper.java
│ └── ...
├── model/ # 模型类
│ ├── entity/ # 实体类
│ │ ├── SysUser.java
│ │ ├── SysRole.java
│ │ └── ...
│ ├── form/ # 表单类
│ │ ├── UserForm.java
│ │ └── ...
│ ├── query/ # 查询类
│ │ ├── UserPageQuery.java
│ │ └── ...
│ └── vo/ # 视图对象
│ ├── UserVO.java
│ └── ...
└── converter/ # 对象转换器
├── UserConverter.java
└── ...分层架构
Controller 层(控制器层)
负责接收HTTP请求,参数验证,调用Service层处理业务逻辑,返回响应结果。
java
@RestController
@RequestMapping("/api/v1/users")
@Tag(name = "用户管理")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/page")
@Operation(summary = "用户分页列表")
public Result<PageResult<UserVO>> getUserPage(UserPageQuery query) {
PageResult<UserVO> result = userService.getUserPage(query);
return Result.success(result);
}
@PreAuthorize("hasAuthority('sys:user:add')")
@PostMapping
@Operation(summary = "新增用户")
public Result<Void> addUser(@Valid @RequestBody UserForm form) {
userService.saveUser(form);
return Result.success();
}
}Service 层(服务层)
负责业务逻辑处理,事务控制,调用Mapper层进行数据操作。
java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private UserConverter userConverter;
@Override
public PageResult<UserVO> getUserPage(UserPageQuery query) {
// 分页查询
Page<SysUser> page = userMapper.selectPage(
new Page<>(query.getPageNum(), query.getPageSize()),
new LambdaQueryWrapper<SysUser>()
.like(StringUtils.hasText(query.getKeywords()),
SysUser::getUsername, query.getKeywords())
);
// 转换为 VO
PageResult<UserVO> result = PageResult.of(page);
List<UserVO> records = userConverter.entity2VO(page.getRecords());
result.setList(records);
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveUser(UserForm form) {
SysUser entity = userConverter.form2Entity(form);
userMapper.insert(entity);
}
}Mapper 层(数据访问层)
负责数据库操作,继承 MyBatis-Plus 的 BaseMapper。
java
@Mapper
public interface UserMapper extends BaseMapper<SysUser> {
/**
* 获取用户分页列表
*/
Page<UserVO> getUserPage(
Page<UserVO> page,
@Param("query") UserPageQuery query
);
}配置文件说明
application.yml - 主配置
yaml
spring:
application:
name: youlai-boot
profiles:
active: dev # 激活的环境
server:
port: 8989
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0application-dev.yml - 开发环境
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/youlai
username: root
password: 123456
data:
redis:
host: localhost
port: 6379最佳实践
1. 命名规范
- 实体类(Entity):以表名命名,驼峰格式,如
SysUser - 表单类(Form):实体名 + Form,如
UserForm - 查询类(Query):实体名 + Query,如
UserPageQuery - 视图对象(VO):实体名 + VO,如
UserVO
2. 包结构规范
- 同一业务模块的类放在同一包下
- 按层次分包:controller、service、mapper、model
- model 包按类型分包:entity、form、query、vo
3. 接口设计规范
- RESTful 风格:GET查询、POST新增、PUT修改、DELETE删除
- 统一前缀:
/api/v1/ - 资源名用复数:
/users、/roles
