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

博主分享开发中通过id列表查询数据的优化过程。最初用for循环逐个查询,高并发下数据库压力大。后采用批量查询,用SQL的in方法一次性获取数据,再将结果转为map,通过遍历id列表从map取数据,可大大减少数据库访问,列表越大性能越优。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

话不多说,上代码:

模拟一个传进来的id列   

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

原来的思路:

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

mapper查询语句:

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

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

新思路写法;

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

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

mapper语句:

@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:

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

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

 

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

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

 

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

 

                                                                                                                                                         记录自己,帮助他人!

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值