众所周知,mybatis中使用#号可以防止SQL注入,但是order by却不能使用#而必须使用$

Mybatis中如果使用#符引用参数,会自动在参数值两端加引号,导致排序失效,因此Mybatis中使用Order By时一定使用$符号

另外如果表名是参数,也要用$符,因为表名不允许使用引号,直接就会报语法错误。

用下表做参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `t2` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`value` VARCHAR(50) NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;

mysql> select * from t2;
+----+-------+
| id | value |
+----+-------+
| 1 | 5 |
| 2 | 4 |
| 3 | 3 |
| 4 | 2 |
| 5 | 1 |
+----+-------+

则下面两条SQL执行结果为何

1
2
select * from t2 order by value;
select * from t2 order by 'value'; -- 可以看出当使用引号时,输出结果并没有排序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> select * from t2 order by value;
+----+-------+
| id | value |
+----+-------+
| 5 | 1 |
| 4 | 2 |
| 3 | 3 |
| 2 | 4 |
| 1 | 5 |
+----+-------+
mysql> select * from t2 order by 'value';
+----+-------+
| id | value |
+----+-------+
| 1 | 5 |
| 2 | 4 |
| 3 | 3 |
| 4 | 2 |
| 5 | 1 |
+----+-------+

这是因为当order by后是字符串,MySQL会认为根据一个常量列排序,如下列代码所示:

而常量列所有值都相等,所以也就不会排序。

1
2
3
4
5
6
7
8
9
10
mysql> select id,value,'value' from t2 order by 'value';
+----+-------+-------+
| id | value | value |
+----+-------+-------+
| 1 | 5 | value |
| 2 | 4 | value |
| 3 | 3 | value |
| 4 | 2 | value |
| 5 | 1 | value |
+----+-------+-------+