当前位置: 首页 > news >正文

SpringBoot学习第三天|CRUD接口实战+MyBatis-Plus整合(附原理+面试高频题)

SpringBoot学习第三天|CRUD接口实战+MyBatis-Plus整合(附原理+面试高频题)

哈喽,各位一起学SpringBoot的小伙伴~ 今天是SpringBoot系列学习的第三天,承接前两天的自动装配、Bean生命周期核心原理,今天我们落地实战+深挖底层——从0到1实现一套生产级CRUD接口,整合MyBatis-Plus简化开发,同时拆解CRUD底层原理、MyBatis-Plus核心机制,同步配套面试高频题,兼顾“实战落地”和“面试备考”,新手能上手,备考能提分!

先明确本期核心目标,避免盲目学习:

  • 实战:整合SpringBoot + MyBatis-Plus,实现用户模块CRUD(增删改查),支持分页、条件查询

  • 原理:吃透MyBatis-Plus整合原理、CRUD接口底层执行流程、分页插件工作机制

  • 面试:掌握CRUD相关面试高频题(如分页实现、逻辑删除、MyBatis和MyBatis-Plus区别),记住满分答案

  • 避坑:梳理实战中常见错误(如映射异常、分页失效),给出解决方案

一、前置准备(衔接前期,快速上手)

基于第一天搭建的SpringBoot基础项目,新增3个核心依赖(pom.xml),无需手动配置MyBatis核心文件,MyBatis-Plus会自动适配,这也是它简化开发的核心优势之一。

<!-- MyBatis-Plus 核心依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1&lt;/version&gt;
&lt;/dependency&gt;
<!-- 数据库驱动(MySQL 8.0+) -->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope&gt;runtime&lt;/scope&gt;
&lt;/dependency&gt;
<!--  lombok(简化实体类,减少get/set) -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

核心配置(application.properties),配置数据库连接和MyBatis-Plus基础参数,重点注意时区和映射路径:


# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# MyBatis-Plus 配置
# 映射文件路径(若有XML映射文件,需配置)
mybatis-plus.mapper-locations=classpath:mapper/**/*.xml
# 实体类别名包(简化XML中的类路径)
mybatis-plus.type-aliases-package=com.bailu12.springbootdemo.entity
# 日志打印SQL(便于调试,开发环境开启,生产环境关闭)
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

二、实战:实现CRUD接口(从实体类到接口测试)

采用“实体类 → Mapper → Service → Controller”四层架构,贴合企业开发规范,MyBatis-Plus提供的BaseMapper、IService可直接复用CRUD方法,无需手动写SQL,大幅提升开发效率。

1. 第一步:创建实体类(Entity)

对应数据库user表,使用lombok的@Data简化get/set,MyBatis-Plus注解指定表名、主键策略(面试高频考点)。


package com.bailu12.springbootdemo.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;@Data // lombok注解,自动生成get/set/toString等方法
@TableName("user") // 指定对应数据库表名(若实体类名与表名一致,可省略)
public class User {// 主键注解,指定主键策略:自增(MySQL常用)@TableId(type = IdType.AUTO)private Long id;// 普通字段,若实体类字段与表字段一致,可省略@TableFieldprivate String username;private String password;private String email;private Integer age;// 逻辑删除字段(面试高频),0=未删除,1=已删除@TableLogicprivate Integer isDeleted;// 自动填充字段(创建时间、更新时间),无需手动赋值@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;
}

2. 第二步:创建Mapper接口

继承MyBatis-Plus的BaseMapper,无需写任何方法,即可获得CRUD基础能力(底层原理后续拆解)。


package com.bailu12.springbootdemo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bailu12.springbootdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;// @Mapper:标识该接口是MyBatis的Mapper接口,SpringBoot会自动扫描并注入容器
@Mapper
public interface UserMapper extends BaseMapper<User> {// 无需手动写CRUD方法,BaseMapper已封装好
}

3. 第三步:创建Service层

Service层负责业务逻辑处理,继承IService,实现类继承ServiceImpl,复用BaseMapper的方法,同时可扩展自定义业务。


