最近做公司的项目需要做字段动态传入,然后校验返回值,所以去网上找了下
<select id="queryAll" resultType="mp.study.demo.bean.User">
select
<if test="sets != null and sets.size > 0">
<foreach collection="sets"
item="sets"
separator=",">
${sets}
</foreach>
</if>
from mp_user
</select>
这里用$符而不是#,后面会说
看打印SQL:
@Override
public List<User> queryAll()
{
Set<String> set = new LinkedHashSet<>();
set.add("id");
set.add("name");
set.add("age");
return userMapper.queryAll(set);
}
这完全没毛病,也做到了动态化的效果. 那么如果用#会怎么样呢?
==> Preparing: select ? , ? , ? from mp_user
==> Parameters: id(String), name(String), age(String)
<== Columns: id, name, age
<== Row: id, name, age
很显然,传入的参数全部变成了?,这里我就想到了 $ 和 # 传参的区别. 以前我们老生常谈的话题, 面试题大多数人也都背到过. 这样可以防止SQL注入,更加安全.
我想起来前段时间我看我的同事写动态SQL的时候,就是用 $符号传参,虽然也能起到效果,但是他还需要自己拼接引号. 这是个不同点,# 注入参数会带引号. 而 $ 符号是没有经过编译处理的,所以就是个普通变量. 这样就是为什么动态注入字段要用 $ 而不是 # 的原因了!所以比如order by 排序的时候, 要是动态字段的话,你也得用 $ 注入