SpringBoot 3 + MyBatis-Plus 全栈项目实战:从零搭建企业级应用

SpringBoot 3 + MyBatis-Plus 全栈项目实战:从零搭建企业级应用

Ethan
2025-04-10 发布 / 正在检测是否收录...

SpringBoot 3 + MyBatis-Plus 是目前 Java 后端开发中最流行的技术组合。本文将从零开始,带你搭建一个具备完整前后端分离能力的企业级项目,涵盖项目结构设计、数据库操作、权限认证和部署方案。

项目初始化:最佳实践的项目结构

src/main/java/com/example/project/\n├── config/          # 配置类(Security、CORS、MyBatis-Plus)\n├── controller/      # 控制器层\n├── service/         # 服务接口\n│   └── impl/        # 服务实现\n├── mapper/          # MyBatis Mapper 接口\n├── entity/          # 数据库实体\n├── dto/             # 数据传输对象\n├── vo/              # 视图对象(返回给前端)\n├── common/          # 公共类(统一响应、异常处理)\n│   ├── Result.java\n│   ├── GlobalExceptionHandler.java\n│   └── PageResult.java\n└── utils/           # 工具类

MyBatis-Plus:告别手写 SQL

1. 基础配置

// application.yml\nspring:\n  datasource:\n    url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4\n    username: root\n    password: ${DB_PASSWORD}\nmybatis-plus:\n  configuration:\n    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # SQL 日志\n    map-underscore-to-camel-case: true  # 下划线转驼峰\n  global-config:\n    db-config:\n      logic-delete-field: deleted  # 逻辑删除字段\n      logic-delete-value: 1\n      logic-not-delete-value: 0

2. 实体与 Mapper

// User.java - 实体类\n@Data\n@TableName("t_user")\npublic class User {\n    @TableId(type = IdType.AUTO)\n    private Long id;\n    private String username;\n    @TableField(select = false)  // 查询时排除密码\n    private String password;\n    private String email;\n    @TableField(fill = FieldFill.INSERT)\n    private LocalDateTime createTime;\n    @TableField(fill = FieldFill.INSERT_UPDATE)\n    private LocalDateTime updateTime;\n    @TableLogic  // 逻辑删除\n    private Integer deleted;\n}\n\n// UserMapper.java - 一行代码完成 CRUD\n@Mapper\npublic interface UserMapper extends BaseMapper {\n    // 继承 BaseMapper 后自动拥有 CRUD 方法\n    // 复杂查询在这里自定义\n    @Select("SELECT * FROM t_user WHERE email = #{email}")\n    User selectByEmail(@Param("email") String email);\n}

3. 分页查询(一行代码)

// Controller\n@GetMapping("/list")\npublic Result> list(\n    @RequestParam(defaultValue = "1") Integer page,\n    @RequestParam(defaultValue = "10") Integer size,\n    @RequestParam(required = false) String keyword\n) {\n    Page pageParam = new Page<>(page, size);\n    LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();\n    if (keyword != null) {\n        wrapper.like(User::getUsername, keyword)\n               .or().like(User::getEmail, keyword);\n    }\n    wrapper.orderByDesc(User::getCreateTime);\n    return Result.success(userService.page(pageParam, wrapper));\n}

统一响应与异常处理

// Result.java - 统一响应格式\n@Data\npublic class Result {\n    private Integer code;\n    private String message;\n    private T data;\n\n    public static  Result success(T data) {\n        Result r = new Result<>();\n        r.code = 200; r.message = "success"; r.data = data;\n        return r;\n    }\n    public static  Result error(String message) {\n        Result r = new Result<>();\n        r.code = 500; r.message = message;\n        return r;\n    }\n}\n\n// GlobalExceptionHandler.java - 全局异常处理\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n    @ExceptionHandler(Exception.class)\n    public Result handleException(Exception e) {\n        log.error("系统异常", e);\n        return Result.error("服务器内部错误");\n    }\n    @ExceptionHandler(MethodArgumentNotValidException.class)\n    public Result handleValidation(MethodArgumentNotValidException e) {\n        String msg = e.getBindingResult().getFieldErrors()\n            .stream().map(FieldError::getDefaultMessage)\n            .collect(Collectors.joining(", "));\n        return Result.error(msg);\n    }\n}

Spring Security + JWT 认证

// SecurityConfig.java\n@Configuration\n@EnableWebSecurity\npublic class SecurityConfig {\n    @Bean\n    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {\n        http\n            .csrf(AbstractHttpConfigurer::disable)\n            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n            .authorizeHttpRequests(auth -> auth\n                .requestMatchers("/api/auth/**").permitAll()\n                .requestMatchers("/api/admin/**").hasRole("ADMIN")\n                .anyRequest().authenticated()\n            )\n            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);\n        return http.build();\n    }\n}\n\n// JwtUtil.java\n@Component\npublic class JwtUtil {\n    @Value("${jwt.secret}")\n    private String secret;\n\n    public String generateToken(Long userId, String username) {\n        return Jwts.builder()\n            .setSubject(String.valueOf(userId))\n            .claim("username", username)\n            .setIssuedAt(new Date())\n            .setExpiration(new Date(System.currentTimeMillis() + 7200000)) // 2小时\n            .signWith(Keys.hmacShaKeyFor(secret.getBytes()))\n            .compact();\n    }\n}

前后端分离项目部署

Docker Compose 一键部署

# docker-compose.yml\nversion: '3.8'\nservices:\n  mysql:\n    image: mysql:8.0\n    environment:\n      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}\n    volumes:\n      - mysql_data:/var/lib/mysql\n\n  backend:\n    build: ./backend\n    ports:\n      - "8080:8080"\n    depends_on:\n      - mysql\n    environment:\n      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb\n\n  frontend:\n    build: ./frontend\n    ports:\n      - "80:80"\n    depends_on:\n      - backend\n\nvolumes:\n  mysql_data:

总结

SpringBoot 3 + MyBatis-Plus 的组合让 Java 后端开发变得异常高效——MyBatis-Plus 消除了 80% 的 CRUD 样板代码,SpringBoot 3 的自动配置让你专注于业务逻辑。但高效不等于简单:理解 Spring 的 IoC 容器、AOP 切面编程、事务传播机制,才能真正驾驭这套技术栈。

© 版权声明
THE END
喜欢就支持一下吧
点赞 1 分享 收藏

评论 (0)

取消

Warning: file_put_contents(/var/www/html/usr/cache/pagecache/ac/aced154c6f69b0606ad4fab0b9bd9574.cache): failed to open stream: No such file or directory in /var/www/html/usr/plugins/PageCache/Plugin.php on line 188