// 接口
package com.bailu12.springbootdemo.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.bailu12.springbootdemo.entity.User;public interface UserService extends IService<User> {// 可扩展自定义业务方法,如:根据年龄查询用户User selectByAge(Integer age);
}// 实现类
package com.bailu12.springbootdemo.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bailu12.springbootdemo.entity.User;
import com.bailu12.springbootdemo.mapper.UserMapper;
import com.bailu12.springbootdemo.service.UserService;
import org.springframework.stereotype.Service;@Service // 标识为Service组件,Spring自动注入
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {// 自定义业务方法:根据年龄查询用户(示例)@Overridepublic User selectByAge(Integer age) {// 用MyBatis-Plus的条件构造器QueryWrapper,无需写SQLreturn lambdaQuery().eq(User::getAge, age).one();}
}

4. 第四步:创建Controller层(CRUD接口)

编写RESTful风格接口,对应增删改查,使用@RestController返回JSON数据,接口测试用Postman即可。


package com.bailu12.springbootdemo.controller;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bailu12.springbootdemo.entity.User;
import com.bailu12.springbootdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/user") // 接口统一前缀
public class UserController {// 注入Service@Autowiredprivate UserService userService;// 1. 新增用户(POST)@PostMappingpublic boolean addUser(@RequestBody User user) {// save()方法来自IService,自动填充createTime/updateTimereturn userService.save(user);}// 2. 删除用户(DELETE)- 逻辑删除(面试重点)@DeleteMapping("/{id}")public boolean deleteUser(@PathVariable Long id) {// removeById()默认执行逻辑删除,而非物理删除return userService.removeById(id);}// 3. 更新用户(PUT)@PutMappingpublic boolean updateUser(@RequestBody User user) {// updateById()自动填充updateTimereturn userService.updateById(user);}// 4. 单个查询(GET)@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {// getById()查询未被逻辑删除的用户return userService.getById(id);}// 5. 分页查询(GET)- 面试高频@GetMapping("/page")public IPage<User> getUserPage(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "10") Integer pageSize) {// 分页构造器,pageNum=当前页,pageSize=每页条数Page&lt;User&gt; page = new Page<>(pageNum, pageSize);// 分页查询,返回IPage对象(包含总条数、总页数等信息)return userService.page(page);}// 6. 自定义查询(GET)@GetMapping("/age/{age}")public User getUserByAge(@PathVariable Integer age) {return userService.selectByAge(age);}
}

5. 第五步:配置分页插件(关键)

MyBatis-Plus的分页功能需手动配置插件,否则分页失效(面试常考“分页失效原因”),创建配置类:


package com.bailu12.springbootdemo.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration // 标识为配置类
public class MyBatisPlusConfig {// 配置分页插件@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加分页拦截器,指定数据库类型(MySQL)interceptor.addInnerInterceptor(new PaginationInnerInterceptor(com.baomidou.mybatisplus.core.metadata.TableInfoHelper.DB_TYPE_MYSQL));return interceptor;}
}

6. 接口测试(验证实战效果)

用Postman测试5个核心接口,确保CRUD正常、分页生效、逻辑删除正常:

  • 新增:POST /user,请求体传入

  • 删除:DELETE /user/1,返回true(数据库is_deleted变为1)

  • 更新:PUT /user,请求体传入

  • 单个查询:GET /user/2,返回对应用户信息(is_deleted=0)

  • 分页查询:GET /user/page?pageNum=1&amp;pageSize=5,返回分页数据(含总条数、当前页数据)

三、核心原理拆解(面试重点,吃透不踩坑)

今天的核心原理的有3个,都是面试高频考点,结合实战代码,拆解底层逻辑,拒绝死记硬背。

1. MyBatis-Plus整合SpringBoot的核心原理

MyBatis-Plus整合的核心是“自动配置”,延续SpringBoot“约定优于配置”的思想,底层依赖MyBatis-Plus的starter包,自动完成以下操作:

  1. 自动配置DataSource:读取application.properties中的数据库配置,创建数据源对象,注入IoC容器;

  2. 自动配置SqlSessionFactory:整合MyBatis核心配置,加载Mapper接口和映射文件,无需手动配置mybatis-config.xml;

  3. 自动扫描Mapper接口:通过@Mapper注解或@MapperScan注解,扫描指定包下的Mapper接口,将其注入IoC容器;

  4. 自动注入BaseMapper:BaseMapper封装了CRUD方法,底层通过动态代理生成代理对象,执行对应的SQL语句。

面试金句:MyBatis-Plus整合SpringBoot的核心是利用starter的自动配置,简化MyBatis的配置流程,通过BaseMapper和IService封装CRUD方法,减少重复代码,本质是对MyBatis的增强。

2. CRUD接口底层执行流程(以查询为例)

