mybatis plus中使用in动态sql的踩坑记录
项目中有个需求,根据多个整型id查询对应的信息
理论上最终sql应该是如下所示:
select userName form t_user where userId in(1,2,3,4,5,6);
但前端传来的参数
Integer[] userIdArr
想着就把userIdArr转成1,2,3,4,5,6就行了
/**
* [1,2,3] to 1,2,3
*
* @return
public static String intArrToString(Integer[] arr) {
return StringUtils.join(arr, ",");
}
然后将字符串形式的userArrIds作为参数传给mappe,于是写成动态sql如下
@Select("select userName from t_user where userId in (#{userArrIds})")
List<String> getUserNameByUserIds(String userArrIds);
按照预想的,它应该生成如下sql语句
select userName form t_user where userId in(1,2,3,4,5,6);
自测一下,发现无论userIdArr传多少个,都只能查出第一个,郁闷了半天
才发现被自己“蠢哭了”,因为将Integer[] userIdArr转换成了String,最终的sql其实是这样的
select userName form t_user where userId in('1,2,3,4,5,6');
整个参数被当成了一个完整的字符串
使用QueryWrapper既然发现了问题,这条路就走不通了,换一个方法实现,还是将Integer[] userIdArr转换成String,这回用com.baomidou.mybatisplus.core.conditions.query.QueryWrapper来生成动态sql
List<UserDo> userList = userMapper.selectList(new QueryWrapper<UserDo>().inSql("userID",result).select("userName"));
这样结果是查出来了,但也有个问题,因为在定义BaseMapper的时候项目组已经约定了泛型为UserDo,所以用QueryWrapper查询返回值只能是UserDo的列表或单行,如果我需要其他想要的类型都只能通过额外的转换。
@Repository
public interface UserMapper extends BaseMapper<UserDo> {
…………………………
}
比如我这只需要返回一个List<userName>,拿到数据后还需要转换一下,虽然转换并不难,但还是觉得有点多余。
List<String> userNameList = userDoList.stream().map(UserDo::getuserName).collect(Collectors.toList());@Select+script
鉴于上面的方法存在两个不优雅的问题
需要将整形数组参数转换成字符串返回结果需要二次转换查阅了很多资料后,发现一个更好的实现方法,既不需要转换入参,也可以按自己的需求决定返回值。
@Select("<script> " +
"select userNanme from t_user where userId " +
"in <foreach item='item' index='index' collection='userIdArr' open='(' separator=',' close=')'> #{item} </foreach> " +
"</script>")
List<String> getUserNameByUserIds(Integer[] userIdArr);
版权声明
本文仅代表作者观点,不代表博信信息网立场。
上一篇:Seata 在蚂蚁国际银行业务的落地实践 下一篇:经典Mysql50道练习题