最近在整理mybatis面试题,记录下,用#{},和 ${}传参的区别。
使用场景
固定值(列名)
传入参数是,sql语句解析是会加上'*'
,比如
select id, username, password, email, phone, question, answer, role, create_time, update_time from mall_user where username = ?
,传入的username为admin,那么最后打印出来的就是
select id, username, password, email, phone, question, answer, role, create_time, update_time from mall_user where username = 'admin'
动态值
另外一种情况是,如果你要做动态的排序,比如
order by column
这个时候务必要用${},因为如果你使用了#{},那么打印出来的将会是
select * from table order by 'name'
这样是会报错的。
目前来看,能用#就不要用$。
Mybatis中的#和$的区别
-
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”;
-
$将传入的数据直接显示生成在sql中。如:order by user_id,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id;
-
#方式能够很大程度防止sql注入;
-
$方式无法防止Sql注入;
-
$方式一般用于传入数据库对象,例如传入表名、列名;
-
能用#就别用$;
-
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。
SQL注入攻击
Mapper接口方法
User selectByUsername(@Param("username") String username);
XML配置
<select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from mall_user
where username = ${username}
</select>
传入参数
@Test
public void Mybatis01(){
String username = "'admin' or 1 = 1";
User admin = userMapper.selectByUsername(username);
log.info(admin.toString());
}
打印执行结果
==> Preparing: select id, username, password, email, phone, question, answer, role, create_time, update_time from mall_user where username = 'admin' or 1 = 1
==> Parameters:
<== Columns: id, username, password, email, phone, question, answer, role, create_time, update_time
<== Row: 1, admin, 21232F297A57A5A743894A0E4A801FC3, admin@qq.com, null, null, null, 0, 2000-08-06 15:12:00, 2000-08-06 15:12:00
<== Row: 2, 1234, 01044cfd18dd5c0cde26733c11a3b542, xiaogao1398@163.com, null, null, null, 1, 2021-12-26 21:31:49, 2021-12-26 21:31:49
<== Row: 3, 高冷, 01044cfd18dd5c0cde26733c11a3b542, xiaogao13982@163.com, null, null, null, 1, 2021-12-26 21:32:06, 2021-12-26 21:32:06
<== Row: 5, jack, e10adc3949ba59abbe56e057f20f883e, jack@qq.com, null, null, null, 1, 2022-01-14 10:15:47, 2022-01-14 10:15:47
<== Row: 6, admin123, 21232f297a57a5a743894a0e4a801fc3, admin123@qq.com, null, null, null, 1, 2022-01-17 11:33:53, 2022-01-17 11:33:53
<== Total: 5
攻击成功。