欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis中#和$的区别

程序员文章站 2022-07-14 09:26:09
...

preparestatement和statement

再看之前,我们先来回顾preparestatement和statement之间的区别
先来看下PrepareStatement执行Sql的代码:

String sql = “select * from user where user_id=?”;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, “1001”);
ResultSet rs = pstmt.executeQuery();

因为PreparedStatement对象会预编译sql模版。在以后执行相同的语句模版只需要传参给他就可以重复执行,而不需要在进行编译.不仅提升了效率而且有效的防止了sql注入

#和$

在mybatis中,#和$的区别你可以理解为是PrepareStatement和StateMent的区别

我们来看这样的一个SQL语句

<select id="select" resultType="com.alibaba.fastjson.JSONObject">
  select * from food where name = #{name}
</select>

 @Test
void contextLoads() {
  List<JSONObject> list = mapper.select(" '菜'or 1=1");
  System.out.println(list.size());
}
这是最后发送的sql,获得正确的结果值
select *
 FROM food
 WHERE name = ' '菜' or 1=1';

Mybatis中#和$的区别
再看这一组SQL

<select id="select2" resultType="com.alibaba.fastjson.JSONObject">
  select * from food where name = ${name}
</select>

@Test
void contextLoads2() {
  // 这个测试 会出错
  List<JSONObject> list = mapper.select2("菜 or 1=1");
  System.out.println(list.size());
}

下面是发送的sql,我们可以看到他直接name=菜的时候没有给我们添加字符串的引号。然后报错了,我们给加上``
Mybatis中#和$的区别
下面的语句,最终发送的sql如下,导致了sql注入,or 1=1 变成了一个条件
Mybatis中#和$的区别

@Test
 void contextLoads2() {
     List<JSONObject> list = mapper.select2(" 'c菜' or 1=1");
     System.out.println(list.size());
 }
${}使用场景

在我们需要排序的时候,我们一般使用${},由于#{}会帮我们加上引号,如果我们字段有 ‘stars’ 和 stars 这样的字段,而我们想要按照stars排序,如果使用#{}最后就会按照’stars’来排序了。

总结
1 、#{}是预编译处理,传入的参数最后会帮我们加上引号
2 ${},会有sql注入风险,传入的参数直接是字符串拼接,不会帮我们加上引号,导致参数可能变成查询条件

相关标签: mybatis