news 2026/4/18 11:18:00

5 分钟搞定 SpringBoot+MyBatis 数据库查询:从 0 到 1 跑通完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5 分钟搞定 SpringBoot+MyBatis 数据库查询:从 0 到 1 跑通完整流程

一、回顾JDBC 操作的问题与流程

  • 问题:JDBC 是操作 MySQL 的传统方式,但步骤繁琐。
  • 核心流程(共 9 步):
    1. 创建数据库连接池(DataSource)
    2. 获取数据库连接(Connection)
    3. 编写带占位符的 SQL
    4. 创建操作命令对象(Statement)
    5. 替换 SQL 占位符
    6. 执行 SQL
    7. 处理执行结果(查询返回 ResultSet,更新返回数量)
    8. 处理结果集
    9. 释放资源

二、MyBatis 的定义与背景

  1. 定位:优秀的持久层框架,用于简化 JDBC 开发,专注于程序与数据库的交互。
  2. 持久层的含义:对应 Web 分层中的 Dao 层,负责数据库操作。

MyBatis 作为框架仅简化操作逻辑,实际数据存储仍依赖 MySQL,因此必须引入MySQL 驱动

三、MyBatis⼊⻔

MyBatis 结合 Spring Boot 的使用流程分为 4 步:

  1. 准备工作:创建 Spring Boot 工程、准备数据库表、定义实体类;
  2. 配置依赖:引入 MyBatis 框架、MySQL 驱动等依赖,并配置数据库连接信息;
  3. 编写 SQL:通过注解或 XML 文件编写 SQL 语句;
  4. 测试:验证数据库操作效果。
3.1准备⼯作
3.1.1创建⼯程

创建springboot⼯程,并导⼊mybatis的起步依赖、mysql的驱动包

项目创建后 pom.xml 会自动导入 MyBatis、MySQL 驱动依赖,版本随 SpringBoot 适配(SpringBoot 3.X → MyBatis 3.X),参考:https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

3.1.2数据准备

创建⽤户表,并创建对应的实体类User

