1.原始数据(十分重要)
t_user表
2.各类测试(全网最齐全)
测试1 — “ad”“min”
1.1 方法
List<User> getUserByLike(@Param("username") String name)
1.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like "ad""min"
</select>
1.3 结果
DEBUG 03-21 22:38:17,885 ==> Preparing: select * from t_user where username like "ad""min" (BaseJdbcLogger.java:137)
User{id=8, username='ad"min', password='123456', age=33, sex='男', email='123@qq.com'}
测试2 — “ad”‘min’
2.1 方法
List<User> getUserByLike(@Param("username") String name)
2.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like "ad"'min'
</select>
2.3 结果
DEBUG 03-21 22:44:44,462 ==> Preparing: select * from t_user where username like "ad"'min' (BaseJdbcLogger.java:137)
User{id=2, username='admin', password='123456', age=23, sex='女', email='123456@qq.com'}
测试3 — ‘ad’“min”
3.1 方法
List<User> getUserByLike(@Param("username") String name)
3.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like 'ad'"min"
</select>
3.3 结果
DEBUG 03-21 22:44:44,462 ==> Preparing: select * from t_user where username like 'ad'"min" (BaseJdbcLogger.java:137)
User{id=2, username='admin', password='123456', age=23, sex='女', email='123456@qq.com'}
测试4 — ${username}
4.1 方法
List<User> getUserByLike(@Param("username") String name)
//传入参数
List<User> list = mapper.getUserByLike("d");
list.forEach(System.out::println);
4.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like "a${username}min"
</select>
4.3 结果
DEBUG 03-21 22:44:44,462 ==> Preparing: select * from t_user where username like "admin" (BaseJdbcLogger.java:137)
User{id=2, username='admin', password='123456', age=23, sex='女', email='123456@qq.com'}
测试5 — #{username}
5.1 方法
List<User> getUserByLike(@Param("username") String name)
//传入参数
List<User> list = mapper.getUserByLike("d");
list.forEach(System.out::println);
5.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like "a#{username}min"
</select>
5.3 结果
DEBUG 03-21 22:56:51,712 ==> Preparing: select * from t_user where username like "a?min" (BaseJdbcLogger.java:137)
//出现异常:Cause: org.apache.ibatis.type.TypeException
6.1 方法 — “a”#{username}“min”
List<User> getUserByLike(@Param("username") String name)
//传入参数
List<User> list = mapper.getUserByLike("d");
list.forEach(System.out::println);
6.2 代码
<select id="getUserByLike" resultType="User">
select * from t_user where username like "a"#{username}"min"
</select>
6.3 结果
DEBUG 03-21 22:58:27,353 ==> Preparing: select * from t_user where username like "a"?"min" (BaseJdbcLogger.java:137)
User{id=2, username='admin', password='123456', age=23, sex='女', email='123456@qq.com'}
3.总结
- 在mysql中一个字符串内有一个单引号和一个双引号(不论前后,连在一起),会被看成是做字符串连接运算。
- 在mysql中一个字符串内有一对连在一起的双引号,会被转义看成是一个双引号。
- 在mybatis中,字符串拼接${}其就是直接在其位置插入字符串,比如username=“d”,则
“a${username}min"被看做"admin”,故对于单独使用且参数为字符串类型或者日期类型时,需要手动加上单引号。 - 在mybatis中,#{}其就是直接在其位置插入字符串并且自动加上单引号,比如username=“d”,则"a"#{username}“min"被看做"a”‘d’“min”,又根据第一条理论,故"a"#{username}“min"在mysql被识别为"admin”。
- 总的来说,如果不是特殊情况,如果能同时使用${}和#{},我们优先考虑使用占位符赋值#{}。因为字符串拼接操作${}容易产生SQL注入,可以参考我的文章JDBC基本处理流程的核心步骤第三点。字符串拼接${}可以看做使用的是Statement,而#{}可以看做是用的是PreparedStatement。毕竟MyBatis是一个持久层ORM框架,底层是对JDBC的封装。