以getById(Long id)方法为例,拆解底层执行流程(面试常问“MyBatis-Plus的CRUD方法执行过程”):

  1. 调用userService.getById(id),IService的getById方法由ServiceImpl实现;

  2. ServiceImpl调用baseMapper.selectById(id),BaseMapper的selectById方法是接口方法,由MyBatis-Plus动态生成代理实现;

  3. 代理对象解析方法名(selectById),生成对应的SQL语句(SELECT * FROM user WHERE id = ? AND is_deleted = 0);

  4. 通过SqlSessionFactory创建SqlSession,执行SQL语句,将结果集映射为User实体类对象;

  5. 返回User对象,完成查询操作。

3. 分页插件工作原理(面试高频)

MyBatis-Plus的分页插件本质是“SQL拦截器”,核心流程如下:

  1. 当执行分页查询(page方法)时,分页拦截器(PaginationInnerInterceptor)拦截SQL语句;

  2. 拦截器根据分页参数(pageNum、pageSize),对原SQL进行改造,添加LIMIT关键字(MySQL);

  3. 同时执行一条COUNT语句,查询总条数,封装到IPage对象中;

  4. 执行改造后的SQL,获取当前页数据,最终返回包含总条数、总页数、当前页数据的IPage对象。

易错点:分页失效的核心原因——未配置分页插件、分页参数传递错误、SQL语句手动写死LIMIT,覆盖了插件的改造逻辑。

四、面试高频真题汇总(附满分答案)

本期真题围绕CRUD、MyBatis-Plus整合、分页展开,都是后端面试高频题,直接背答案即可应对面试。

1. 基础必考题(入门级)

  • 真题1:SpringBoot如何整合MyBatis-Plus?

    答:1\. 导入MyBatis\-Plus starter、数据库驱动、lombok依赖;2\. 配置application\.properties,设置数据库连接和MyBatis\-Plus基础参数;3\. 创建实体类,使用MyBatis\-Plus注解指定表名、主键策略;4\. Mapper接口继承BaseMapper,添加@Mapper注解;5\. 配置分页插件(如需分页);6\. Service层继承IService,Controller层调用Service方法实现接口。
    
  • 真题2:MyBatis和MyBatis-Plus的区别?

    答:MyBatis\-Plus是MyBatis的增强工具,核心优势是“简化开发”:1\. 无需手动写CRUD SQL,BaseMapper/IService封装了基础方法;2\. 支持条件构造器(QueryWrapper),动态生成SQL;3\. 内置分页插件、逻辑删除、自动填充等功能;4\. 完全兼容MyBatis,可手动写SQL扩展。
    
  • 真题3:@TableId的作用是什么?有哪些主键策略?

    答:@TableId用于指定实体类的主键字段,主键策略(IdType)常用的有:AUTO(自增,MySQL常用)、INPUT(手动输入主键)、ASSIGN\_ID(雪花算法生成主键,分布式场景常用)。
    

2. 进阶面试题(高频重点)

  • 真题1:MyBatis-Plus的逻辑删除原理是什么?

    答:逻辑删除是通过@TableLogic注解标识删除字段(如is\_deleted),删除时不执行DELETE语句,而是执行UPDATE语句,将is\_deleted设为1;查询时自动添加AND is\_deleted = 0条件,实现“假删除”,保留数据历史。
    
  • 真题2:MyBatis-Plus分页插件的工作原理?分页失效的原因有哪些?

    答:工作原理:分页插件是SQL拦截器,拦截分页查询SQL,自动添加LIMIT关键字和COUNT查询,封装分页结果。分页失效原因:1\. 未配置分页插件;2\. 分页参数(pageNum、pageSize)传递错误;3\. 手动写死SQL的LIMIT,覆盖插件逻辑;4\. Mapper接口方法未使用MyBatis\-Plus的分页方法(如用了selectList而非page)。
    
  • 真题3:MyBatis-Plus的自动填充原理是什么?

    答:通过@TableField\(fill = FieldFill\.XXX\)注解标识需要自动填充的字段(如createTime、updateTime),自定义实现MetaObjectHandler接口,重写insertFill和updateFill方法,设置填充规则,当执行新增/更新操作时,自动为字段赋值,无需手动设置。
    

