news 2026/2/3 12:44:30

Spring Boot一课一得:在“约定”中解锁高效开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot一课一得:在“约定”中解锁高效开发

对于spring boot ,我只接触了一个学期,没有太大的了解,作为刚接触Java开发框架的新手,在学Spring Boot前,我对传统Spring项目的配置简直“谈虎色变”。记得第一次尝试搭建简单的Web项目,光是查资料引入Spring MVC、Tomcat的依赖就花了半天,更别提还要写一长串XML配置来“装配Bean”——那些<bean>标签、命名空间看得我眼花缭乱,好不容易写好配置,启动时又因为Spring和依赖包版本不匹配报错,盯着控制台的红色日志半天摸不着头脑。而这堂Spring Boot课程,就像给迷茫的我递了一盏灯,不仅让我快速搭起了能跑的项目,更让我这个新手读懂了“约定优于配置”这种听起来很抽象的设计理念。

课程里最让我惊喜的,是Spring Boot的“起步依赖”。老师在IDEA里只加了一行<spring-boot-starter-web>依赖,点击启动按钮,项目就直接跑起来了——不用手动配Tomcat,不用额外引JSON解析包,甚至能直接写个接口在浏览器里访问。这场景让我想起前几天自己瞎折腾的经历:为了让Spring项目能返回JSON数据,我翻遍论坛才找到匹配的Jackson版本,反复试了五六次才成功。而Spring Boot的起步依赖就像“打包好的工具箱”,通过<spring-boot-dependencies>把常用依赖的版本都协调好了,根本不用我们新手操心版本冲突,终于能把精力放在“怎么写业务逻辑”上,而不是“怎么把框架拼起来”。

自动配置功能则让我觉得Spring Boot“特别聪明”。老师讲数据库连接的时候,我本来做好了记一堆配置参数的准备,结果发现只要在application.properties里写清楚数据库地址、账号密码,项目就能直接连上数据库。老师说这是因为Spring Boot会自动装HikariCP连接池,我追问背后的原因,才知道是<ConditionalOnClass>这些注解在“干活”——只要项目里有数据库相关的类,框架就自动触发配置,要是我们没自己定义连接池,它就用默认的。这对新手太友好了!以前写传统Spring配置,光是数据源的<property>标签就够我抄半天,现在居然“填几个参数就搞定”。这让我明白,“约定优于配置”不是不让我们配置,而是帮新手把“该怎么配”的规矩定好了,少走很多弯路。

实践课上的小失误,反倒让我对框架理解更深了。我照着老师的例子写了个接口,前端同学说跨域访问不了,我当时就慌了——明明代码和老师的一模一样,怎么会出问题?我甚至怀疑是不是Spring Boot有“bug”。后来老师提醒我:“框架的自动配置是‘按约定来的’,跨域这种特殊需求得自己加配置。”他教我用@CrossOrigin注解,或者在配置类里写CORS规则,问题一下子就解决了。这件事让我清醒过来:Spring Boot虽然“省心”,但不是“万能”的。作为新手,不能光会“拿来就用”,还得知道它的“约定”是什么,遇到超出约定的需求时,才知道该怎么调整。就像老师说的:“新手先会用,再懂原理,但不能一直只当‘调包侠’。”

// 控制器类,负责接收请求并返回数据 import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; // @RestController = @Controller + @ResponseBody,自动返回JSON格式数据 @RestController public class HelloController { // @GetMapping表示接收GET请求,路径为/hello @GetMapping("/hello") // @RequestParam获取请求参数,defaultValue设置默认值 public String sayHello(@RequestParam(defaultValue = "Spring Boot新手") String name) { return "你好," + name + "!这是我的第一个Spring Boot接口"; } }

课程最后讲的自定义Starter,让我觉得Spring Boot“潜力好大”。老师说有电商公司把自己常用的日志、监控功能做成了自定义Starter,新人建项目只要引个依赖,这些功能就都有了,新服务上线时间省了一大半。我当时就想:“我这种新手也能做这个吗?”跟着老师的步骤,我试着把课上写的“接口日志打印”功能封装成了简单的Starter——写个自动配置类,加上<AutoConfiguration>注解,再打包成jar包。当我把这个jar包引入另一个项目,不用任何配置,接口调用时控制台就自动打印日志了,那种成就感真的没法说。原来我不光能“用别人的框架”,还能基于框架做自己的小工具,这让我对继续学下去更有动力了。

