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 Mapper-->>Repository: PageResult Repository-->>Service: PageResult Service->>Service: 转换为PageResult Service-->>Controller: PageResult Controller-->>Client: 200 OK + JSON

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

相关推荐
胚芽鞘6814 小时前
关于java项目中maven的理解
java·数据库·maven
岁忧5 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
CJi0NG5 小时前
【自用】JavaSE--算法、正则表达式、异常
java
Hellyc5 小时前
用户查询优惠券之缓存击穿
java·redis·缓存
今天又在摸鱼6 小时前
Maven
java·maven
老马啸西风6 小时前
maven 发布到中央仓库常用脚本-02
java·maven
代码的余温6 小时前
MyBatis集成Logback日志全攻略
java·tomcat·mybatis·logback
ladymorgana6 小时前
【spring boot】三种日志系统对比:ELK、Loki+Grafana、Docker API
spring boot·elk·grafana
一只叫煤球的猫7 小时前
【🤣离谱整活】我写了一篇程序员掉进 Java 异世界的短篇小说
java·后端·程序员
斐波娜娜7 小时前
Maven详解
java·开发语言·maven