3. 实战避坑题(面试加分)

  • 真题:使用MyBatis-Plus时,实体类字段与数据库表字段不一致,如何解决?

    答:有3种方式:1\. 使用@TableField\(\&\#34;表字段名\&\#34;\)注解,指定实体类字段对应的数据表字段;2\. 在application\.properties中配置mybatis\-plus\.configuration\.map\-underscore\-to\-camel\-case=true(开启驼峰命名映射,如实体类username对应表user\_name);3\. 自定义SQL语句,指定字段映射。
    

五、总结+下期预告

本期核心总结

  1. 实战:完成了SpringBoot + MyBatis-Plus的整合,实现了用户模块CRUD接口,掌握了分页、逻辑删除、自动填充的使用;

  2. 原理:吃透了MyBatis-Plus整合原理、CRUD执行流程、分页插件工作机制,理解“增强MyBatis、简化开发”的核心;

  3. 面试:掌握了8道高频真题,重点记住分页、逻辑删除、自动填充的原理和实现方式,避免踩坑。

下期预告

SpringBoot学习第四天:接口异常处理+统一响应格式+拦截器实战,解决实战中接口报错混乱、响应格式不统一的问题,同时拆解异常处理原理、拦截器工作机制,配套面试高频题(如拦截器和过滤器的区别),让接口更规范、更健壮!

最后提醒:本期代码可直接复制到项目中运行,记得修改数据库配置,测试接口时注意逻辑删除的效果~ 有任何问题,评论区留言交流哦!

(注:文档部分内容可能由 AI 生成)

http://www.jsqmd.com/news/681317/

相关文章:

  • 告别屏幕偏色!用高通QDCM 6.0 + CA-410为你的安卓设备做一次专业级色彩校准
  • 2026年杭州热门标识工程公司排名,英帕尔标识工程有限公司性价比高吗? - mypinpai
  • 2026年速冻青豆生产厂家排名,北京上海等地靠谱源头工厂推荐 - 工业品牌热点
  • 思源宋体完全指南:3个关键问题解决你的字体选择困境
  • Fluent DPM模型实战:手把手教你设置颗粒粒径分布(Rosin-Rammler分布详解)
  • AI写专著必备!一键生成20万字专著,AI专著生成工具助你高效写作!
  • RK3588双系统实战:从分区表设计到fstab修改,手把手教你构建Android 12与Linux Debian共存环境
  • 365微机原理-基于8086温度采集系统仿真设计
  • 突破百度网盘限速:Python多线程下载脚本实战指南
  • 探讨2026年英帕尔标识工程有限公司口碑,排名情况大揭秘 - 工业品网
  • 别再为输入尺寸发愁了!PyTorch中nn.AdaptiveAvgPool2d的保姆级使用指南
  • 告别ValueError:Invalid format string的实战排查与修复指南
  • 2026质量可靠的电解整流器厂家哪个口碑好,跃阳电源获好评 - 工业推荐榜
  • 别再只会useradd了!CentOS用户管理的5个高效命令与3个常见坑点
  • 374基于MSP430车载红外人数统计超载报警系统设计
  • 从零到一:基于Docker的OnlyOffice跨平台部署与深度集成实践
  • 聊聊2026年电渗析电源厂家哪家好,知名电渗析整流器厂家推荐 - 工业品牌热点
  • 如何快速掌握ppInk屏幕标注工具:面向初学者的完整教程
  • 别再让高频电路‘发烧’了!手把手教你用Ansys Maxwell仿真搞定集肤效应与邻近效应
  • Hugging Face Accelerate多GPU训练:从“卡死”报错到优雅避坑的实战指南
  • MATLAB quiver绘图避坑指南:箭头重叠、颜色混乱、坐标轴不对齐?一次搞定
  • 剖析《金田一少年事件簿》:从少年侦探到37岁大叔的推理宇宙构建
  • 从理论到实践:朴素贝叶斯分类器的核心原理与平滑策略
  • SQL Server 开发系列(第四期):连接与子查询——JOIN 的底层逻辑与性能调优
  • Allegro 17.4 铺铜避坑指南:从全局参数到手动挖铜,硬件工程师必知的8个细节
  • 聊聊电渗析电源厂家,哪些品牌值得长期合作? - 工业推荐榜
  • XMind卡成PPT?别急着换电脑,先试试调整这个Java内存参数(附Xms/Xmx保姆级设置指南)
  • 2024 AI写专著利器:AI专著生成工具助力,20万字专著快速成型!
  • 375基于STM32多路抢答器时间显示声音提示系统设计
  • PyTorch新手必看:别再被unsqueeze和squeeze搞晕了,一张图教你理解张量维度操作