您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页一些特殊SQL使用Mybatis的#{}和${}注意点

一些特殊SQL使用Mybatis的#{}和${}注意点

来源:化拓教育网

Mybatis对JDBC进行了进一步封装,使得我们可以更加便捷的使用Java操作数据库。Mybatis获取参数值有两种方式:#{}${}

在大部分情况下,#{}${}都能相互替代,使用两者之一即可,更加推荐使用#{},因为可以防止SQL注入问题,但是由于#{}${}本质上的不同,部分SQL语句使用#{}${}需要格外注意

#{}和${}本质区别

模糊查询

这个场景下,使用#{}${}都能达到目的,但是用法稍有不同

Mapper接口

List<User> selectLike(@Param("likeString") String likeString);

直接使用#{}

<select id="selectLike" resultType="pojo.User">
	select * from user where user_name like '%#{likeString}%'
</select>

结果报错,?占位符被当做字符串处理了

将#{}换成${}

<select id="selectLike" resultType="pojo.User">
    select * from user where user_name like '%${likeString}%'
</select>

成功执行

如果非要使用#{},也不是没有解决办法

使用""拼接

<select id="selectLike" resultType="pojo.User">
    select * from user where user_name like "%"#{likeString}"%"
</select>

结果

使用concat函数

<select id="selectLike" resultType="pojo.User">
    select * from user where user_name like concat('%',#{likeString},'%')
</select>

结果

动态表名

在某些场景下,我们需要来回操作各种表,但SQL语句功能一致,这时我们可以使用动态表名,即传参为表名类型,这时就要从#{}${}中进行选择了

Mapper接口

List<User> selectAllFromTable(@Param("tableName") String tableName);

直接使用#{}

<select id="selectAllFromTable" resultType="pojo.User">
    select * from #{tableName}
</select>

结果报错,原因在于#{}为占位符赋值,传参为String的话就会自动补上单引号'',而表名不允许添加单引号,所以导致出错

使用${}

<select id="selectAllFromTable" resultType="pojo.User">
    select * from ${tableName}
</select>

结果成功了,所以在动态表名的情况下,我们只能使用${}

分页

分页是一个实际开发中用的很广泛的一个功能,但是使用MyBatis传参进行手动分页时,坑可不小

首先我们来看一下分页公式

select * from <表名> limit <每页大小> * (<页码> - 1), <每页大小>; 

写出公式,分页就变得很简单了,但是这时候使用#{}进行传参就有一些问题

/**
 * @param pageSize 每页大小
 * @param currentPage 当前页码
 * @return 结果集List
 */
List<User> selectAllByPage(@Param("pageSize") Integer pageSize, @Param("currentPage") Integer currentPage);

使用#{}

<select id="selectAllByPage" resultType="pojo.User">
    select * from #{pageSize} * (#{currentPage} - 1), #{pageSize}
</select>

结果报错,原因在于limit后面不能运算,而我们传入的正是运算表达式

既然不能运算,那我们将运算结果传进去不就好了?

<select id="selectAllByPage" resultType="pojo.User">
    select * from #{pageSize * (currentPage - 1)}, #{pageSize}
</select>

结果还是报错,原因在于#{}会将大括号内的表达式整体当成一个参数给占位符赋值,这显然是不可以的

使用${}

<select id="selectAllByPage" resultType="pojo.User">
    select * from user limit ${pageSize * (currentPage - 1)}, #{pageSize}
</select>

结果成功了,${}会先把大括号内的表达式计算出来,再来进行字符串拼接

批量删除

有些场景,需要我们根据id数组批量删除记录,这个时候也有一些坑

由于id数组的长度是不确定的,所以我们不能确定参数的个数,但是我们可以使用in关键字,这个时候我们将id数组转为字符串进行传参就好了

[1,2,3] => 1,2,3

Mapper接口

Integer deleteByIds(String Ids);

使用#{}

<delete id="deleteByIds">
    delete from user where id in (#{ids})
</delete>

结果报错,原因在于in后面的小括号里面的'1,2,3'为字符串类型且为一个整体,与整数类型不符,因此不能使用#{}

使用${}

<delete id="deleteByIds">
    delete from user where id in (${ids})
</delete>

结果成功了,看来有些场景不得不使用${}

使用${}

<delete id="deleteByIds">
    delete from user where id in (${ids})
</delete>

结果成功了,看来有些场景不得不使用${}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务