MyBatis中獲取參數值的兩種方式:${} 和 #{},以及它們之間區別是什麼? ${}:的本質就是字元串拼接 #{}:的本質就是占位符賦值 ...
MyBatis中獲取參數值的兩種方式
${}:的本質就是字元串拼接 #{}:的本質就是占位符賦值
① 使用${}占位符,在字元串拼接的方式拼接sql,若為字元串類型或為日期類型的欄位進行賦值時,需要手動加單引號
② 使用#{}占位符賦值的方式拼接sql,此時為字元串類型或日期類型的欄位進行賦值時,自動添加單引號
MyBatis中的#{}和${}的區別是什麼? --前者動態參數,後者字元串拼接
首先,MyBatis提供的#號占位符和$占位符,都是實現動態SQL的一種方式,通過這兩種方式把參數傳遞給xxxMapper.XML
在執行SQL操作之前,MyBatis會對這兩種占位符進行動態解析
‘#’號占位符,等同於jdbc裡面的?號占位符,它相當於向PreparedStatement中的預處理語句中設置參數,而PreparedStatement中的sql語句是預編譯的,SQL語句中使用了占位符規定了SQL語句的機構,並且在設置參數的時候,如果有特殊字元,會自動進行轉義,所以使用#號占位符還可以防止SQL註入。
而使用$占位符的方式進行傳參,相當於直接把參數拼接到原始的SQL裡面,MyBatis不會對它進行特殊處理
<!-- User getUserByUsername(String username); -->
<select id="getUserByUsername" resultType="User">
<!-- 通過#{}占位符 獲取參數 填充 -->
select * from user where username = #{username};
<!-- 通過${}占位符 獲取參數需要加單引號
select * from user where username = '${username}';
-->
</select>
所以$和#最大的區別在於,前者是動態參數,後者是占位符,動態參數無法防止SQL註入的問題,所以在實際應用中,應該儘可能的使用#號占位符
另外,$占位符,可以應用在一些動態SQL場景中,比如動態傳遞表名,批量刪除等
模糊查詢:
<!-- 模糊查詢 -->
<!-- List<User> getUserByLike(@Param("username") String username); -->
<select id="getUserByLike" resultType="user">
<!-- select * from user where username like '%${username}%'; -->
<!-- select * from user where username like concat('%',#{username},'%'); -->
select * from user where username like "%"#{username}"%";
</select>
動態傳遞表名
<!-- List<User> getUserByTableName(@Param("tableName") String tableName); -->
<select id="getUserByTableName" resultType="User">
select * from ${tableName};
</select>
批量刪除
<!-- 批量刪除 -->
<!-- Integer deleteMore(@Param("ids") String ids); -->
<delete id="deleteMore">
delete from user where id in(${ids});
</delete>
雖然用$和#都能實現Mybatis獲取參數,併進行SQL拼接,但是大多數還是建議使用#號占位符並且大部分情況下都是使用@Param註解配合#號獲取參數,還能有效的避免SQL註入問題。
- 模糊查詢可以使用like concat
<!--List<SysUser> selectAllocatedList(SysUser sysUser);-->
<select id="selectAllocatedList" parameterType="SysUser" resultMap="SysUserResult">
SELECT DISTINCT u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
LEFT JOIN sys_user_role ur oN u.user_id = de.dept_id
LEFT JOIN sys_role r ON r.role_id = ur.role_id
WHERE u.del_flag = '0' AND r.role_id = #{roleId}
<if test="userName != null and userName != ''">
AND u.user_name LIKE CONCAT('%', #{userName}, '%')
</if>
<if test="phoneNumber != null and phoneNumber != ''">
AND u.phonenumber LIKE CONCAT('%', #{phoneNumber}, '%')
</if>
</select>
- 批量刪除可以用都可以使用foreach標簽等
<!--Integer deleteUserByUserIds(@Param("userIds")Long[] userIds);-->
<update id="deleteUserByIds" parameterType="Long">
UPDATE sys_user
SET del_flag = '2' WHERE user_id IN
<foreach collection="array" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</update>