1.创建测试表
创建User表
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(12) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名称',
`password` varchar(80) COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
`last_token` text COLLATE utf8mb4_general_ci COMMENT '登陆时的token',
`status` tinyint(4) DEFAULT '0' COMMENT '用户状态 -1代表已删除 0代表正常 1代表冻结',
`created_at` bigint(20) DEFAULT NULL COMMENT '创建时间',
`updated_at` bigint(20) DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
复制代码
填充数据
BEGIN;
INSERT INTO `users` VALUES (1, 'test1', '$2y$10$.mzu/iNaNDJRex.vA06IQu7xg5vwvE8PYhsPQPaIV74uK4BcrzUUm', NULL, 0, 20190625075319, 20190625075319);
INSERT INTO `users` VALUES (2, 'test2', '$2y$10$P5ALENaHchjrwN8NXUrDAeuVGQmcoyuSzvfhaC073cgPh2slPEzZ.', NULL, 0, 20190625075639, 20190625075639);
INSERT INTO `users` VALUES (3, 'test3', '$2y$10$0fqd.LhBt4CBjM4W2X/Dse1i2jer1iJ8gtTjS4S7ZwF5wkxNpbqDC', NULL, 0, 20190625075644, 20190625075644);
COMMIT;
复制代码
2.使用#{param}
使用MyBatis的过程中,向SQL语句中传参是必不可少的。在使用MyBatis的大多数情况下是使用#{}来接收参数。
2.1.根据Name查询用户信息
编写根据用户ID查询用户信息的查询接口:
UserPo selectUserByName(@Param("name") String name);
复制代码
接口对应的XML文件UserMapper.XML中对应的<select>标签如下:
<select id="selectUserByName" parameterType="string" resultMap="BaseResult">
SELECT
*
FROM USERS
WHERE name = #{name}
</select>
复制代码
selectUserByName的SQL语句接收一个String类型的参数,参数符号#{name}。
调用selectUserByName("test1") 方法,根据Name查询用户信息,实际执行SQL如下:
SELECT * FROM USERS WHERE name = 'test1'
复制代码
运行截图:
2.2.等效JDBC代码
String selectUserByName = "SELECT * FROM USERS WHERE name=?";
PreparedStatement ps = conn.prepareStatement(selectUserByName);
ps.setInt(1,name);
复制代码
3.使用${param}
在MyBatis XML中使用${}来接收参数。
3.1.根据Name查询用户信息
使用2.1.根据Name查询用户信息的查询方法,修改UserMapper.xml中selectUserByName的参数符号为${name}。
再次调用selectUserByName("test1")方法,实际执行SQL如下:
SELECT * FROM USERS WHERE name = test1
复制代码
但是SQL执行失败,此时的错误信息如下:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test1' in 'where clause'
### The error may exist in file [/Users/heng/worker/java/springboot_practice/springboot_mybatis/target/classes/mapper/UserDao.xml]
### The error may involve com.example.mybatis.dao.UserDao.selectUserByName-Inline
### The error occurred while setting parameters
### SQL: SELECT * FROM USERS WHERE name = test1
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test1' in 'where clause'
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test1' in 'where clause'] with root cause
复制代码
SQL语句错误,test1不是Users表中的字段。
修改调用方法selectUserByName("'test1'"),实际执行SQL如下:
SELECT * FROM USERS WHERE name = 'test1'
复制代码
运行截图:
3.2.等效JDBC代码
String selectUserByName = "SELECT * FROM USERS WHERE name=" + name;
复制代码
4.总结
-
用
#{name},MyBatis会创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个?来标识,并被传递到一个新的预处理语句中。 -
用
${name},MyBatis则会直接替换参数 (用${name}方式可以用在表名替换上)。 -
通常情况下只需使用
#{name}即可满足大多数需求。
用`${name}`方式接受用户的输入,并将其用于语句中的参数是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。




近期评论