关于 MyBatis 中 #{} 与 ${} 的本质区别
-
#{}底层使用的是PreparedStatement预编译机制:- MyBatis 会将 SQL 中的
#{xxx}替换为?,生成一个参数化的 SQL 模板; - 实际参数值通过
PreparedStatement.setXXX()方法传入; - 所有参数都被视为纯数据(字面量),不会被数据库解析为 SQL 关键字或表达式;
- 因此,天然具备防止 SQL 注入的能力,是安全的首选方式。
- MyBatis 会将 SQL 中的
-
${}是纯粹的字符串替换:- MyBatis 直接将
${xxx}替换为变量的字符串值,不做任何转义或类型处理; - 最终拼接成一条完整的 SQL 字符串再发送给数据库;
- 如果用户输入恶意内容(如
' OR '1'='1),就会导致 SQL 注入漏洞; - 仅在极少数场景下可谨慎使用 ,例如:
- 动态表名(如按时间分表:
user_202511); - 动态列名或排序字段(如
ORDER BY ${column});
- 动态表名(如按时间分表:
- 必须配合严格的白名单校验或输入过滤(如验证表名是否合法、是否来自可信来源),否则绝不允许使用。
- MyBatis 直接将
📌 最佳实践 :
99% 的场景使用#{};只有在明确知道风险并做好防护的前提下,才考虑使用${}。
"雪花 ID 逆向找表"场景
动态分表 需求,确实可能需要用到 ${},例如:
<select id="getUser" resultType="User">
SELECT * FROM user_${tableSuffix} WHERE id = #{id}
</select>
但关键在于:
tableSuffix不能直接来自用户输入;- 应由服务端根据雪花 ID 解析出时间,再映射到预定义的合法后缀 (如
202511); - 最好再加一层校验:
if (!validSuffixes.contains(tableSuffix)) throw ...
这样才能在使用 ${} 的同时保证安全。
Spring、Spring MVC 和 Spring Boot 的区别与联系
Spring、Spring MVC 和 Spring Boot 都属于 Spring 全家桶,它们是层层递进、职责分明的关系。
-
Spring Framework 是整个生态的基础
它的核心是 IoC(控制反转)和 AOP(面向切面编程):
- IoC 将对象(Bean)的创建和依赖关系管理交给 Spring 容器,开发者通过 依赖注入(DI) (如
@Autowired)获取 Bean,避免了硬编码的new操作,降低了组件耦合度; - AOP 通过动态代理实现日志、事务、权限等横切逻辑的统一处理,提升代码复用性。
- IoC 将对象(Bean)的创建和依赖关系管理交给 Spring 容器,开发者通过 依赖注入(DI) (如
-
Spring MVC 是基于 Spring 的 Web 框架
它采用 MVC 分层架构 (Model-View-Controller),用于构建 Web 应用或 RESTful 接口。
核心流程是:
- 请求由前端控制器
DispatcherServlet拦截; - 通过
HandlerMapping找到对应的 Controller 方法(Handler); - 经过参数解析、数据绑定(如 JSON 反序列化)后执行业务逻辑;
- 若方法标注
@ResponseBody(或使用@RestController),则直接将返回值序列化为 JSON 响应给前端;
(传统模式会返回ModelAndView,由视图解析器渲染页面,但现在主流是前后端分离,基本都用@ResponseBody)
- 请求由前端控制器
-
Spring Boot 是对 Spring 的进一步封装和简化
它的核心理念是 "约定大于配置" + "开箱即用":
- 通过 Starter 依赖 自动引入整合好的技术栈(如
spring-boot-starter-web= Spring MVC + 内嵌 Tomcat + Jackson); - 启动时自动扫描 classpath 下所有 JAR 包中的
META-INF/spring.factories(或新版的AutoConfiguration.imports),加载自动配置类; - 自动配置类通过 条件注解 (如
@ConditionalOnClass(DataSource.class))判断是否生效------例如,只要 classpath 中有数据库驱动,就会自动配置DataSource、JdbcTemplate等 Bean; - 开发者无需手动配置 XML 或繁琐的 Java Config,直接注入即可使用,极大提升了开发效率。
- 通过 Starter 依赖 自动引入整合好的技术栈(如