您的位置:首页 > 编程语言 > Java开发

利用java8的stream的list转map,实现数据库批量查询业务逻辑,减低数据库压力

2019-05-17 16:04 567 查看

之前在开发过程中,遇到了这样的一个业务场景,需要通过传进来的一个id列表list去查询一个list数据,然后再对每一个数据做相应的业务处理,那时候刚出来工作,第一时间想到的是用for循环去遍历这个id列表,然后一个一个去根据id把对应的数据查出来,再做处理。

乍一看这样处理没什么问题,但是当传进来的id列表很大的时候,对数据库的操作就太频繁了,假如id列表有10个数据,就得查询10次数据库,当三个用户同时访问得时候,就得查询30次,那在高并发的情况下数据库就炸了。后来写完再代码回看的时候,发现这样有点傻,就想到了先通过批量查询,把List<id>作为一个查询条件通过sql的 in 方法先去一次过把数据全查出来,然后把查出来的List<>数据通过Stream转为map,再通过遍历id列表,以id为key去一个一个拿map中的数据,这样就可以大大减低数据库的访问了。

话不多说,上代码:

模拟一个传进来的id列   

[code]List<Integer> ids = Arrays.asList(1,2,4,5);

原来的思路:

[code]for (int i = 0; i < ids.size(); i++) {
//遍历查询User
User user = userMapper.getById(ids.get(i));
/*
* 这里写处理业务
* */
}

mapper查询语句:

[code]@Select("select * from user where id = #{id}")
User getById(@Param("id") Integer id);

没接触Stream之前,我基本上遇到这种查询多个的,都这样写,直到那个风和日丽的下午,我去看了java8的新特性

新思路写法;

先一次性批量查询出所有的数据

[code]List<User> userList = userMapper.getByIds(ids);

mapper语句:

[code]@Select({
"<script>" +
"select * from user where id in " +
"<foreach item = 'item' index = 'index' collection = 'ids' open='(' separator=',' close=')'>" +
"#{item}" +
"</foreach>"+
"</script>"})
List<User> getByIds(@Param("ids") List<Integer> ids);

再把查询出来的List<User>转为以id为key的map:

[code]Map<Integer, User> userMap = userList.parallelStream().collect(Collectors.toMap(User :: getId, u -> u, (u1, u2) -> u1));

(u1, u1)-> u1 是表示当有两个key相同的时候,取第一个,一般id是不会重复,不过难免以后会有以其他作为key的情况出现

 

接着遍历id列表去一个一个拿需要的数据:

传统遍历方法:

[code]for (Integer id : ids) {
User user = userMap.get(id);
/*
* 这里写业务
* */
}

stream写法:

[code]ids.stream().forEach(id ->{
User user = userMap.get(id);
/*
* 这里写业务
* */
});

这样就可以大大的减少数据库的访问了,我这里传进来的id列只有4个,那么用stream的思路就可以减少3次的访问,传进来的列表越大这样的写法性能越优,而我们写业务肯定得考虑高并发得情况,所以我觉得这个东西还是很有帮助的。

 

                                                                                                                                                         记录自己,帮助他人!

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