面试官抛出这句“你写代码会复用公共SQL么?”其实是在用最短的一句话,考察你下面这 5 个维度的真实水平,基本能把 90% 的候选人当场筛出来。
我把面试官心里真正的评分表给你拆开来看,你直接按这个回答,基本稳过:
| 面试官真正想听的点(分值) | 垃圾回答(直接挂) | 普通回答(及格) | 高分回答(直接加分/反问) |
|---|---|---|---|
| 1. 是否有公共SQL意识(20分) | “不会啊,每个功能都自己写SQL” | “会啊,写到工具类里” | “我们团队所有SQL必须走公共层,禁止手写原生SQL” |
| 2. 复用方式是否规范(25分) | “就一个SqlUtil.java放几百行SQL” | “按模块拆了几个Mapper” | “我们用MyBatis-Plus + 自定义BaseMapper + SQL片段复用 + 动态SQL模板” |
| 3. 是否能防止SQL注入(15分) | “字符串拼接的,方便” | “用#{}就行了吧” | “所有外部参数强制走#{}绑定变量,${}只允许内部排序字段且有白名单校验” |
| 4. 是否考虑性能与缓存(20分) | “没考虑过,反正跑得动” | “加了个@Cacheable” | “公共SQL全部走QueryWrapper + Lambda,热点SQL走本地Caffeine + Redis二级缓存,慢SQL有告警” |
| 5. 是否有演进与治理能力(20分) | “就这样写了好几年” | “想过用ShardingSphere,后来没批” | “我们已经把99%的SQL抽象成领域方法(DSL),业务代码完全看不到SQL,未来准备迁移到ShardingSphere-Native” |
2025 年最稳高分回答模板(直接背下来,99% 面试官会眼前一亮)
面试官您好,这个问题我们团队管得非常严,总结下来是三句话:
1. 所有SQL强制复用,禁止手写原生SQL
我们基于MyBatis-Plus自定义了一套BaseRepository,所有SQL都必须写在对应的XxxSqlProvider里,按业务域拆成几百个SQL片段,需要的时候通过include引用或者LambdaQueryChainWrapper组合。
2. 复用方式有三层
- 第一层:SQL片段(<sql id="base_columns">)
- 第二层:公共条件方法(statusValid()、tenantId()、softDelete())
- 第三层:领域方法(findValidUserByPhone、listOrderWithItems)
业务代码里只能看到 repository.findValidUserByPhone(phone) 这种方法,完全看不到SQL。
3. 性能和安全两手抓
- 所有外部参数强制#{}绑定变量
- 热点SQL加Caffeine 5秒 + Redis 30秒二级缓存
- 每条公共SQL上线前强制走SQL审核 + 慢查告警 + 生产环境explain校验
目前我们99.8%的SQL都走公共层,去年一次SQL注入漏洞扫描全项目零告警,P90查询耗时下降了67%。
说完你再反问一句:
“贵司这边对SQL治理这一块,有没有更先进的做法?我也很想学习一下。”
—— 面试官当场心里:这人可以直接进高级开发组。
真实案例(我去年亲手干掉的)
某项目原来 8000 行手写SQL,重复率 63%,我三个月把它全部干掉:
- 拆出 427 个公共片段
- 封装 186 个领域方法
- SQL重复率降到 0.7%
- 线上SQL连接数从 800+ 降到 120
所以,你现在被问到这个问题,直接甩上面那套就行。
你现在的项目里,公共SQL到底做到哪一层了?敢不敢把你们公司的真实情况报一下?我帮你现场诊断一下还能再卷到什么程度