这堂Spring Boot课,对我这个开发新手来说,不止是学会了一个框架,更像是帮我建立了“高效开发”的思维。以前我总觉得“写代码就是堆配置、抄代码”,现在才知道,好的框架会帮你把重复的工作都做了,你只要专注于解决实际问题。接下来我打算先把课上的知识点吃透,比如老师提到的@ConfigurationProperties怎么用,生产环境里连接池该怎么调参数,这些“细节”对新手来说特别重要。然后我想做几个小项目练手,比如写个简易的待办清单接口,把学到的东西用起来,之后再试着把项目里重复的功能也封装成Starter,慢慢积累自己的“工具库”。

对我来说,Spring Boot的学习才刚刚起步。这堂课最大的收获,是让我这个新手不再害怕框架,知道了“跟着约定走,复杂的事交给框架”。以后开发的时候,我既要学会用框架的“约定”省力气,也要在需要的时候,敢去调整配置、扩展功能。我相信只要一步步来,先会用、再懂原理,总有一天能真正“驾驭”这个强大的框架,而不是只做一个“会点鼠标的新手”。

这一个学期学spring boot,虽然学会的不多,但是有多少收获的,度过了一学期的学习,过的还不错,有挫折,有难度,但是我尽力完成了这个学习的课程。

关键实现(新手重点)

学习价值:掌握MyBatis-Plus简化开发的核心技巧,理解“实体类-服务层-控制器”的分层思想,这是所有Spring Boot项目的基础架构。

案例2:简易个人博客(进阶级·多表关联)

核心功能:包含文章发布、分类管理、标签关联、文章列表分页查询,支持按分类/标签筛选文章,适合作为个人技术博客雏形。

技术栈:Spring Boot 2.7.x + Spring Web + MyBatis-Plus + MySQL + Thymeleaf(前端模板,无需单独写前端接口) + PageHelper(分页插件)。

学习价值:掌握企业级权限控制基础,理解事务管理的重要性,适合作为课程设计或小型团队工具。

学习价值:理解多表关联查询逻辑,掌握分页插件使用,学会用Thymeleaf实现前后端简单结合,也可扩展为前后端分离架构。

案例3:图书管理系统(实用级·权限控制)

核心功能:区分管理员和普通用户权限——管理员可进行图书CRUD、用户管理;普通用户仅能查询图书、借阅/归还图书,包含借阅记录查询。

技术栈:Spring Boot 2.7.x + Spring Web + Spring Security(权限控制) + MyBatis-Plus + MySQL + Bootstrap。

关键实现(新手重点)

学习价值:理解多表关联查询逻辑,掌握分页插件使用,学会用Thymeleaf实现前后端简单结合,也可扩展为前后端分离架构。学习价值(贴合新手成长的真实收获): 1. 突破“单表局限”:这是我第一次接触多表关联,从“一对多”到“多对多”的实现,让我明白“中间表”“外键”不是课本上的抽象概念,而是解决实际问题的工具——就像我给Spring Boot笔记贴“自动配置”“起步依赖”标签,用标签筛选文章时,瞬间懂了多对多的意义; 2. 建立“分层思维”:写服务层时,我刻意把“查文章”“关联分类”“分页”拆成不同方法,不再像刚学的时候把所有代码堆在控制器里,这种“控制器接请求、服务层做逻辑”的分层,和老师说的“企业开发规范”完全对应,以后写简历也有东西可写; 3. 收获“实用成果”:这个博客我现在每天都用——把课堂上的代码案例、配置技巧写成文章,按分类归档,期末复习时直接按“Spring Boot配置”“MyBatis-Plus用法”筛选,比翻笔记快10倍;更意外的是,我把这个项目放到GitHub上,面试时HR特意问了这个案例,说“比空泛的‘掌握Spring Boot’更有说服力”; 4. 降低“技术畏难情绪”:一开始看到“多表关联”“分页”就怕了,拆成小步骤后发现,核心还是之前学的“CRUD+简单循环”,这种“大问题拆小解决”的思路,不仅适用于编程,我后来写课程报告时也用这个方法,效率特别高。 对新手来说,这个案例最大的价值不是“做出一个博客”,而是让我们明白:Spring Boot的进阶知识不用“一步到位”,只要跟着“基础功能→核心难点→实用优化”的节奏走,再复杂的需求也能啃下来。

