从零搭建企业级Java Web项目:Spring Boot+MyBatis-Plus实战指南

📅 2026/7/30 8:53:19
从零搭建企业级Java Web项目:Spring Boot+MyBatis-Plus实战指南
1. 项目概述与核心价值最近在带新人发现很多朋友对如何从零开始搭建一个完整的、可落地的企业级项目感到无从下手。正好手头有一个“苍穹外卖”的实战项目它本质上是一个模拟外卖平台的后台管理系统涵盖了从用户下单、商家接单到骑手配送的全流程。今天我就以这个项目为例拆解一下一个标准Java Web项目的搭建全过程。这不仅仅是打开IDE新建一个工程那么简单它涉及到技术选型的权衡、项目结构的规划、依赖管理的规范以及如何避免那些新手常踩的“坑”。无论你是想学习Spring Boot、MyBatis-Plus还是想了解前后端分离项目如何协同这个搭建过程都能给你一个清晰的骨架。我会把每一步背后的“为什么”讲清楚并提供可以直接“抄作业”的配置和命令让你不仅能搭起来更能理解其中的门道。2. 项目整体设计与技术栈选型2.1 核心业务模型与架构思路“苍穹外卖”作为一个典型的外卖平台后台其核心业务模型围绕“订单”展开。我们需要管理用户、商家、骑手三类核心角色处理菜品、购物车、订单、配送等实体。在架构上我们选择目前最主流的单体应用分层架构而非微服务。对于大多数中小型项目或教学项目而言单体架构结构清晰、部署简单、调试方便是快速启动和验证业务逻辑的最佳选择。分层上我们采用经典的Controller-Service-DaoMapper三层配合DTOData Transfer Object进行层间数据传输确保职责分离。2.2 后端技术栈详解与选型理由后端我们选择Spring Boot 2.7.x作为基础框架。它提供了“约定大于配置”的极简风格内嵌Tomcat让我们免去了繁琐的XML配置和服务器部署的麻烦能专注于业务开发。为什么不是最新的3.x2.7.x是长期支持版本社区资源、第三方依赖兼容性都更为成熟稳定对于学习和企业级项目都是更稳妥的选择。数据持久层我们选用MyBatis-Plus。相比原生的MyBatisMP提供了强大的CRUD封装和条件构造器能极大减少模板代码的编写。例如我们不需要手动写简单的insert、selectById语句MP的BaseMapper已经提供。它的LambdaQueryWrapper更是能让我们以Java Lambda表达式的方式安全地构建查询条件避免SQL注入的同时代码可读性极高。数据库自然是MySQL 8.0。它拥有完善的生态、强大的事务支持对我们订单系统至关重要以及合理的性能。搭配Druid作为数据库连接池Druid提供了强大的监控和防SQL注入功能是生产环境中的可靠选择。2.3 前端技术栈与前后端分离模式前端我们使用Vue 3和Element Plus组件库。Vue 3的Composition API让逻辑组织更灵活配合TypeScript能提升代码的健壮性。Element Plus提供了丰富且美观的UI组件能快速搭建出符合企业规范的管理后台界面。这里要明确我们采用前后端完全分离的模式。前端项目独立运行在一个端口中如localhost:8081通过Axios发送HTTP请求调用后端API运行在localhost:8080。两者通过JSON进行数据交互后端只负责提供RESTful API不涉及任何前端页面渲染。这种模式利于前后端并行开发和独立部署。2.4 辅助工具链配置项目构建工具选用Maven。虽然Gradle也很流行但Maven在Java生态中的普及率更高其基于XML的pom.xml依赖声明方式对于初学者来说结构更直观。我们会统一管理所有第三方库的版本避免依赖冲突。开发工具是IntelliJ IDEA Ultimate。它对于Spring Boot和Maven的支持是无与伦比的智能提示、代码生成、一键运行和调试功能能极大提升开发效率。数据库可视化工具推荐Navicat或DBeaver用于直观地管理MySQL数据库。版本控制毫无疑问是Git代码托管平台可以选择Gitee或GitHub。从项目一开始就使用Git进行版本管理是良好的开发习惯。3. 开发环境准备与项目初始化3.1 基础软件安装与配置首先确保你的机器上已经安装了JDK 8或11。我推荐JDK 11它是另一个长期支持版本在性能和特性上取得了很好的平衡。安装后务必在命令行中执行java -version和javac -version来验证。接着安装Maven 3.6。下载后解压需要配置环境变量MAVEN_HOME并将其bin目录添加到PATH中。安装完成后在命令行运行mvn -v检查。这里有个关键点需要配置Maven的本地仓库路径和镜像源。打开Maven安装目录下conf/settings.xml文件修改localRepository标签指定一个非系统盘的路径如D:\maven-repo避免C盘空间被占满。同时在mirrors标签内添加阿里云镜像这将使依赖下载速度飞升。mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirrorMySQL 8.0的安装过程中记得记下你设置的root密码。安装完成后建议使用命令行或工具创建一个专门用于本项目的数据库例如sky_take_out并设置字符集为utf8mb4排序规则为utf8mb4_general_ci以支持存储Emoji等四字节字符。IntelliJ IDEA安装后需要做一些初始优化在File - Settings - Build, Execution, Deployment - Build Tools - Maven中将Maven home path、User settings file和Local repository指向你刚才配置的位置。这样IDEA就会使用我们配置好的镜像和仓库了。3.2 使用Spring Initializr快速初始化项目这是搭建项目的关键第一步。我们不用手动创建目录和文件而是借助Spring官方提供的Spring Initializr。有两种方式一是通过IDEA内置的创建向导New Project - Spring Initializr二是直接访问 start.spring.io 网站生成后下载。在配置页面我们需要填写和选择以下信息Project: Maven ProjectLanguage: JavaSpring Boot: 2.7.x (选择最新的2.7.x版本如2.7.18)Project Metadata:Group:com.sky(通常用公司或组织域名倒写)Artifact:sky-take-out(项目名推荐使用中划线分隔)Name:sky-take-outPackage name:com.sky(与Group一致)Packaging: Jar (Spring Boot推荐的可执行Jar包)Java: 11在Dependencies中我们添加初始依赖。这里不必一次性加全先加入最核心的Spring Web(用于构建Web API)MyBatis Framework(基础MyBatis支持)MySQL Driver(MySQL数据库连接驱动)点击生成你会得到一个标准的Spring Boot项目压缩包。用IDEA打开这个项目等待Maven自动下载完所有依赖。打开pom.xml你应该能看到刚才选择的依赖已经被引入。注意很多新手在这一步会遇到“Maven报错”比如依赖下载失败、红线等。99%的原因有两个一是网络问题Maven中央仓库访问慢或失败。请务必确认上一步的阿里云镜像配置正确并生效。二是IDEA的Maven配置未生效。请检查IDEA的设置并尝试点击Maven工具栏的“刷新”按钮一个循环箭头图标或者右键点击pom.xml选择Maven - Reload project。3.3 项目目录结构规范项目初始化后标准的目录结构如下。理解每个目录的用途至关重要sky-take-out/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com.sky/ │ │ │ ├── SkyTakeOutApplication.java # Spring Boot主启动类 │ │ │ ├── config/ # 配置类目录如Web配置、MyBatis配置 │ │ │ ├── controller/ # 控制层接收请求调用Service │ │ │ ├── service/ # 业务逻辑层接口 │ │ │ │ └── impl/ # 业务逻辑层实现类 │ │ │ ├── mapper/ # 数据访问层接口 (MyBatis Mapper) │ │ │ ├── entity/ # 实体类与数据库表对应 │ │ │ ├── dto/ # 数据传输对象用于前后端或层间传输 │ │ │ ├── vo/ # 视图对象用于封装返回给前端的数据 │ │ │ └── common/ # 通用工具类、常量、异常定义等 │ │ └── resources/ │ │ ├── static/ # 静态资源 (CSS, JS, 图片) │ │ ├── templates/ # 模板文件 (如Thymeleaf本项目用不到) │ │ ├── mapper/ # MyBatis的XML映射文件 (如果用XML方式) │ │ └── application.yml # 主配置文件 (推荐YAML格式比properties更清晰) │ └── test/ # 测试代码目录 └── pom.xml # Maven项目对象模型文件我个人的习惯是在com.sky下严格按照这个结构创建包。清晰的目录结构是团队协作和项目可维护性的基石。4. 核心配置与数据库连接4.1 全局配置文件 application.yml 详解Spring Boot的配置中心是application.yml或application.properties。我强烈推荐使用YAML格式因为它支持层级结构写起来更直观。我们将主要配置放在这里。首先配置服务器端口和数据源。在src/main/resources/application.yml中写入server: port: 8080 # 后端应用启动端口 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver # MySQL 8 驱动类 url: jdbc:mysql://localhost:3306/sky_take_out?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghai username: root # 你的数据库用户名 password: your_password # 你的数据库密码 # 配置Druid连接池需先引入依赖 druid: initial-size: 5 min-idle: 5 max-active: 20 test-on-borrow: true关键点解释useSSLfalse: 本地开发环境通常不启用SSL加密连接可以关闭以简化配置。生产环境必须为true并配置证书。serverTimezoneAsia/Shanghai: 这至关重要它确保JDBC连接使用东八区时间避免数据库时间和Java程序时间不一致导致的日期时间问题。很多诡异的日期错误都源于此。characterEncodingutf-8: 保证连接使用UTF-8编码防止中文乱码。4.2 集成MyBatis-Plus并配置接下来我们需要将初始化的MyBatis Framework依赖替换为功能更强大的MyBatis-Plus。在pom.xml中找到mybatis-spring-boot-starter依赖将其替换为dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version !-- 使用与Spring Boot 2.7兼容的稳定版本 -- /dependency然后在application.yml中继续添加MyBatis-Plus的配置mybatis-plus: configuration: # 控制台打印执行的SQL语句及其参数开发阶段极其有用 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启驼峰命名自动映射。数据库字段是user_name实体类属性是userNameMP会自动映射。 map-underscore-to-camel-case: true global-config: db-config: # 全局主键类型。AUTO表示数据库ID自增这是最常用的方式。 id-type: auto # 逻辑删除字段名如果表中有is_deleted字段 logic-delete-field: isDeleted # 逻辑删除值删除后该字段的值 logic-delete-value: 1 # 逻辑未删除值 logic-not-delete-value: 0 # 指定Mapper接口对应的XML文件位置。如果你用注解方式写SQL可以不用配。 mapper-locations: classpath:mapper/*.xml4.3 创建启动类与测试连接主启动类SkyTakeOutApplication.java在项目初始化时已经生成。我们需要在其中添加MapperScan注解告诉Spring Boot去哪里扫描MyBatis的Mapper接口。package com.sky; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication MapperScan(com.sky.mapper) // 指定Mapper接口所在的包 public class SkyTakeOutApplication { public static void main(String[] args) { SpringApplication.run(SkyTakeOutApplication.class, args); } }现在右键点击这个类选择Run ‘SkyTakeOutApplication‘。如果控制台没有报错并且最后出现类似Started SkyTakeOutApplication in 5.123 seconds (JVM running for 6.456)的日志说明Spring Boot应用启动成功。为了测试数据库连接是否真正通畅我们可以创建一个简单的测试。在test目录下新建一个测试类package com.sky; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; SpringBootTest class SkyTakeOutApplicationTests { Autowired private DataSource dataSource; Test void contextLoads() throws SQLException { // 尝试获取一个数据库连接 Connection connection dataSource.getConnection(); System.out.println(数据库连接成功连接对象 connection); connection.close(); // 记得关闭连接 } }运行这个测试方法如果成功打印出连接信息恭喜你后端项目的基础骨架和数据库连接已全部就绪。5. 前后端分离配置与联调准备5.1 解决跨域问题 (CORS)由于前端项目运行在localhost:8081后端在localhost:8080浏览器出于安全考虑会阻止这种跨域请求。我们必须在后端配置CORS跨源资源共享。创建一个配置类WebMvcConfigurationpackage com.sky.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; Configuration public class WebMvcConfiguration implements WebMvcConfigurer { Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) // 对所有接口路径生效 .allowedOriginPatterns(*) // 允许所有来源。生产环境应替换为具体的前端地址 .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) // 允许的HTTP方法 .allowedHeaders(*) // 允许所有请求头 .allowCredentials(true) // 允许携带Cookie等凭证 .maxAge(3600); // 预检请求的缓存时间(秒) } }; } }实操心得开发阶段可以暂时允许所有来源*但上线前务必修改allowedOriginPatterns为确切的前端域名或IP这是重要的安全措施。allowCredentials(true)和allowedOriginPatterns(*)不能同时使用但Spring Boot 2.4.3的allowedOriginPatterns支持通配符解决了此问题。5.2 统一响应结果封装为了让前端处理响应更规范我们需要定义一个统一的数据返回格式。通常包含状态码、提示信息和数据体。package com.sky.result; import lombok.Data; import java.io.Serializable; Data public class ResultT implements Serializable { private Integer code; // 状态码1成功0失败 private String msg; // 提示信息 private T data; // 返回的数据 public static T ResultT success() { ResultT result new Result(); result.code 1; result.msg 成功; return result; } public static T ResultT success(T object) { ResultT result new Result(); result.code 1; result.msg 成功; result.data object; return result; } public static T ResultT error(String msg) { ResultT result new Result(); result.code 0; result.msg msg; return result; } }在Controller中我们就可以这样返回GetMapping(/user/{id}) public ResultUser getUserById(PathVariable Long id) { User user userService.getById(id); return Result.success(user); }5.3 集成Swagger/knife4j生成API文档前后端协作清晰的API文档必不可少。我们集成knife4j它是Swagger的增强版界面更友好。首先在pom.xml中添加依赖dependency groupIdcom.github.xiaoymin/groupId artifactIdknife4j-spring-boot-starter/artifactId version3.0.3/version /dependency然后创建一个配置类Knife4jConfigurationpackage com.sky.config; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; Configuration EnableSwagger2 EnableKnife4j public class Knife4jConfiguration { Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage(com.sky.controller)) // 扫描的Controller包路径 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(苍穹外卖项目接口文档) .version(1.0) .description(苍穹外卖项目接口文档供前端开发人员查阅) .build(); } }启动项目后访问http://localhost:8080/doc.html就能看到美观的API文档界面了。你可以在Controller的方法上使用Api、ApiOperation等注解来丰富文档说明。6. 常见问题排查与实战技巧6.1 依赖下载失败与版本冲突这是新手最高频的问题。除了检查镜像源还要学会看IDEA的Maven面板。如果某个依赖一直下载失败可以尝试在本地仓库D:\maven-repo中找到对应的文件夹整个删除然后重新刷新Maven项目。检查pom.xml中依赖的版本号是否与其他依赖的传递依赖冲突。使用mvn dependency:tree命令查看依赖树找到冲突的依赖然后用exclusions标签排除掉冲突的版本。6.2 数据库连接失败错误信息可能五花八门如Access denied、Communications link failure。检查四要素URL、用户名、密码、数据库名。确保数据库sky_take_out已创建。检查MySQL服务是否已启动可以在服务管理里查看或命令行net start mysql。检查时区配置务必在JDBC URL中加上serverTimezoneAsia/Shanghai。检查驱动类MySQL 8.0使用的是com.mysql.cj.jdbc.Driver不是旧的com.mysql.jdbc.Driver。6.3 端口被占用如果启动时报错Web server failed to start. Port 8080 was already in use.说明8080端口被其他程序可能是你之前未关闭的Spring Boot应用占用了。解决方案一在application.yml中修改server.port为其他端口如8082。解决方案二推荐找到并关闭占用端口的进程。在命令行执行Windows:netstat -ano | findstr :8080找到PID然后taskkill /PID [PID] /FMac/Linux:lsof -i :8080找到PID然后kill -9 [PID]6.4 MyBatis-Plus 常见问题实体类与表字段映射不上确保实体类属性使用了TableField注解指定数据库字段名如果不符合驼峰规则或者全局配置map-underscore-to-camel-case: true已开启。插入时ID不自动递增确保数据库表主键设置了AUTO_INCREMENT并且实体类主键字段使用了TableId(type IdType.AUTO)注解。逻辑删除不生效除了在application.yml中配置还需要在实体类的对应字段如isDeleted上添加TableLogic注解。6.5 前端请求后端接口失败检查网络请求打开浏览器开发者工具F12切换到Network网络选项卡查看发送的请求。重点看状态码404接口路径错误、500服务器内部错误、403可能跨域或权限问题。请求URL是否和后端RequestMapping定义的路径完全一致包括大小写。请求头特别是Content-Type如果是POST提交JSON应该是application/json。查看后端日志IDEA控制台会打印详细的错误堆栈信息这是定位Bug的最直接依据。学会阅读和理解堆栈信息是后端开发的必备技能。6.6 项目结构规划建议在真正开始编码前花点时间规划好包结构。我建议除了基础的三层还可以考虑common/constant存放业务常量如订单状态枚举。common/exception自定义全局异常和异常处理器。common/utils工具类如日期处理、加密解密、JWT工具等。aspect存放切面用于统一日志、权限校验等。interceptor拦截器用于登录校验、权限验证。一个清晰、可扩展的目录结构能让后续的开发和维护事半功倍。