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 的代码生成需求。它特别适合中小型项目或业务模块之间高度耦合的项目,能够有效提高代码的可维护性和开发效率。

相关推荐
bbq粉刷匠21 分钟前
HashMap 底层原理深度拆解(二):putVal 完整链路解析(懒加载 · 链表遍历 · 尾插法)
java·开发语言·哈希算法
Sam_Deep_Thinking28 分钟前
一个靠谱的C端网关服务应该包含什么内容
java·程序员·系统架构
杨运交1 小时前
[055][调度模块]Spring动态任务调度框架的设计与实现
java·后端·spring
白狐_7981 小时前
408 数据结构算法题 01:线性表暴力求解保分指南
java·数据结构·算法
流云鹤1 小时前
03Java学习day(3)
java·学习
tqs_123451 小时前
Agent智能体+Skill插件引擎+Milvus混合检索 技术沉淀
java·python·milvus
严同学正在努力2 小时前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
QQ_21696290963 小时前
Spring Boot 养老院管理系统:从入住、护理到费用结算的全流程实现(源码可领)
java·spring boot·后端
cxoptics3 小时前
冰洲石分束器设计与应用
java
ck-joker3 小时前
M1 Pro跑LLM实测:Ollama+LangChain4j零成本本地大模型开发,比云端API快在哪?
java·语言模型