关于CacheUtil的疑问

Blade 未结 3 1581
bluerose
bluerose 剑圣 2022-03-31 22:28

直接截取2段代码说明疑问。

image.png

上图为userCache的代码。但是更新user的时候是批量删除USER_CACHE全部的方式。如下图

image.png

如果是这样,每次更新任何一个用户信息就丢弃所有的用户缓存,这样是不是太暴力了?为何不细化到每一个key呢?谢谢解惑!

3条回答
  • 我对这个清除缓存方式 我觉得是不高效的 ,后面我对我的业务统一用

    CacheUtil.evict

    这个方法来清缓存

    一下为我写的一个业务缓存类,你重点关注 evict方法就可以了

    /**
     * 道闸设备缓存
     *
     * @author : yun.can
     * @since : 2021-10-07 08:00
     **/
    @Slf4j
    public class PlateDeviceCache {
    
       private static final IPlateDeviceService plateDeviceService;
    
       private static final String PLATE_PARK_SERIAL_NO_PROFILE = "plate::serialno::";
       private static final String PLATE_PARK_DEVICE_ID_PROFILE = "plate::deviceId::";
       private static final String PLATE_PARK_LIST_PROFILE = "plate::list::";
       private static final String PLATE_PARK_ID_PROFILE = "plate::parkId::";
    
    
       static {
          plateDeviceService = SpringUtil.getBean(IPlateDeviceService.class);
       }
    
       /**
        * 获取道闸停车设备
        *
        * @param serialNo 设备序列号
        * @return PlateDevice
        */
       public static PlateDevice getBySerialNo(String serialNo) {
          PlateDevice plateDevice = CacheUtil.get(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_SERIAL_NO_PROFILE, serialNo, () -> plateDeviceService.selectBySerialno(serialNo), false);
          if (null == plateDevice)
          {
             throw new PlateException(String.format("无效的设备序列号: %s", serialNo));
          }
          return plateDevice;
       }
       /**
        * 根据Id获取道闸停车设备
        *
        * @param deviceId 设备Id
        * @return PlateDevice
        */
       public static PlateDevice getById(Long deviceId) {
          PlateDevice plateDevice = CacheUtil.get(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_DEVICE_ID_PROFILE, deviceId, () -> plateDeviceService.getById(deviceId), false);
          if (null == plateDevice)
          {
             throw new PlateException(String.format("无效的设备Id: %s", deviceId));
          }
          return plateDevice;
       }
       /**
        * 根据停车场id查询设备
        *
        * @param parkId 停车场Id
        * @return PlateDevice
        */
       public static List<PlateDevice> getByParkId(Long parkId) {
          List<PlateDevice> plateDevice = CacheUtil.get(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_ID_PROFILE, parkId, () -> plateDeviceService.selectByParkId(parkId), false);
          if (null == plateDevice || plateDevice.size() == 0)
          {
             throw new PlateException(NOT_FOUND_PLATE_DEVICE,parkId.toString());
          }
          return plateDevice;
       }
    
       /**
        * 获取主相机设备对象
        * @param parkId 车场Id
        * @param outEnum 入口还是出口的主相机
        * @return 道闸相机设备对象
        */
       public static PlateDevice getMainCamera(Long parkId,InOutEnum outEnum){
          List<PlateDevice> plateDevices = getByParkId(parkId);
          List<PlateDevice> devices = plateDevices.stream().filter(plateDevice -> plateDevice.getInOut().equals(outEnum.getOpt()) && plateDevice.getMainCamera().equals(1)).collect(Collectors.toList());
          if (devices.size() == 0){
             throw new PlateException(NOT_FOUND_MAIN_CAMERA,outEnum.getOptInfo());
          }
          if (devices.size() > 1){
             throw new PlateException(BIND_MULTIPLE_MAIN_CAMERA);
          }
          return devices.get(0);
       }
    
       /**
        * 查询用于选择停车场列表的list数据
        * @return 道闸相机设备对象列表
        */
       public static List<PlateDevice> selectList() {
          return CacheUtil.get(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_LIST_PROFILE, AuthUtil.getTenantId(), () ->
             plateDeviceService.lambdaQuery().select(PlateDevice::getId, PlateDevice::getSerialno, PlateDevice::getParkName, PlateDevice::getDeviceName)
                .orderByDesc(PlateDevice::getCreateTime).list(), false);
       }
    
       /**
        * 清除道闸设备缓存
        * @param plateDevice 道闸相机设备对象
        */
       public static void evict(PlateDevice plateDevice) {
          if (!Func.isNull(plateDevice) && Func.isNotEmpty(plateDevice.getSerialno()) && Func.isNotEmpty(AuthUtil.getTenantId())) {
             CacheUtil.evict(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_SERIAL_NO_PROFILE, plateDevice.getSerialno(), false);
             CacheUtil.evict(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_LIST_PROFILE, AuthUtil.getTenantId(), false);
             CacheUtil.evict(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_ID_PROFILE,plateDevice.getParkId(), false);
             CacheUtil.evict(PlateCacheConstant.PLATE_DEVICE_CACHE, PLATE_PARK_DEVICE_ID_PROFILE,plateDevice.getId(), false);
          } else {
             log.warn("清除道闸设备缓存失败警告!入参数据:{}", plateDevice);
             CacheUtil.clear(PlateCacheConstant.PLATE_DEVICE_CACHE);
             CacheUtil.clear(PlateCacheConstant.PLATE_DEVICE_CACHE,false);
          }
    
       }
    
    
    }


    0 讨论(0)
  • 2022-04-01 13:31

    我们也推荐业务模块细化evit,但是之前有过用户修改系统模块,没有删除完全,最后出了问题好久才找到。

    所以我们现在系统层级的都是一次性全部清除,虽然范围大了点,但是可以保证用户在修改系统模块的时候不会因为这一点导致问题出现。

    0 讨论(0)
  • 2022-04-06 22:19

    谢谢各位大侠

    0 讨论(0)
提交回复