如何用Map优化Java中批量PriceCode的查询与赋值逻辑?
核心优化思路:批量查询+Map映射
把循环内的多次数据库查询合并为1次批量查询,再通过Map快速匹配赋值,彻底解决N次查询的性能问题。
1. 先给Repository添加批量查询方法
你的现有Repository只支持单个priceCode查询,需要新增一个支持批量参数的方法(Spring Data JPA原生支持In语法):
// ManufacturerPriceCodesRepository接口新增方法 public interface ManufacturerPriceCodesRepository extends JpaRepository<ManufacturerPriceCodes, Long> { List<ManufacturerPriceCodes> findByManufacturerIDAndPriceCodeInAndRecordDeleted( Long manufacturerID, Collection<String> priceCodes, String recordDeleted ); }
2. 修改业务方法实现优化逻辑
调整原方法,先批量拉取所有需要的数据,转成Map后再循环赋值:
private Item getItemManufacturerPriceCodes(Item item) { List<ItemPriceCode> itemPriceCodes = item.getItemPriceCodes(); // 提取所有需要查询的priceCode集合 List<String> priceCodes = itemPriceCodes.stream() .map(ItemPriceCode::getPriceCode) .collect(Collectors.toList()); // 仅执行1次批量查询,替换原循环内的多次查询 List<ManufacturerPriceCodes> mpcList = manufacturerPriceCodesRepository.findByManufacturerIDAndPriceCodeInAndRecordDeleted( item.getManufacturerID(), priceCodes, NOT_DELETED ); // 转成以priceCode为key的Map,实现O(1)快速取值 Map<String, String> priceCodeNameMap = mpcList.stream() .collect(Collectors.toMap( ManufacturerPriceCodes::getPriceCode, ManufacturerPriceCodes::getName )); // 循环赋值,直接从Map取值,无需再查数据库 for(ItemPriceCode ipc : itemPriceCodes) { String name = priceCodeNameMap.get(ipc.getPriceCode()); if(name != null) { ipc.setManufacturerPriceCode(name); } } // 保留原有的删除逻辑 item.getItemPriceCodes().removeIf(ipc -> DELETED.equals(ipc.getRecordDeleted())); return item; }
关键细节说明
- 批量查询:
findBy...In是Spring Data JPA的标准语法,会生成带IN条件的SQL,一次性拉取所有匹配数据,避免频繁数据库交互。 - Map映射:将查询结果转为
priceCode -> 名称的键值对,循环时直接通过key取值,时间复杂度从O(n)降为O(1)。 - 逻辑对齐:原代码中查询不到则不赋值,这里用
Map.get()返回null时跳过赋值,和原业务逻辑完全一致。
内容的提问来源于stack exchange,提问作者user20714961
相关产品推荐
相关产品推荐

