用Trae生成Spring Boot后端:从零搭建前后端分离的CRUD实战
2026/9/8 4:22:59 网站建设 项目流程

简介:这是一套借助Trae工具自动生成Spring Boot后端程序的示例工程,面向正在学习前后端分离开发或希望提升脚手架使用效率的Java开发者,也适合需要参考分层代码组织的初中级学习者。压缩包内有20个文件,以xml工程配置、java源码和properties配置为主,另含接口测试说明文档,整体大小只有10KB,属于轻量级工程模板。项目以学生管理场景为例,自动生成的代码覆盖实体类、数据访问接口、服务层、控制器及启动配置,能够直观看出Trae根据数据模型生成可运行的增删改查后端骨架。同时,工程内包含Maven项目结构、开发环境配置文件与接口测试文档,方便导入IDE后对照检查依赖关系和调用链路,也可以作为手工编写与自动生成代码差异对比的参考。目前已有939人学习下载,适合作为自动化代码生成入门及Spring Boot快速上手的参考资料。

1. 动手前先把需求和环境理清楚

1.1 Trae 不是替你思考,是帮你加速

先说结论:Trae 这类 AI 编程工具,真正的价值不在于"一键生成一个完整项目",而在于把那些重复、琐碎、写起来没技术含量但又不得不写的代码,快速变成可运行的产物,让你把精力留在业务设计上。

这次我用 Trae 生成一个前后端分离的 Web 应用程序中的后端程序,技术栈选的是市场上最顺手的组合:Spring Boot + MyBatis-Plus + MySQL。为什么选这套?一是生态成熟,招人好招;二是 Trae 对 Spring Boot 的理解足够深,生成出来的代码质量明显比早期 AI 编程工具高一个档次;三是前后端分离场景下,后端只需要把接口吐出来,前端用 Vue 或者其他框架都无所谓,恰好是 Spring Boot 最擅长的领域。

我建议你试的时候,别一上来就喊"帮我写个后端",那样出来的东西大概率是玩具。先花十分钟想清楚:这个后端要管什么数据、要提供哪些接口、给谁调用。需求越具体,Trae 生成的东西越能用。

1.2 本地环境准备清单

在用 Trae 之前,先把下面这些东西准备好。很多新手在这步翻车,后面全乱套。

工具版本建议说明
JDK1.8 或 17如果用 Spring Boot 2.7.x 就配 JDK 8,用 3.x 就配 JDK 17
Maven3.6+构建和依赖管理,装完记得配国内镜像
MySQL5.7 或 8.0本地数据库
Trae最新版下载安装后,建议登录自己的账号,保证 Builder 模式可用
IDEA 或 VSCode任意建议和 Trae 配合用一个编辑器,省得来回切

这里有个关键点:Trae 本身是一个编辑器形态的 AI 工具,它带了 Builder 模式,能自动写代码、建文件、甚至跑命令。但生成的 Maven 项目,你最终还是可以用 IDEA 打开去调。我个人的习惯是:让 Trae 负责"生成",IDEA 负责"运行和调试",这样出了问题比较好定位。

1.3 先定义一个小而完整的后端需求

不要一上来就搞大而全的系统,新手做前后端分离实战,最合适的项目是一个"用户管理 + 图书管理"的 CRUD 后端。

为什么选这个?因为它覆盖了后端开发的核心要素:

  • 实体类和数据库表的映射
  • 增删改查的基础接口
  • 分页查询
  • 统一返回格式
  • 跨域配置(前后端分离必踩的坑)
  • 接口文档

把这些跑通了,再做复杂业务就是往上叠加的事。我的需求清单是这样的:

做一个图书管理系统后端,提供用户注册登录、图书的增删改查、分页查询、根据书名模糊搜索这几个功能。数据库用 MySQL,表设计用 user 和 book 两张表。

把这个需求描述给 Trae 之后,剩下的事就是一步步引导它干活。

2. 用 Trae 生成 Spring Boot 项目骨架

2.1 在 Trae 里创建项目与对话约定

打开 Trae,新建一个文件夹作为项目根目录,比如book-system-backend。然后在 Trae 的对话框里,我建议按这个套路提需求:

创建一个 Spring Boot 项目,使用 Maven 构建,JDK 版本 17,Spring Boot 版本 2.7.18。集成 MyBatis-Plus 和 Lombok,包名用 com.example.booksystem。项目路径放在当前目录。

