mybatis 差异更新法
主表酒店(blue_hotel)和子表房间(blue_hotel_room)
1.先找出要删除的房间(存在于旧房间但不在新房间中),筛选出新房间的id,然后拿新房间的id去和旧房间做过滤,最后得到结果。代码示例
/*** 找出需要删除的房间(存在于oldRooms但不在newRooms中)** @param oldRooms* @param newRooms* @return*/private List<BlueHotelRoom> findRoomsToDelete(List<BlueHotelRoom> oldRooms, List<BlueHotelRoom> newRooms) {// 收集新房间中的所有ID(使用Set提高查找效率)Set<Long> newRoomIds = newRooms.stream().map(BlueHotelRoom::getHotelRoomId).filter(Objects::nonNull).collect(Collectors.toSet());// 返回旧房间中不在新房间ID集合中的房间return oldRooms.stream().filter(room -> !newRoomIds.contains(room.getHotelRoomId())).collect(Collectors.toList());}
2.找出需要新增或更新的房间。将旧房间的数据转换为Map<房间ID,房间对象>的数据形式,然后拿新房间的数据做过滤,新房间中的id等于空或者不在旧房间中,证明是需要新增或者更新的房间,最后检查其它字段的数据一致,不一致则更新字段。示例代码
/*** 找出需要新增或更新的房间** @param oldRooms* @param newRooms* @return*/private List<BlueHotelRoom> findRoomsToAddOrUpdate(List<BlueHotelRoom> oldRooms, List<BlueHotelRoom> newRooms) {// 收集旧房间中的所有ID(使用Map提高查找效率)Map<Long, BlueHotelRoom> oldRoomMap = oldRooms.stream().collect(Collectors.toMap(BlueHotelRoom::getHotelRoomId, room -> room));return newRooms.stream().filter(room -> {// 新增房间(ID为null或不在旧房间中)if (room.getHotelRoomId() == null) return true;if (!oldRoomMap.containsKey(room.getHotelRoomId())) return true;// 检查是否需要更新(比较关键字段)BlueHotelRoom oldRoom = oldRoomMap.get(room.getHotelRoomId());return !Objects.equals(room.getHotelRoomName(), oldRoom.getHotelRoomName()) ||!Objects.equals(room.getOrderNum(), oldRoom.getOrderNum());// 添加其他需要比较的字段}).collect(Collectors.toList());}
3.最后更新的时候先更新主表数据,也就是酒店的数据。然后查询现有的房间数据,也就是旧的房间数据(oldRooms)新的房间数据就是传过来的房间数据(newRooms),最后调用两用上面两个方法,该删除的删除,该新增的新增。示例代码
/*** 修改酒店管理** @param blueHotel 酒店管理* @return 结果*/@Transactional@Overridepublic int updateBlueHotel(BlueHotel blueHotel) {blueHotel.setUpdateTime(DateUtils.getNowDate());List<BlueHotelRoom> newRooms = blueHotel.getBlueHotelRoomList();// 1. 更新主表int rows = blueHotelMapper.updateBlueHotel(blueHotel);// 2. 查询现有房间List<BlueHotelRoom> oldRooms = blueHotelMapper.selectBlueHotelRoomByHotelId(blueHotel.getHotelId());// 3. 找出需要删除的房间(存在于old但不在new中)List<BlueHotelRoom> toDelete = findRoomsToDelete(oldRooms, newRooms);toDelete.forEach(room -> {blueHotelMapper.deleteBlueHotelRoomByHotelRoomId(room.getHotelRoomId());});// 4. 找出需要新增/更新的项目List<BlueHotelRoom> toAddOrUpdate = findRoomsToAddOrUpdate(oldRooms, newRooms);toAddOrUpdate.forEach(room -> {room.setHotelId(blueHotel.getHotelId());if (room.getHotelRoomId() == null) {blueHotelMapper.insertBlueHotelRoom(room);} else {blueHotelMapper.updateBlueHotelRoom(room);}});return rows;}