跳到主要内容

徽章信息缓存

像徽章这种东西,每个用户都会去查询,我们可以考虑放到缓存中。那么是放到本地缓存还是Redis缓存中呢?

  • 如果是经常变得东西,那么我们考虑放到Redis缓存中
  • 如果静态不常变,那么我们考虑放本地缓存,因为可以减少网络IO。Redis的瓶颈就是带宽

我们可以使用Spring的Cacheable注解进行缓存

配置

自己配置使用的是caffine

@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {

@Bean("caffeineCacheManager")
@Primary
public CacheManager caffeineCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
// 方案一(常用):定制化缓存Cache
cacheManager.setCaffeine(Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.initialCapacity(100)
.maximumSize(200));
return cacheManager;
}

}

为要缓存的内容添加缓存类:

Spring缓存几个比较重要的注解:

  • @Cacheable:该注解用于标注将结果缓存的方法。每次调用该方法时,Spring 会先检查缓存是否存在,如果存在则直接返回缓存中的结果,否则调用方法并将结果缓存。

@Cacheable(value = "cacheName", key = "#id")

  • value: 缓存的名称,可以是一个或多个。
  • key: 缓存的键值,支持 SpEL 表达式。

每个名称会创建一个CacheManager,相当于做了一个分组

  • @CachePut:该注解用于标注既要执行方法,又要将方法结果更新到缓存的方法。通常用于创建或更新缓存数据。

  • @CacheEvict:该注解用于标注移除缓存条目(或清空缓存)的方法。可以配置在数据更新或删除的方法上。

@Component
public class ItemCache {// todo 多级缓存

@Autowired
private ItemConfigService itemConfigService;

@Cacheable(cacheNames = "item", key = "'itemsByType:'+#type")
public List<ItemConfig> getByType(Integer itemType) {
return itemConfigService.getByType(itemType);
}

@Cacheable(cacheNames = "item", key = "'item:'+#itemId")
public ItemConfig getById(Long itemId) {
return itemConfigService.getById(itemId);
}
}

使用:查询所有徽章信息:

@Override
public List<BadgeResponse> badges(Long uid) {
// 获取所有的徽章
List<ItemConfig> itemConfigs = itemCache.getByType(ItemTypeEnum.BADGE.getType());
// 获取用户拥有的徽章
List<UserBackpack> userBackpacks = userBackpackService.
getByItemIds(uid, itemConfigs.stream().map(ItemConfig::getId).collect(Collectors.toList()));
// 查询用户佩戴的徽章
User user = getById(uid);
return UserAdapter.buildBadgeResponse(itemConfigs, userBackpacks, user);
}