注意几个措辞细节:

  • 明确 JDK 版本和 Spring Boot 版本,避免 AI 选一个最新版然后踩兼容性的坑。
  • 明确包名,这样生成出来的代码结构统一。
  • 明确"放在当前目录"而不是让它新建一个子目录,否则后续路径很乱。

Trae 在 Builder 模式下会自己创建 pom.xml、启动类、application.yml,然后告诉你"项目已生成,接下来要做什么"。这个过程很快,基本在一分钟以内。

2.2 用 Trae 生成 pom.xml 和启动类

Trae 生成的 pom.xml 核心部分是这样的:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>

这里我特意选了 2.7.18 而不是 Spring Boot 3.x,主要是为了少踩坑:3.x 里javax变成jakarta,很多老教程代码直接导入会报错。如果你是在学习阶段,用 2.7.x 最省心。

启动类基本不用怎么管,Trae 生成的代码一定是标准写法:

@SpringBootApplication @MapperScan("com.example.booksystem.mapper") public class BookSystemApplication { public static void main(String[] args) { SpringApplication.run(BookSystemApplication.class, args); } }

要注意@MapperScan这个注解是 MyBatis-Plus 扫描 Mapper 接口用的,没加这个,后面启动会报"找不到 mapper bean"。

2.3 配置文件与数据源初始化

application.yml 是数据库连接的关键。Trae 生成的默认配置往往是 H2 内存数据库,我们要改成 MySQL。这一步我不会直接让它"改配置",而是给出完整的 yml 内容让它写进去,避免它自己发挥:

server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/book_system?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0

几个细节值得说:

  • map-underscore-to-camel-case是让数据库的user_name自动映射到 Java 的userName,少写很多@TableField注解。
  • logic-delete-field: deleted是配置逻辑删除,就是删除记录时改成打标记,而不是物理删掉。这个在管理系统中几乎是标配,Trae 对 MyBatis-Plus 的配置理解没毛病,但如果你不说它不会主动加。
  • 数据库book_system要自己手动建好,密码改成你自己的。

3. 核心业务代码的自动生成

3.1 实体类与表结构设计

表结构我沿用经典设计,然后在对话里直接告诉 Trae:

我有 user 和 book 两张表,user 表字段包括 id、username、password、nickname、created_at、deleted;book 表字段包括 id、title、author、price、publish_date、created_at、deleted。帮我生成对应的实体类和建表 SQL。

这一步 Trae 会帮你生成实体类,同时把建表 SQL 也写在注释里。实际上我更建议 SQL 自己先跑一遍,因为 AI 生成的类型映射偶尔会有小问题,比如Decimal映射成Double而不是BigDecimal。价格这种字段,用BigDecimal才是正确的选择,如果你发现 Trae 生成的是Double,直接告诉它"price 字段改成 BigDecimal"就行。

生成的 User 实体大致长这样:

@Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String username; private String password; private String nickname; private LocalDateTime createdAt; @TableLogic private Integer deleted; }

3.2 通用返回体与统一异常处理

这是我自己在项目中一直坚持的部分,也是 Trae 生成得比较"看心情"的部分。不是它不会写,而是它默认生成的内容比较朴素,需要你明确提要求。

我给它的话是:

写一个统一返回体 Result ,包含 code、message、data 三个字段,提供 success 和 error 静态方法。同时写一个全局异常处理器 GlobalExceptionHandler,处理参数校验异常和业务异常。

几十秒后,Result 类出来了,核心代码如下:

@Data public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.setCode(200); result.setMessage("操作成功"); result.setData(data); return result; } public static <T> Result<T> error(Integer code, String message) { Result<T> result = new Result<>(); result.setCode(code); result.setMessage(message); return result; } }

全局异常处理器的价值在于:没有它,后端一报错直接把异常堆栈抛给前端,前后端联调就是灾难。有它之后,前端拿到的永远是结构化的 JSON 错误信息,问题定位容易得多。

3.3 用户模块和图书模块的 Controller、Service、Mapper

骨架和基础配置就绪后,业务代码的生成才是这次实操的重头戏。我继续在对话框下发指令:

生成 UserController、UserService、UserMapper,提供注册、登录两个接口。注册时用户名不能重复,密码用 MD5 加密,登录时校验用户名密码是否匹配。返回 Result 类型。

Trae 做的事是帮你把整个链路都建起来,包括 Mapper 接口(继承 BaseMapper)、Service 接口和实现类、Controller 类。不用你一步步去建文件、写 import,这是它比"问一句答一句"的普通 AI 对话模式强的地方。