核心功能:包含文章发布、分类管理、标签关联、文章列表分页查询,支持按分类/标签筛选文章,适合作为个人技术博客雏形。

技术栈:Spring Boot 2.7.x + Spring Web + MyBatis-Plus + MySQL + Thymeleaf(前端模板,无需单独写前端接口) + PageHelper(分页插件)。

关键实现(新手重点)

  1. 依赖管理省心:起步依赖(如spring-boot-starter-web)已打包协调好常用组件版本,避免新手手动引依赖的版本冲突问题,像 “现成工具箱” 直接用。
  2. 配置极度简化:“约定优于配置” 减少冗余操作,如数据库连接仅需在配置文件填地址 / 账号 / 密码,框架自动装配连接池,无需传统 Spring 的繁琐 XML 配置。
  3. 上手快速高效:内嵌 Tomcat 等容器,项目引入依赖后可直接启动,新手无需纠结环境搭建,能快速聚焦业务逻辑开发。
  4. 灵活且易扩展:基础需求 “零配置” 满足,特殊场景(如跨域)可通过简单注解 / 配置扩展,还支持自定义 Starter 封装通用功能,适配不同需求。 对我来说,Spring Boot的学习才刚刚起步。这堂课最大的收获,是让我这个新手不再害怕框架,知道了“跟着约定走,复杂的事交给框架”。以后开发的时候,我既要学会用框架的“约定”省力气,也要在需要的时候,敢去调整配置、扩展功能。我相信只要一步步来,先会用、再懂原理,总有一天能真正“驾驭”这个强大的框架,而不是只做一个“会点鼠标的新手”。更意外的是,Spring Boot不仅帮我掌握了一项技术,还悄悄改变了我的生活节奏和思维方式。作为初学编程的学生,以前总因为搭环境、调配置占用大量时间,常常熬夜赶作业,现在用Spring Boot能快速完成项目demo,不仅作息变规律了,还能腾出时间学前端知识,形成“Java+前端”的技能搭配。这种“高效解决问题”的体验,也让我在生活中养成了“找方法、省力气”的习惯——比如整理笔记时会像Spring Boot的“约定”一样,先定好固定格式,后续补充内容就不用反复纠结排版,做事效率明显提高。在职业规划上,Spring Boot更给了我明确的方向。现在很多企业招聘都把Spring Boot作为基础要求,我用课程里学的知识做了个简易的个人博客接口,放在简历里后,居然收到了小企业的实习面试邀请。对新手来说,这种“学完就能用、能用就有反馈”的正向激励太重要了,它让我不再迷茫“学编程到底有没有用”,也让我明白掌握高效工具,能让自己在职业起步阶段就站稳脚跟。甚至在帮同学解决编程问题时,我能用Spring Boot快速写出示例代码,这种“被需要”的感觉,也让我更有学习动力。

    @RestController public class CrossOriginController { // @CrossOrigin允许跨域访问,origins指定前端地址 @CrossOrigin(origins = "http://127.0.0.1:5500") // 本地前端文件打开的地址 @GetMapping("/user") public String getUserInfo() { return "{'username':'小明','age':20}"; // 模拟返回用户数据 } }

    import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; // @Configuration表示这是配置类,Spring Boot会自动识别 @Configuration public class GlobalCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有接口生效 .allowedOrigins("http://127.0.0.1:5500") // 允许的前端地址 .allowedMethods("GET", "POST") // 允许的请求方式 .allowCredentials(true) // 允许携带Cookie .maxAge(3600); // 跨域配置有效期(秒) } }

    二、代码使用说明

    1. 上述代码均无需额外配置XML,只需在application.properties中添加基础配置(如端口):server.port=8080

    2. 新手可直接在IDEA中创建“Spring Boot Initializr”项目,勾选“Spring Web”依赖,将代码复制到对应包下即可启动;

    3. 若需连接数据库,仅需在配置文件添加:spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=123456,无需手动配置数

    // 控制器类,负责接收请求并返回数据 import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; // @RestController = @Controller + @ResponseBody,自动返回JSON格式数据 @RestController public class HelloController { // @GetMapping表示接收GET请求,路径为/hello @GetMapping("/hello") // @RequestParam获取请求参数,defaultValue设置默认值 public String sayHello(@RequestParam(defaultValue = "Spring Boot新手") String name) { return "你好," + name + "!这是我的第一个Spring Boot接口"; } }

    import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.time.LocalDateTime; // 日志拦截器,拦截接口请求并打印日志 public class LogInterceptor implements HandlerInterceptor { // 接口调用前执行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取接口路径和方法名 String url = request.getRequestURI(); String methodName = handlerMethod.getMethod().getName(); // 打印日志 System.out.println(LocalDateTime.now() + " - 接口被调用:" + url + ",方法名:" + methodName); } return true; // 允许接口继续执行 } }

    关键实现(新手重点)

  5. 依赖引入:除spring-boot-starter-web外,新增MyBatis-Plus起步依赖,无需手动写基础CRUD SQL:mybatis-plus-boot-startermysql-connector-java

  6. 核心代码: ① 实体类(与数据库表映射):import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import lombok.Data;@Data // Lombok注解,自动生成getter/setter,减少代码public class Todo {@TableId(type = IdType.AUTO) // 主键自增private Long id;private String content; // 待办内容private Integer status; // 状态:0未完成,1已完成private LocalDateTime createTime; // 创建时间}② 控制器(接口层,类似前文HelloController):@RestController@RequestMapping("/todo")public class TodoController {@Autowiredprivate TodoService todoService;// 添加待办@PostMappingpublic String addTodo(@RequestBody Todo todo) {todo.setCreateTime(LocalDateTime.now());todo.setStatus(0);todoService.save(todo); // MyBatis-Plus自带save方法return "添加成功";}// 按状态查询(0未完成,1已完成)@GetMapping("/status/{status}")public List<Todo> getTodoByStatus(@PathVariable Integer status) {return todoService.lambdaQuery().eq(Todo::getStatus, status).list(); // 链式查询,无需写SQL} }

    案例2:简易个人博客(进阶级·多表关联)

    核心功能:包含文章发布、分类管理、标签关联、文章列表分页查询,支持按分类/标签筛选文章,适合作为个人技术博客雏形。

    技术栈:Spring Boot 2.7.x + Spring Web + MyBatis-Plus + MySQL + Thymeleaf(前端模板,无需单独写前端接口) + PageHelper(分页插件)。

    关键实现(新手重点)

  7. 多表设计:核心表3张(文章表article、分类表category、标签表tag),通过article_category、article_tag中间表实现多对多关联。

  8. 分页查询实现:引入PageHelper依赖后,仅需一行代码开启分页:// 服务层代码,查询第1页,每页10条数据public PageInfo<Article> getArticlePage(Integer pageNum) {PageHelper.startPage(pageNum, 10); // 分页核心代码List<Article> articleList = articleMapper.selectAll();&#xA; return new PageInfo<>(articleList); // 封装分页结果}

  9. 跨域支持:若后续对接独立前端(如Vue),直接复用前文的GlobalCorsConfig配置类即可解决跨域问题。

  10. 权限配置核心:通过Spring Security配置类实现角色区分,无需手动判断权限:@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN") // 管理员接口仅ADMIN角色可访问.antMatchers("/book/**").hasAnyRole("ADMIN", "USER") // 图书接口两种角色均可访问.anyRequest().authenticated() // 其他请求需登录.and().formLogin(); // 启用默认登录页}}

  11. 借阅业务逻辑:核心判断“图书是否已被借出”,通过事务注解@Transactional保证操作原子性(借阅时同时修改图书状态和新增借阅记录):@Servicepublic class BorrowService {@Autowiredprivate BookMapper bookMapper;@Autowiredprivate BorrowRecordMapper borrowRecordMapper;@Transactional // 事务注解,确保两步操作同时成功或失败public String borrowBook(Long bookId, Long userId) {Book book = bookMapper.selectById(bookId);if (book.getStatus() == 1) { // 1表示已借出return "该图书已被借出";}// 1. 修改图书状态为已借出book.setStatus(1);bookMapper.updateById(book);// 2. 新增借阅记录BorrowRecord record = new BorrowRecord();record.setBookId(bookId);record.setUserId(userId);record.setBorrowTime(LocalDateTime.now());borrowRecordMapper.insert(record);return "借阅成功";} }

  12. @Data@TableName("article") // 明确对应数据库表名,新手别漏写public class Article {@TableId(type = IdType.AUTO)private Long id;private String title;private String content;@TableField("category_id") // 对应数据库的categoryId字段,避免大小写问题private Long categoryId;// 关联分类信息,MyBatis-Plus会自动封装@TableField(exist = false) // 表示数据库表中没有这个字段,仅用于前端展示private Category category;private LocalDateTime createTime;}③ 核心接口实现(和之前写的TodoController逻辑相通): 控制器(ArticleController.java):我特意保留了和待办清单相似的结构,新手能快速复用已有经验:import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;// 注意这里用@Controller,不是@RestController——Thymeleaf需要返回页面路径@Controllerpublic class ArticleController {@Autowiredprivate ArticleService articleService;@Autowiredprivate CategoryService categoryService;// 1. 发布文章页面:携带所有分类数据,供前端下拉选择@GetMapping("/article/add")public String addArticlePage(Model model) {// 把分类列表传给前端,Thymeleaf直接用${categories}获取model.addAttribute("categories", categoryService.list());return "article/add"; // 对应resources/templates下的HTML文件}// 2. 提交发布文章请求@PostMapping("/article/save")public String saveArticle(@RequestParam String title, // 接收前端输入的标题@RequestParam String content, // 接收文章内容@RequestParam Long categoryId) { // 接收选择的分类IDArticle article = new Article();article.setTitle(title);article.setContent(content);article.setCategoryId(categoryId);article.setCreateTime(LocalDateTime.now());articleService.save(article);return "redirect:/article/list"; // 发布后跳转到文章列表页}// 3. 文章列表页(带分类名称展示)@GetMapping("/article/list")public String articleList(Model model) {// 调用服务层方法,查询文章时关联查询分类信息List<Article> articleList = articleService.getArticleWithCategory();model.addAttribute("articles", articleList);return "article/list";}}④ 服务层核心代码(多表关联的关键,新手不用自己写SQL): ArticleService.java:用MyBatis-Plus的LambdaQueryChainWrapper实现关联查询,比写XML简单太多:import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryChainWrapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class ArticleServiceImpl implements ArticleService {@Autowiredprivate ArticleMapper articleMapper;@Autowiredprivate CategoryMapper categoryMapper;// 查询文章并关联分类信息(新手重点看这个方法)@Overridepublic List<Article> getArticleWithCategory() {// 1. 先查所有文章List<Article> articleList = articleMapper.selectList(null);// 2. 循环给每个文章设置对应的分类信息for (Article article : articleList) {// 根据文章的categoryId查分类Category category = categoryMapper.selectById(article.getCategoryId());article.setCategory(category); // 把分类信息存到文章对象里}return articleList;}}这个方法我一开始没想到“循环赋值”这么简单,后来老师说“新手不用急着学复杂的联表查询,先能用基础方法实现功能更重要”,试了之后果然跑通了,特别有信心。

  13. 第二步:攻克“进阶难点”——文章与标签的多对多关联+分页① 多对多核心:中间表设计: 文章和标签是“一篇文章可贴多个标签,一个标签可对应多篇文章”,所以需要一张中间表(article_tag)来关联,表结构只有两个字段:article_id(关联文章表)、tag_id(关联标签表),不用加主键,新手别画蛇添足。② 分页实现(一行代码搞定,新手必学): 之前自己写分页时,算“起始位置”总是出错,用PageHelper后直接省了这个步骤—— 第一步:在pom.xml加依赖(和MyBatis-Plus兼容,不用担心版本问题):<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version> // 这个版本和Spring Boot 2.7.x完美匹配</dependency>第二步:在服务层加分页逻辑(就多了PageHelper.startPage这一行):// 分页查询文章列表,pageNum是当前页码,pageSize是每页条数@Overridepublic PageInfo<Article> getArticlePage(Integer pageNum, Integer pageSize) {// 核心分页代码:告诉插件当前页码和每页条数PageHelper.startPage(pageNum, pageSize);// 下面的查询会自动被分页,和之前查全量列表的代码一样List<Article> articleList = getArticleWithCategory();// 封装分页结果(包含总条数、总页数等信息,前端直接用)&#xA; return new PageInfo<>(articleList);}第三步:控制器接收页码参数,传给前端分页数据:// 分页的文章列表接口@GetMapping("/article/list/page")public String articlePageList(@RequestParam(defaultValue = "1") Integer pageNum, // 默认显示第一页Model model) {PageInfo<Article> pageInfo = articleService.getArticlePage(pageNum, 5); // 每页5条数据model.addAttribute("pageInfo", pageInfo);return "article/list";}③ 前端页面(Thymeleaf新手写法): 列表页(list.html)里用Thymeleaf循环展示文章,分页按钮直接用pageInfo里的属性,不用自己拼URL:<!-- 展示文章列表 --><div th:each="article : ${pageInfo.list}"><h3 th:text="${article.title}"></h3><p>分类:<span th:text="${article.category.name}"></span></p><p th:text="${article.content}"></p></div><!-- 分页按钮 --><a th:href="@{/article/list/page(pageNum=1)}">首页</a><a th:href="@{/article/list/page(pageNum=${pageInfo.prePage})}">上一页</a><span th:text="|当前第 ${pageInfo.pageNum} 页,共 ${pageInfo.pages} 页|"></span><a th:href="@{/article/list/page(pageNum=${pageInfo.nextPage})}">下一页</a><a th:href="@{/article/list/page(pageNum=${pageInfo.pages})}">尾页</a>我写这个页面时,直接把课堂上Thymeleaf的案例改了改,半小时就搞定了,比学Vue快太多,特别适合前端基础弱的新手。

  14. 新手避坑指南(我踩过的坑,帮你省时间): 1. 多表关联时,别忘给实体类的“关联字段”加@TableField(exist = false),否则MyBatis-Plus会误以为数据库有这个字段,报“字段不存在”的错; 2. Thymeleaf页面必须放在resources/templates目录下,否则Spring Boot找不到,我一开始放错文件夹,页面一直404,查了半小时才发现; 3. 分页时如果前端传的页码是null,一定要用@RequestParam(defaultValue = "1")设默认值,否则会报空指针异常,这是老师帮我排查出来的小细节; 4. 想快速测试接口,直接用之前学的Swagger,加个依赖就能在线调接口,不用再开Postman,省了切换工具的时间。

  15. 多表设计:核心表3张(文章表article、分类表category、标签表tag),通过article_category、article_tag中间表实现多对多关联。

  16. 分页查询实现:引入PageHelper依赖后,仅需一行代码开启分页:// 服务层代码,查询第1页,每页10条数据public PageInfo<Article> getArticlePage(Integer pageNum) {PageHelper.startPage(pageNum, 10); // 分页核心代码List<Article> articleList = articleMapper.selectAll();&#xA; return new PageInfo<>(articleList); // 封装分页结果}

  17. 跨域支持:若后续对接独立前端(如Vue),直接复用前文的GlobalCorsConfig配置类即可解决跨域问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/2 23:52:56

Docker + Vercel AI SDK环境变量配置终极方案(附完整CI/CD流程代码)

第一章&#xff1a;Docker 与 Vercel AI SDK 的环境变量概述在现代全栈应用开发中&#xff0c;Docker 和 Vercel AI SDK 的结合为开发者提供了高效、可移植的部署方案与强大的生成式 AI 能力。环境变量作为连接本地开发与生产部署的关键桥梁&#xff0c;承担着配置管理、密钥隔…

作者头像 李华
网站建设 2026/2/3 1:07:16

10 个专科生降AIGC工具推荐,AI写作优化神器

10 个专科生降AIGC工具推荐&#xff0c;AI写作优化神器 论文写作的困境&#xff1a;时间、重复率与降重的三重挑战 对于专科生来说&#xff0c;论文写作从来不是一件轻松的事。从选题到文献综述&#xff0c;再到撰写和修改&#xff0c;每一个环节都充满了挑战。尤其是在任务书阶…

作者头像 李华
网站建设 2026/2/2 22:59:05

哈希加密:给数据按下“唯一指纹”的魔法

你有没有想过&#xff0c;为什么登录网站时系统总能“认出”你的密码&#xff0c;但即使网站管理员也看不到你的密码原文&#xff1f;为什么下载大型文件时&#xff0c;官方会提供一串“验证码”让你核对&#xff1f;这一切的背后&#xff0c;都归功于一项被称为哈希加密的技术…

作者头像 李华
网站建设 2026/2/2 23:54:01

【零基础学java】(小疑问和几个水算法题)

浅浅计算一下自己活了多久吧&#xff0c;哈哈。这里的重点&#xff0c;把字符串表示的出生日期这个字符串变成Date对象&#xff0c;再用get方法获取到毫秒值&#xff0c;JDK以前的时间类&#xff0c;都要先获取对应的毫秒值补充&#xff08;由此可见打好基础的重要性&#xff0…

作者头像 李华