一、前言
前面四篇,我们已经学会了:
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
以及:企业里到底哪些字段需要索引