这里有几个我在实操中验证过的重点经验:

  • 密码加密不要用 MD5,至少用 BCrypt。我一开始习惯性让 Trae 写 MD5,后来意识到这是坏习惯。你可以在生成完代码后,手动把加密方式改成BCryptPasswordEncoder,再把三处调用点改过来。改起来其实很快,但安全等级完全不同。
  • Controller 里不要写业务逻辑,只做参数接收和结果返回。Trae 生成的代码偶尔会偷懒把业务逻辑全塞进 Controller 里,你可以检查一遍并让它"抽取到 Service 层"。
  • 登录接口返回的密码字段要置空。这是一个非常常见的低级问题:查询出来的 User 对象直接返回给前端,密码也带出去了。让 Trae 在返回前把 password 设为 null 或者写一个UserVO只返回需要的字段。

图书模块也是类似的套路。分页查询那部分,MyBatis-Plus 自带Page对象,代码很简洁:

public Page<Book> pageBooks(int pageNum, int pageSize, String keyword) { Page<Book> page = new Page<>(pageNum, pageSize); LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>(); if (StringUtils.hasText(keyword)) { wrapper.like(Book::getTitle, keyword).or().like(Book::getAuthor, keyword); } return bookMapper.selectPage(page, wrapper); }

从 Trae 生成到我可以运行,整个过程不到二十分钟。它生成代码的速度是真的快,但你要保持清醒,知道它在干什么。我见过不少朋友让 AI 写完后直接启动,报错了就喊"AI 生成的代码不行"。其实不是不行,是你没告诉它上下文和约束条件。

4. 接口联调与前后端分离的关键配置

4.1 跨域配置必须一次做对

前后端分离项目里,跨域是绕不开的问题。前端跑在http://localhost:5173(Vue 默认端口),后端跑在http://localhost:8080,这种"不同端口即不同源"的情况,浏览器会拦截 AJAX 请求。

Trae 生成的跨域配置有两种路径。第一种是写一个CorsConfig配置类,第二种是在 Controller 上加@CrossOrigin注解。我的建议是用全局配置类,一次性解决所有接口的跨域问题,而不是每个 Controller 都去加注解。

我给 Trae 的指令是:

添加一个 WebMvcConfigurer 的配置类,允许所有来源的跨域请求,允许所有请求头,允许 GET、POST、PUT、DELETE 方法,暴露所有响应头。

生成的代码大致如下:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

需要注意allowCredentials(true)allowedOriginPatterns("*")的组合。如果你用了allowedOrigins("*"),在开启凭据时会报错,必须改成allowedOriginPatterns。这个坑很隐蔽,Trae 第一次生成的配置大概率就是报错的那种,需要你手动改一下。

4.2 统一接口风格与前端适配

除了跨域,前后端对接还有一个隐蔽问题:接口返回格式不一致。前端写起来最舒服的格式是{ code: 200, message: "操作成功", data: { list: [], total: 0 } },所以后端做分页查询时,Result里的 data 就不能直接放Page对象,而是要放一个包含listtotal的 Map 或者PageVO

我让 Trae 把分页接口的数据结构调整成前端友好的格式:

@GetMapping("/page") public Result<Map<String, Object>> page(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize, @RequestParam(required = false) String keyword) { Page<Book> result = bookService.pageBooks(pageNum, pageSize, keyword); Map<String, Object> data = new HashMap<>(); data.put("list", result.getRecords()); data.put("total", result.getTotal()); return Result.success(data); }

这个改动看起来很小,但直接决定了你联调的时候顺不顺手。如果前端拿到的 total 藏在data.total里还是data.data.total里,就得看后端心情了。先和后端商量好统一格式再动手写前端,是前后端分离实战里最重要的一条潜规则。

4.3 接口自测:用 Apifox 把接口跑通

代码写完不代表工作结束。我在每次让 Trae 生成完接口后,都会用 Apifox(或者 Postman)把接口全部打一遍。我的测试顺序和关注点如下:

  1. 先测注册接口,看返回是否成功、密码字段是否没暴露。
  2. 再测登录接口,拿到 token 后再测需要鉴权的接口。
  3. 测图书的增删改查,每测完一个接口就刷新一次数据库看数据变化是否符合预期。
  4. 测分页接口,传入keyword参数,看模糊搜索有没有生效。
  5. 故意传错误参数(比如把pageSize传成 0),看全局异常处理器有没有兜住。

