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?

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

java 复制代码
@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)

负责:

复制代码
简单增删改查

例如:

java 复制代码
userMapper.selectById(id);

userMapper.insert(user);

2️⃣ QueryMapper(复杂 JOIN)

负责:

复制代码
联表查询
复杂 SQL
统计查询

例如:

java 复制代码
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

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 帮你自动生成。


示例

java 复制代码
public interface UserMapper
        extends BaseMapper<User> {
}

然后直接:

java 复制代码
userMapper.selectById(id);

userMapper.insert(user);

就能用。


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

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

复制代码
以后不用写 SQL 了

其实不是。


企业真实情况

简单 CRUD:

复制代码
MyBatis-Plus

复杂查询:

复制代码
XML

原因

因为 JOIN 很复杂。

例如:

java 复制代码
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


接口

java 复制代码
@Mapper
public interface UserQueryMapper {

    UserDetailVO selectUserDetailById(Long id);
}

XML

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

示例

java 复制代码
@Service
public class UserServiceImpl {

    @Resource
    private UserQueryMapper userQueryMapper;

    public UserDetailVO getUserDetail(Long id) {

        return userQueryMapper
                .selectUserDetailById(id);
    }
}

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

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

例如:

复制代码
用户详情页

访问频率非常高。

所以会:

复制代码
先查 Redis
没有再查数据库

示例

java 复制代码
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

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

相关推荐
阳光九叶草LXGZXJ3 小时前
达梦数据库-报错-15-列【XXX】长度超出定义
linux·运维·数据库·sql·学习
字节渡客4 小时前
Redis键明明过期了,业务还在读到旧数据
数据库·redis·spring
OnlineProxy6 小时前
亚马逊多账号运营:如何在规避“关联封号”风险的同时实现电商规模化扩张
服务器·数据库·redis
辻弋2018 小时前
五年前的旅行视频糊成马赛克?Video2X用Real-ESRGAN逐帧重建细节,但只支持Windows、集显用户建议直接放弃
服务器·数据库·windows·游戏引擎·电脑
可乐鸡翅yeah_8 小时前
业务中 M3U8 水印相关坑,硬水印和动态水印区别
前端·网络·数据库·ffmpeg·m3u8在线
石头麻辣鱼9 小时前
Bamboo 调度系统 OceanBase 适配实战:存储过程迁移踩过的三个大坑
数据库
龙亘川9 小时前
数智驱动民政升级 精准守护民生保障
大数据·数据库·人工智能
念何架构之路9 小时前
zap扩展生态与总结
java·前端·数据库
晚安日记wanna10 小时前
MySQL 回表为什么这么慢?5 种优化手段逐个拆解
数据库·mysql·性能优化
第七页独白10 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库