news 2026/5/10 2:07:01

SQL 第五篇:SQL 如何真正接入 Spring Boot 项目(企业 Mapper 分层实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL 第五篇:SQL 如何真正接入 Spring Boot 项目(企业 Mapper 分层实战)

一、前言

前面四篇,我们已经学会了:

CRUD 建表 表关系 JOIN

但到这里,其实还只是:

数据库层面

真正的企业开发,还差最后一步:

❗ SQL 如何接入 Spring Boot 项目

很多初学者学 SQL 时有个问题:

会写 SQL 不会落项目

比如:

  • SQL 写在哪里?
  • JOIN 写在哪里?
  • Service 能不能直接写 SQL?
  • MyBatis-Plus 到底干嘛的?
  • XML 为什么企业还在用?

这一篇,我们把这些问题一次讲透。


二、企业里的真实调用链

先看真实项目里的结构:

Controller ↓ Service(业务 + 事务 + 缓存) ↓ QueryMapper(复杂 JOIN) ↓ Mapper(单表 CRUD) ↓ 数据库

这一套非常重要。

后面你做 Spring Boot 项目,基本都会围绕这个结构展开。


三、为什么 SQL 不能写在 Service?

很多新手最开始会这样写:

@Service public class UserService { @Resource private JdbcTemplate jdbcTemplate; public UserDetailVO getUserDetail(Long id) { String sql = """ SELECT ... """; return jdbcTemplate.queryForObject(sql, ...); } }

虽然能跑。但问题很大:


1️⃣ Service 职责混乱

Service 本来应该负责:

业务逻辑 事务 缓存

结果现在:

SQL 也塞进来了

会越来越乱。


2️⃣ SQL 无法复用

以后别的接口也要查:

用户详情

你只能复制 SQL。


3️⃣ JOIN SQL 很快会失控

企业里的 JOIN:

几十行 上百行

Service 根本没法看。


四、企业里的正确做法:Mapper 分层

所以企业里通常会这样分:


1️⃣ Mapper(单表 CRUD)

负责:

简单增删改查

例如:

userMapper.selectById(id); userMapper.insert(user);

2️⃣ QueryMapper(复杂 JOIN)

负责:

联表查询 复杂 SQL 统计查询

例如:

userQueryMapper.selectUserDetailById(id);

五、企业真实结构(推荐)

这里给你一个接近企业的结构。


user 模块

user/ ├── controller/ ├── service/ ├── converter/ ├── model/ │ ├── dto/ │ ├── vo/ │ └── entity/ └── infrastructure/ └── persistence/ └── mapper/ ├── UserMapper.java ├── UserQueryMapper.java └── xml/ └── UserQueryMapper.xml

六、Mapper 到底干什么?


UserMapper.java

@Mapper public interface UserMapper { int insert(User user); User selectById(Long id); int updateById(User user); int deleteById(Long id); }

这里:

只做单表 CRUD

七、MyBatis-Plus 为什么企业喜欢用?

因为:

单表 CRUD 太重复了

比如:

insert delete update selectById

几乎每张表都有。

所以 MyBatis-Plus 帮你自动生成。


示例

public interface UserMapper extends BaseMapper<User> { }

然后直接:

userMapper.selectById(id); userMapper.insert(user);

就能用。


八、为什么复杂 JOIN 企业还是喜欢 XML?

很多人第一次学 MyBatis-Plus 会以为:

以后不用写 SQL 了

其实不是。


企业真实情况

简单 CRUD:

MyBatis-Plus

复杂查询:

XML

原因

因为 JOIN 很复杂。

例如:

SELECT u.id, u.username, d.real_name, a.receiver_name, a.phone FROM user u LEFT JOIN user_detail d ON u.id = d.user_id LEFT JOIN user_address a ON u.id = a.user_id WHERE u.id = #{id}

这种 SQL:

XML 更清晰 更容易维护 更容易优化

九、企业里的 QueryMapper


接口

@Mapper public interface UserQueryMapper { UserDetailVO selectUserDetailById(Long id); }

XML

<select id="selectUserDetailById" resultType="com.example.vo.UserDetailVO"> SELECT u.id, u.username, d.real_name, a.receiver_name, a.phone, a.detail_address FROM user u LEFT JOIN user_detail d ON u.id = d.user_id LEFT JOIN user_address a ON u.id = a.user_id WHERE u.id = #{id} </select>

十、Service 真正该做什么?

Service 不负责写 SQL。

Service 负责:

业务逻辑 事务 缓存 调用 Mapper

示例

@Service public class UserServiceImpl { @Resource private UserQueryMapper userQueryMapper; public UserDetailVO getUserDetail(Long id) { return userQueryMapper .selectUserDetailById(id); } }

十一、企业里的缓存(Redis)

企业里通常不会每次都查数据库。

例如:

用户详情页

访问频率非常高。

所以会:

先查 Redis 没有再查数据库

示例

public UserDetailVO getUserDetail(Long userId) { String key = "user:detail:" + userId; // 1. 查缓存 UserDetailVO cached = redis.get(key); if (cached != null) { return cached; } // 2. 查数据库 UserDetailVO vo = userQueryMapper.selectUserDetailById(userId); // 3. 写缓存 redis.set(key, vo); return vo; }

十二、这一篇真正的核心

这一篇最重要的不是:

MyBatis-Plus XML

而是:

❗ SQL 在企业里不是单独存在的

而是:

👉 进入“分层架构”


十三、企业里的 SQL 最终分工


CRUD

MyBatis-Plus

JOIN

XML

业务逻辑

Service

事务

@Transactional

缓存

Redis

十四、一句话总结

企业里的 SQL:

👉 不是“随便写”

而是:

“分层 + 分职责 + 分复杂度”


下一篇

SQL 第六篇:索引入门(为什么你的查询越来越慢)

我们会真正讲透:

索引 B+树 user_id 为什么加索引 EXPLAIN

以及:企业里到底哪些字段需要索引

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

智能体工作流中如何实现多模型灵活切换与成本控制

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 智能体工作流中如何实现多模型灵活切换与成本控制 在构建复杂的智能体工作流时&#xff0c;开发者常常面临两个核心挑战&#xff1…

作者头像 李华
网站建设 2026/5/10 1:57:39

AI Agent技能化实践:安全封装百度网盘API,实现自然语言文件管理

1. 项目概述&#xff1a;当AI助手学会管理你的网盘如果你和我一样&#xff0c;每天要在本地文件、云端存储和AI助手之间来回切换&#xff0c;那这个项目绝对能让你眼前一亮。bdpan-storage&#xff0c;或者说“百度网盘AI技能”&#xff0c;本质上是一个桥梁&#xff0c;它让Cl…

作者头像 李华
网站建设 2026/5/10 1:57:32

XUnity Auto Translator:打破语言障碍的Unity游戏实时翻译终极方案

XUnity Auto Translator&#xff1a;打破语言障碍的Unity游戏实时翻译终极方案 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾因外语游戏中的生涩文本而苦恼&#xff1f;是否渴望畅玩那些精彩的…

作者头像 李华
网站建设 2026/5/10 1:51:31

AI项目规则生成器:自动化配置AI编程助手规则与技能发现

1. 项目概述&#xff1a;AI项目规则生成器的核心价值如果你和我一样&#xff0c;每天都要和Cursor、Claude Code、Antigravity IDE这些AI编程助手打交道&#xff0c;那你肯定也遇到过这个痛点&#xff1a;每次开一个新项目&#xff0c;都得花大量时间去配置.cursorrules、AGENT…

作者头像 李华
网站建设 2026/5/10 1:51:31

写给前端的Vue+Prisma+tRPC入门指南

写在前面&#xff1a;这是给前端实验室实习生培训前写的教案及入门指南&#xff08;因为实验室一个比赛由于各部门人数不均问题导致部分前端实习生没有后端配合&#xff0c;遂得让他们自己写…&#xff09;&#xff0c;写完后觉得应该值得记录一下&#xff0c;本人也只是全栈半…

作者头像 李华
网站建设 2026/5/10 1:50:41

电路中 Filter 和 Matching 完整详解

一、Filter 含义单词本义Filter 滤波器 / 滤波电路作用筛选频率、滤除干扰、保留有用信号&#xff0c;去掉杂波、噪声、纹波核心功能滤除高频干扰把电源、信号里的尖峰、毛刺、EMI 噪声滤掉平滑电压纹波直流电源加上 LC、RC 滤波&#xff0c;让电压更干净选频射频电路只让特定…

作者头像 李华