如果你想让 Trae 顺便帮你生成接口文档,可以在对话框里加一句"集成 Knife4j,生成接口文档",它会自动加入依赖和配置。启动项目后访问http://localhost:8080/doc.html,就能看到所有接口的在线文档。这对前后端分离项目来说,是给前端同学提供的最大善意。

5. 踩坑记录与排查技巧实录

5.1 Spring Boot 2.7 和 JDK 17 的组合

这个组合本身是兼容的,但有几个细节容易踩。如果你本机装的是 JDK 17,而 pom 里 Spring Boot 是 2.7.x,需要注意 Lombok 插件版本要足够新(1.18.30 以上),否则 IDE 里会报诡异错误。让 Trae 生成 pom 时如果用 2.7.18,Lombok 是默认带好版本的,一般没问题。

如果启动时看到java.lang.reflect.InaccessibleObjectException,别慌,多半是 JDK 模块化导致反射受限。解决方案有两个:一是换 JDK 8,二是给 Maven 加 JVM 参数--add-opens。我的偷懒方案是:直接降级到 JDK 8,对 Spring Boot 2.7 来说完全够用,省心。

5.2 Maven 依赖下载慢或失败

这是国内环境的老大难问题。如果你发现 Trae 生成项目后,Maven 一直在下载依赖且速度感人,建一个~/.m2/settings.xml,把中央仓库换成阿里云镜像:

<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>

改完记得重启 IDE 或者重新加载 Maven 工程。这个配置属于一次配好、终身受益的那种。

5.3 Trae 生成代码的"幻觉"环节

再智能的工具也有瞎编的时候。我遇到过比较典型的情况是:让 Trae 写一个"根据用户名查找用户"的方法,它写的 SQL 是SELECT * FROM user WHERE username = ?,没问题;但如果你让它写复杂一点的连表查询,它给出的 SQL 可能跟你的表名、字段名对不上,甚至表名大小写不一致导致报错。

排查这类问题没有捷径,只有一个土办法:SQL 自己跑一遍,接口自己调一遍,把 Trae 生成的东西当成"应该能跑但不保证能跑"的代码来对待。

5.4 常见错误速查表

报错信息原因处理方法
Field 'id' doesn't have a default value实体类主键策略不对@TableIdtype = IdType.AUTO
Cause: java.sql.SQLSyntaxErrorException: Table 'book_system.book' doesn't exist表名拼写或库名不对检查数据库名字和表名是否一致
NoSuchBeanDefinitionException: UserMapper忘了@MapperScan或者 Mapper 接口没加@Mapper启动类加@MapperScan("com.example.booksystem.mapper")
Failed to configure a DataSource: 'url' attribute is not specifiedapplication.yml 里的数据源配置没生效检查配置文件是不是被当成 .txt 了,以及是否放在 resources 下
Access denied for user 'root'@'localhost'MySQL 密码不对检查 yml 里的密码,或者用命令行连一下数据库验证

5.5 让 Trae 生成代码更靠谱的三个建议

最后分享三个我自己摸索出来的使用心得,对新手特别管用。

第一,把需求写完整再提交。你给 Trae 的提示越完整,它返回的结果就越贴近你的预期。一次把表结构、接口签名、返回格式说清楚,比让它来回猜十次有效得多。

第二,让 Trae 一步步来。如果你一口气让它"做一个完整的图书管理系统后端",它大概率会生成一堆你没有要求的代码。把任务拆成"先建项目骨架""再生成用户模块""再生成图书模块"这样的小步骤,每一轮都能及时发现问题,也方便你学清楚每一步。

第三,把 Trae 生成的代码当作 DIY 模型的说明书,而不是成品。AI 编程工具提升的是效率下限,而决定质量上限的,永远是你的代码规范和业务理解。我在每次生成后都会做一轮代码审查,该抽的方法抽取,该删的注释删掉,该补充的校验补上。这个习惯保留下来,才不会让项目变成"能跑但没人敢动"的屎山。

我自己实际操作下来,用 Trae 生成一个前后端分离项目的后端,从零到接口全部跑通,大约一个半小时,其中一半时间花在联调和排查上。对于还在学习 Spring Boot 的朋友,我的建议是别把它当"代写作业的工具",而是当"随叫随到的结对编程伙伴",让它解释代码、让它出多种写法、让它帮你重构,这才是使用这类工具最划算的方式。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询