创建对应的实体类UserInfo(实体类的属性名与表中的字段名⼀ 一对应

3.1.3配置数据库连接字符串

3.1.4写持久层代码

在项⽬中,创建持久层接⼝UserInfoMapper

Mybatis的持久层接规范⼀般都叫XxxMapper

  • Mapper 接口的本质:MyBatis 的 “数据访问接口”,用于告诉 MyBatis “要执行什么 SQL” 的入口,MyBatis 会在运行时自动为这个接口生成实现类(代理对象),无需你手动写实现类;
  • @Mapper 注解的作用:告诉 Spring Boot “这是 MyBatis 的 Mapper 接口”,Spring 会把这个接口的代理对象纳入容器管理,后续可以通过@Autowired注入使用;
  • @Select 注解的作用:把 SQL 语句 “绑定” 到接口方法上,当你调用queryAllUser()方法时,MyBatis 会执行注解里的 SQL,并且自动把查询结果(ResultSet)转换成List<UserInfo>(实体类集合)。

问题讲解MyBatis 的@Mapper和 Spring 的@Service在 “交给 Spring 管理” 的逻辑上有本质区别!!

1.@Mapper不是 “直接交给 Spring 管理”

@MapperMyBatis 的注解,不是 Spring 的注解!它的作用是告诉 MyBatis:“这是一个 Mapper 接口,需要为它生成代理实现类”,而非直接让 Spring 接管。

@ServiceSpring 的注解,作用是标记普通类为 Spring Bean,Spring 会直接实例化这个类并放入容器。

两者的 “交给 Spring 管理” 路径完全不同:

注解归属框架核心作用Spring 管理的对象来源
@ServiceSpring标记普通类为业务 BeanSpring 直接实例化@Service标注的类本身
@MapperMyBatis标记接口为 MyBatis 映射接口MyBatis 生成接口的代理类,再交给 Spring 管理
2.为什么@Mapper不需要 “手动定义实现类 / 变量名”?

你看到的UserInfoMapper userInfoMapper接口,不是普通类 —— 接口本身不能实例化,但 MyBatis 做了 “兜底”:

步骤 1:@Mapper触发 MyBatis 生成代理类

当你在接口上加@Mapper后,MyBatis-Spring 会通过动态代理UserInfoMapper生成一个 “隐形的实现类”(比如叫UserInfoMapperProxy),这个代理类会:

  • 实现UserInfoMapper接口;
  • 重写queryAllUser()方法,执行@Select里的 SQL;
  • 处理数据库连接、SQL 执行、结果映射等逻辑。
步骤 2:MyBatis 把代理类交给 Spring

MyBatis-Spring 会将生成的代理类注册为 Spring Bean(Bean 的类型是UserInfoMapper接口类型),放入 Spring 容器。

步骤 3:@Autowired直接注入代理对象

你在测试类中写:

spring 会从容器中找到 “UserInfoMapper类型的代理 Bean”,直接赋值给这个变量 ——你不需要手动写实现类,也不需要手动 new 对象,MyBatis+Spring 帮你全做了

3.对比@Service:为什么觉得 “需要写成员变量”?

比如你写一个UserService

你觉得 “需要写成员变量”,是因为:

  1. @Service标注的是普通类,Spring 会实例化这个类,但类内部要用到其他 Bean(比如UserInfoMapper),必须手动注入(写成员变量 +@Autowired);
  2. @Mapper标注的是接口,你不会在接口里写成员变量,而是在 “使用这个接口的地方”(比如UserService、测试类)注入接口对象。
举个更直观的对比
场景@Service(普通类)@Mapper(MyBatis 接口)
定义方式写完整的类,包含方法实现只写接口,方法上标注 SQL(无实现)
Spring 管理的对象类的实例对象MyBatis 生成的接口代理对象
使用时的注入方式定义XXXService变量 +@Autowired定义XXXMapper变量 +@Autowired
要不要写实现必须自己写方法实现不用写,MyBatis 根据 SQL 自动生成实现
关键总结
  1. @Mapper@Service:前者是 MyBatis 的 “接口代理生成器”,后者是 Spring 的 “普通类 Bean 标记器”;
  2. 不用写实现类:MyBatis 动态生成UserInfoMapper的代理实现类,Spring 管理这个代理对象;
  3. 变量名不是 “省了”:你在使用UserInfoMapper的地方(测试类 / Service),依然需要定义UserInfoMapper类型的成员变量,再通过@Autowired注入 —— 只是不用自己写实现类而已。
对比熟悉的@Service更易理解
特性@Mapper+ MyBatis@Service
谁生成类MyBatis 运行时动态生成代理类你自己手写类
谁注册为 Spring BeanMyBatis-Spring 帮你注册Spring 自动扫描@Service注册
谁创建对象Spring 实例化代理类Spring 实例化你手写的类
你需要写的代码只写接口 + SQL 注解写完整类 + 方法实现

四、单元测试

在创建出来的SpringBoot⼯程中,在src下的test⽬录下,已经⾃动帮我们创建好了测试类,我们可以直接使⽤这个测试类来进⾏测试.

单元测试的核心作用

单元测试是在开发阶段验证 “某一个组件(这里是UserInfoMapper)是否能正常工作”,避免把问题带到线上 —— 这里的测试目标是:验证queryAllUser()方法能否成功从数据库查询到用户数据

运行结果如下:

使⽤Idea⾃动⽣成测试类

在需要测试的Mapper接⼝中,右键->Generate->Test

记得加@SpringBootTest 注解,加载Spring运⾏环境(别忘记哟!)

关于测试的问题:

问题答案

Test 目录下:能否自定义测试方法

可以,新增方法加@Test即可
执行方法需要点类的箭头吗不用,点单个方法的箭头只跑当前方法,效率更高
启动测试后后续更改测试里的代码需要clean不需要,仅改代码 / 依赖后出问题时才需要
要手动启动 SpringBoot 启动类吗不需要,@SpringBootTest会自动启动 Spring 容器
额外小技巧

如果测试方法执行慢(因为@SpringBootTest会启动完整容器),可以针对 Mapper 测试用@MyBatisTest(轻量化,只启动 MyBatis 相关环境)适合纯 Mapper 层的测试。

验证数据库查询功能是否正常,把数据库中UserInfo表的所有数据查询出来并打印到控制台:

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

【提升应用健壮性必读】:Symfony 8路由参数验证的3种高效实现方式

第一章&#xff1a;Symfony 8路由参数验证概述在现代Web开发中&#xff0c;确保从客户端传入的数据安全、合法是构建健壮应用的关键环节。Symfony 8 提供了强大的路由系统&#xff0c;支持在定义路由时直接对参数进行约束与验证&#xff0c;从而在请求进入控制器之前就完成初步…

作者头像 李华
网站建设 2026/4/17 13:44:21

【顶级医院都在用的生存分析方法】:基于R语言的真实案例解析

第一章&#xff1a;顶级医院都在用的生存分析方法概述在现代医疗数据分析中&#xff0c;生存分析已成为评估患者预后、治疗效果和疾病进展的核心工具。顶级医疗机构广泛采用此类方法来处理带有时间依赖性结局的数据&#xff0c;尤其适用于癌症、心血管疾病等长期随访研究。什么…

作者头像 李华
网站建设 2026/4/17 7:11:11

Pyroscope Java 接入最佳实践

Pyroscope Pyroscope 是 Grafana 开源的持续性能分析平台&#xff0c;旨在帮助用户从应用程序中获取性能洞察&#xff0c;以优化资源使用&#xff0c;如 CPU、内存和 I/O 操作。将 Pyroscope 数据上报到观测云&#xff0c;使用户能够全面了解应用程序的行为&#xff0c;并能够…

作者头像 李华
网站建设 2026/4/18 3:27:29

【PHP 8.6扩展依赖管理终极指南】:掌握高效组件协同的5大核心策略

第一章&#xff1a;PHP 8.6扩展依赖管理的核心演进PHP 8.6 在扩展生态系统的依赖管理方面引入了多项关键改进&#xff0c;显著提升了扩展加载的稳定性与可维护性。通过增强 ext 声明机制和运行时依赖解析能力&#xff0c;开发者能够更精确地定义扩展间的兼容性约束&#xff0c;…

作者头像 李华
网站建设 2026/4/18 3:25:00

收藏!程序员破局必看:AI大模型是你超车的最佳赛道

当下程序员职场的“内卷”早已不是新鲜话题——传统开发领域人才扎堆饱和&#xff0c;不少同行明明技术扎实&#xff0c;却陷入晋升停滞、薪资“原地踏步”的困境。而AI技术的爆发式增长&#xff0c;正像一道劈开迷雾的光&#xff0c;成为打破职业瓶颈的关键风口。对于想寻求突…

作者头像 李华