MyBatis 中拼接字符串的几种方式

一、使用 + 号进行拼接。

SELECT * FROM users WHERE id = 1 + 2;

在 SQL 语句中,+ 号用于进行字符串拼接,相当于将两个字符串连接在一起。在上面的 SQL 语句中,1 和 2 会先进行数值运算,然后再拼接成字符串,最终的 SQL 语句等价于:

SELECT * FROM users WHERE id = 3; 

二、使用 CONCAT 函数进行拼接。

SELECT * FROM users WHERE name = CONCAT('a', 'b');

在 SQL 语句中,CONCAT 函数用于将多个字符串拼接在一起,相当于 + 号的功能。在上面的 SQL 语句中,CONCAT 函数接收了两个参数,分别为 'a' 和 'b',最终会将它们拼接成 'ab',最终的 SQL 语句等价于:

SELECT * FROM users WHERE name = 'ab';

三、使用 || 运算符进行拼接

SELECT * FROM users WHERE name = 'a' || 'b';

在 SQL 语句中,|| 运算符用于将两个字符串拼接在一起,它的作用与 + 号和 CONCAT 函数类似。在上面的 SQL 语句中,两个字符串 'a' 和 'b' 会被拼接在一起,最终的 SQL 语句等价于:

SELECT * FROM users WHERE name = 'ab';  复制代码

四、使用 $ 符号

在 MyBatis 中,拼接字符串还可以使用 $ 符号。例如:

SELECT * FROM users WHERE name = $name;

在 SQL 语句中, 符号用于指定一个字符串拼接,它会在 SQL 语句被执行前进行拼接。与 # 符号不同, 符号不会对输入值进行任何检查和转义,因此它可能会导致 SQL 注入攻击。在上面的 SQL 语句中,name将被拼接到sql语句中,如果name将被拼接到SQL语句中,如果name 的值为 'ab',则最终的 SQL 语句为:

SELECT * FROM users WHERE name = 'ab';

五、# 和 $ 符号

# 用于指定一个占位符,它会在 SQL 语句被执行前进行替换。在下面的 SQL 语句中,#{id} 将被替换为实际的 id 值:

SELECT * FROM users WHERE id = #{id};

如果 #{id} 的值为 1,则最终的 SQL 语句为:

SELECT * FROM users WHERE id = 1;

$ 符号

符号用于指定一个字符串拼接,它会在 SQL 语句被执行前进行拼接。与 # 符号不同, 符号不会对输入值进行任何检查和转义,因此它可能会导致 SQL 注入攻击。例如,在下面的 SQL 语句中,$id 将被拼接到 SQL 语句中:

SELECT * FROM users WHERE id = ${id};  复制代码

同样如果 $id 的值为 1,则最终的 SQL 语句为

SELECT * FROM users WHERE id = 1; 复

咋一看两者是一样的,那为什么推荐使用 # 符号呢?

区别 —— sql注入风险

Java

String sql = "SELECT * FROM users WHERE name = #{name}";  Map<String, Object> params = new HashMap<>(); params.put("name", "a' or '1' = '1");  // 执行 SQL 语句 SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList(sql, params);  复制代码

在执行上面的代码时,MyBatis 会将 #{name} 替换为参数映射中的值,最终的 SQL 语句为:

SQL

SELECT * FROM users WHERE name = 'a\' or \'1\' = \'1'; 复制代码

由于 # 符号会将参数值转义,因此它可以有效防止 SQL 注入攻击。

而 符号仅用于指定一个字符串拼接,它会在 SQL 语句被执行前进行拼接。与 # 符号不同, 符号不会对输入值进行任何检查和转义,因此它可能会导致 SQL 注入攻击。

Java

// 使用 $ 符号拼接字符串 String sql = "SELECT * FROM users WHERE name = ${name}";  Map<String, Object> params = new HashMap<>(); params.put("name", "a' or '1' = '1");  // 执行 SQL 语句 SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList(sql, params);  复制代码

例如,在同样的 SQL 语句中,name将被拼接到sql语句中,如果name将被拼接到SQL语句中,如果{name} 的值为 "a' or '1' = '1",则最终的 SQL 语句为:

SQL

SELECT * FROM users WHERE name = a' or '1' = '1; 复制代码

我们可以看到,拼接后没有带上引号;并且没有对 {name} 的值 "a' or '1' = '1" 进行转义。这可能恶意的sql注入发生。因此,建议使用 # 符号来指定占位符,而不是 符号来拼接字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值