目录
一、学习背景
很多Java面试面试官都会问到Mybatis相关问题,其中#{}、${}的使用区别最为常见,大多人都会回答:
#{}参数带引号,而${}参数不带引号;
#{}防sql注入,${}不防sql注入。
单单两句话概括的话,个人觉得这个回答稍微有点肤浅了。具体怎么个带引号法,为什么要防sql注入,注入生效会导致什么结果也没大概说一下。
本文就从Mybatis特性之一的sql动态解析,#{}、${}解析的不同展开学习,相信一定会给你的回答再加点猛料,没时间看过程的童鞋直接拉最后看总结 ~哇~ 不过这个学习过程也很重要的,有时间就看看吧。
文章主要阐述个人对所学知识的观点,有不合理的地方,欢迎纠正补充,有大犇光顾,欢迎给点指引,蟹蟹,哈哈哈哈!!!
二、语句过程(Mybatis)
三、过程分析
3.1 sql动态解析
sql动态解析是Mybatis的重要特性之一,也是Mybatis相比其他ORM框架的优势所在。sql动态解析时,sql会被解析为BoundSql对象,此处进行动态 SQL的处理。
sql动态解析阶段,#{}、${}有不同的处理体现
#{}解析为占位符?即JDBC 预编译语句(prepared statement)的参数标记符。
select * from table_name where id= #{id};
id传参数值为字符串1,解析为:
select * from table_name where id= ?;
${}则是直接拼接不带引号的参数值到sql语句上。
select * from table_name where id=${id};
解析为:
select * from table_name where id= 1;
表明${}在sql动态解析阶段进行变量替换。
3.2 sql 预编译
数据库驱动在发送sql语句和参数给DBMS之前对sql语句进行编译,这样DBMS执行sql时,就不需要重新编译。预编译阶段,会将sql动态解析阶段#{}解析到的占位符?替换为参数值(带引号的)即变量替换。
3.3 DBMS(执行)
DBMS即Database Management System(数据库管理系统)。mapper.xml自定义的sql语句,经过动态解析阶段、预编译阶段后,得到最终要发送到DBMS执行的sql。