我想在删除多个用户时返回删除失败的用户的id
正常实现需要多次调用Mapper,会比较慢
可以mybatis实现一个方法里面包含多个sql语句
但这样实现不了我的需求
于是选择用存储过程
先写个存储过程并测试一下,再用mybatis调用就ok了
存储过程
- 存储过程需要在调用之前创建好,等待调用就好
- 存储过程的create语法
create procedure name (in arg1 type, out arg2 type)
begin
end;
in为输入参数,out为输出参数,type为mysql的数据类型,begin和end之间写sql语句就好了
- 存储过程的基本思路
输入参数为list,而sql没有这种类型,所以将list变成以逗号分割的字符串,再通过循环切割字符串得到每个id。
用id去修改user.status达到删除的目的,通过row_count()返回上一条语句受影响行数,判断是否删除成功,不
成功的,查出对应id。
- 切割字符串采用substring_index(str, ‘,’ , i)函数,截取到str在第i个逗号‘,’左边的字符,i为负数时则为从右边开始截取。
substring_index("1,2,3,4,5,6", ',', 5)
substring_index("1,2,3,4,5,6", ',', -1)
第一行结果是 1,2,3,4,5
第二行结果是 6
- 存储过程代码
drop procedure if exists delete_users;
create procedure delete_users(in users varchar(1000))
begin
declare length, i, id, exist int default 1;
select substring(users, 2, length(users)-2) into users;
select length(users)-length(replace(users, ',', ''))+1 into length;
while i <= length do
set exist = 0;
select substring_index(substring_index(users, ',', i), ',', -1) into id;
update user set status = 1 where user.user_id = id;
if row_count() = 0 then
select id;
end if;
set i = i+1;
end while;
end;
可以通过call procedure来调用
call delete_users('[1, 2, 3,7]')
- mybatis调用存储过程
mapper写法
<select id="invalidUsers" statementType="CALLABLE" parameterType="String" resultType="Integer">
call delete_users(#{users, mode=IN, jdbcType=VARCHAR})
</select>
dao接口
List invalidUsers(@Param("users")String users);
注意这里参数类型是string
测试
@Test
public void invalidUsers() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List list1 = userMapper.invalidUsers(list.toString());
log.info("删除多用户 》》》" + list1);
}