springboot 项目的包结构设计(二)

在 Spring Boot 项目中,以下是几个包结构设计。

  1. 基于领域驱动设计和分层架构的包结构(上一篇介绍)
  2. 基于功能分层而非按业务模块的包结构

基于功能分层而非按业务模块的包结构

为了减少包重复冗余,同时保持代码组织清晰并适配 MyBatis Dynamic SQL,下面设计了一种按功能分层而非按业务模块分包的优化结构。这种结构既保持了代码的清晰组织,又避免了模块化分包带来的冗余问题。

优化后的包结构设计

bash 复制代码
src/main/java
└── com
    └── example
        └── demo
            ├── Application.java                  # 启动类
            │
            ├── config                            # 配置类
            │   ├── MyBatisDynamicConfig.java
            │   ├── WebMvcConfig.java
            │   └── SecurityConfig.java
            │
            ├── common                            # 公共模块
            │   ├── annotation                    # 自定义注解
            │   ├── constant                      # 常量
            │   ├── enums                         # 枚举类
            │   │   ├── AppErrorCode.java
            │   │   └── ErrorCode.java            
            │   ├── exception                     # 异常处理
            │   │   ├── GlobalExceptionHandler.java
            │   │   └── BusinessException.java
            │   ├── model                         # 公共模型
            │   │   ├── page                      # 分页相关
            │   │   │   ├── PageRequest.java
            │   │   │   ├── PageResult.java
            │   │   │   └── PaginationUtils.java
            │   │   ├── response                  # 响应封装
            │   │   │   ├── Result.java
            │   │   └── validation                # 验证工具
            │   └── util                          # 工具类
            │
            ├── controller                        # 控制器层
            │   ├── UserController.java
            │   ├── ProductController.java
            │   └── ...
            │
            ├── service                           # 服务层
            │   ├── UserService.java
            │   ├── ProductService.java
            │   └── impl                          # 服务实现
            │       ├── UserServiceImpl.java
            │       ├── ProductServiceImpl.java
            │       └── ...
            │
            ├── repository                        # 数据访问层
            │   ├── generated                     # MyBatis Generator 生成 MyBatis Dynamic SQL 代码
            │   │   ├── UserMapper.java
            │   │   ├── UserDynamicSqlSupport.java
            │   │   ├── ProductMapper.java
            │   │   ├── ProductDynamicSqlSupport.java            
            │   │   └── ...
            │   ├── custom                        # 自定义Mapper接口
            │   │   ├── UserCustomMapper.java
            │   │   ├── ProductCustomMapper.java
            │   │   └── ...
            │   │   └──builder                          # 构建 SelectStatementProvider
            │   │       ├── UserQueryBuilder.java
            │   │       ├── ProductQueryBuilder.java
            │   │       └── ...
            │   │
            ├── model                             # 数据模型层
            │   ├── entity                        # 实体类 (MyBatis Generator 生成)
            │   │   ├── UserEntity.java
            │   │   ├── ProductEntity.java
            │   │   └── ...
            │   ├── dto                           # 数据传输对象
            │   │   ├── request                   # 请求DTO
            │   │   │   ├── UserCreateRequest.java
            │   │   │   ├── UserUpdateRequest.java
            │   │   │   ├── UserQueryRequest.java
            │   │   │   └── ...
            │   │   └── response                  # 响应DTO
            │   │       ├── UserResponse.java
            │   │       ├── ProductResponse.java
            │   │       └── ...
            │   └── query                         # 查询条件封装
            │       ├── UserQueryCondition.java
            │       ├── ProductQueryCondition.java
            │       └── ...
            │
            └── converter                         # 对象转换器
                ├── UserConverter.java
                ├── ProductConverter.java
                └── ...

src/main/resources
├─ application.yml      // 配置文件
└─ generatorConfig.xml  // MyBatis Generator 配置

优势与特点

  1. 避免包冗余:按功能分层而非按业务模块分包,减少重复结构
  2. 分层清晰:按功能(controller/service/repository)而非业务模块分包
  3. 代码组织清晰:相同功能的类放在同一包下,便于查找和维护
  4. 高度可扩展:新增业务只需添加新类,无需创建新包结构
  5. 适配 MyBatis Dynamic SQL
    • 生成的代码放在 repository/generated
    • 自定义Mapper接口与生成的代码分离
  6. 统一分页处理
    • 基础 Mapper 接口提供通用分页方法
    • 分页请求类可扩展特定字段验证
  7. 类型安全
    • 使用 MyBatis Dynamic SQL 构建类型安全的查询
    • DTO 与实体分离,明确职责边界
  8. 易于维护
    • 对象转换器集中处理模型转换
    • 仓储实现封装数据访问细节

分页查询流程

sequenceDiagram participant Client participant Controller participant Service participant Repository participant Mapper participant DB Client->>Controller: GET /users?page=2&size=5&username=alice Controller->>Service: UserQueryRequest Service->>Repository: findByCondition(condition, request) Repository->>Mapper: selectPage(completer, pageRequest) Mapper->>Mapper: 1. 执行count查询 Mapper->>DB: SELECT COUNT(*) FROM user WHERE ... DB-->>Mapper: 48 Mapper->>Mapper: 2. 执行分页查询 Mapper->>DB: SELECT * FROM user WHERE ... LIMIT 5,5 DB-->>Mapper: List<UserEntity> Mapper-->>Repository: PageResult<UserEntity> Repository-->>Service: PageResult<UserEntity> Service->>Service: 转换为PageResult<UserResponse> Service-->>Controller: PageResult<UserResponse> Controller-->>Client: 200 OK + JSON

这种非模块化分包结构既保持了代码的清晰组织,又避免了模块化分包带来的冗余问题,同时完美适配了 MyBatis Dynamic SQL 的代码生成需求。它特别适合中小型项目或业务模块之间高度耦合的项目,能够有效提高代码的可维护性和开发效率。

相关推荐
孙克旭_27 分钟前
Docker 镜像构建|Vue+SpringBoot+Go 多语言项目 Dockerfile 案例
linux·运维·vue.js·spring boot·docker·dockerfile
2602_9599609234 分钟前
谢飞机面试大厂:Spring Boot、JVM、Redis、Kafka、微服务与音视频搜索场景求生实录
java·jvm·spring boot·redis·面试题
Zane19941239 分钟前
CAS 与原子类:Java 如何实现无锁编程
java·开发语言
略略略咯咯1 小时前
AI玩具-study
java
xier_ran2 小时前
【infra之路】GPU 存储层次总结:L1 / L2 / HBM
java·网络·数据库
wuminyu3 小时前
JDK21中虚拟线程和FFM协同实现高并发源码剖析
java·linux·c语言·jvm·c++
SWAGGY..3 小时前
【C++进阶】:(1)继承机制详解
java·jvm·c++
码匠许师傅3 小时前
【C++ 面试真题】27. 聊聊 C++ 的内存泄漏与内存布局
java·c++·面试
山甫aa3 小时前
Javaweb---MyBatis增删改查
java·数据库·后端·mybatis·springboot
PPPPickup4 小时前
金证秋招笔试
java·开发语言