获取参数值的两种方式
2026/1/15大约 3 分钟MyBatis参数传递SQL注入
MyBatis获取参数值的两种方式
${} 和 #{} 的区别
MyBatis 获取参数值的两种方式:${} 和 #{}
| 方式 | 本质 | 特点 |
|---|---|---|
${} | 字符串拼接 | 需要手动加单引号,有 SQL 注入风险 |
#{} | 占位符赋值 | 自动添加单引号,安全推荐 |
${}使用字符串拼接的方式拼接 SQL,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号#{}使用占位符赋值的方式拼接 SQL,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
1. 单个字面量类型的参数
若 Mapper 接口中的方法参数为单个的字面量类型,此时可以使用 ${} 和 #{} 以任意的名称获取参数的值。
// Mapper接口
User getUserByUsername(String username);<!-- 使用 #{} -->
<select id="getUserByUsername" resultType="User">
select * from t_user where username = #{username}
</select>
<!-- 使用 ${} 需要手动加单引号 -->
<select id="getUserByUsername" resultType="User">
select * from t_user where username = '${username}'
</select>2. 多个字面量类型的参数
若 Mapper 接口中的方法参数为多个时,此时 MyBatis 会自动将这些参数放在一个 Map 集合中:
- 以
arg0, arg1...为键,以参数为值 - 以
param1, param2...为键,以参数为值
因此只需要通过 ${} 和 #{} 访问 Map 集合的键就可以获取相对应的值。
// Mapper接口
User checkLogin(String username, String password);<select id="checkLogin" resultType="User">
select * from t_user where username = #{arg0} and password = #{arg1}
</select>
<!-- 或者使用 param1, param2 -->
<select id="checkLogin" resultType="User">
select * from t_user where username = #{param1} and password = #{param2}
</select>3. Map集合类型的参数
若 Mapper 接口中的方法参数为多个时,此时可以手动创建 Map 集合,将这些数据放在 Map 中,只需要通过 ${} 和 #{} 访问 Map 集合的键就可以获取对应的值。
// Mapper接口
User checkLoginByMap(Map<String, Object> map);<select id="checkLoginByMap" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>// 测试代码
@Test
public void testCheckLoginByMap() {
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("password", "123456");
User user = mapper.checkLoginByMap(map);
System.out.println(user);
}4. 实体类类型的参数
若 Mapper 接口中的方法参数为实体类对象时,此时可以使用 ${} 和 #{},通过访问实体类对象中的属性名获取属性值。
// Mapper接口
int insertUser(User user);<insert id="insertUser">
insert into t_user values(null, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>// 测试代码
@Test
public void testInsertUser() {
User user = new User(null, "李四", "123456", 25, "男", "lisi@qq.com");
int result = mapper.insertUser(user);
System.out.println(result);
}5. 使用@Param标识参数(推荐)
可以通过 @Param 注解标识 Mapper 接口中的方法参数。
此时,会将这些参数放在 Map 集合中:
- 以
@Param注解的 value 属性值为键,以参数为值 - 以
param1, param2...为键,以参数为值
// Mapper接口
User checkLoginByParam(@Param("username") String username, @Param("password") String password);<select id="checkLoginByParam" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>总结
推荐使用方式
- 实体类类型参数:直接使用属性名
- 多个参数:使用
@Param注解标识 - 单个参数:可以使用任意名称,但建议使用有意义的名称
- 优先使用
#{}:安全,防止 SQL 注入
