feat(service): 为主题操作增加 Redis 缓存同步刷新

在新增、更新、删除主题时,按风格维度刷新 Redis 缓存,保持缓存与数据库一致,提升读取性能。
This commit is contained in:
2025-12-29 15:43:23 +08:00
parent c3b18774e0
commit 2eaf9a37d5

View File

@@ -5,21 +5,18 @@ import com.yolo.keyboard.controller.admin.themes.vo.KeyboardThemesPageReqVO;
import com.yolo.keyboard.controller.admin.themes.vo.KeyboardThemesSaveReqVO; import com.yolo.keyboard.controller.admin.themes.vo.KeyboardThemesSaveReqVO;
import com.yolo.keyboard.dal.dataobject.themes.KeyboardThemesDO; import com.yolo.keyboard.dal.dataobject.themes.KeyboardThemesDO;
import com.yolo.keyboard.dal.mysql.themes.KeyboardThemesMapper; import com.yolo.keyboard.dal.mysql.themes.KeyboardThemesMapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import com.yolo.keyboard.framework.common.pojo.PageResult; import com.yolo.keyboard.framework.common.pojo.PageResult;
import com.yolo.keyboard.framework.common.pojo.PageParam;
import com.yolo.keyboard.framework.common.util.object.BeanUtils; import com.yolo.keyboard.framework.common.util.object.BeanUtils;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.yolo.keyboard.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.yolo.keyboard.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yolo.keyboard.framework.common.util.collection.CollectionUtils.convertList;
import static com.yolo.keyboard.framework.common.util.collection.CollectionUtils.diffList;
import static com.yolo.keyboard.module.infra.enums.ErrorCodeConstants.THEMES_NOT_EXISTS; import static com.yolo.keyboard.module.infra.enums.ErrorCodeConstants.THEMES_NOT_EXISTS;
/** /**
@@ -31,15 +28,25 @@ import static com.yolo.keyboard.module.infra.enums.ErrorCodeConstants.THEMES_NOT
@Validated @Validated
public class KeyboardThemesServiceImpl implements KeyboardThemesService { public class KeyboardThemesServiceImpl implements KeyboardThemesService {
private static final String THEME_STYLE_KEY_PREFIX = "theme:style:";
private static final String THEME_STYLE_ALL_KEY = "theme:style:all";
private static final Long ALL_STYLE_ID = 9999L;
@Resource @Resource
private KeyboardThemesMapper themesMapper; private KeyboardThemesMapper themesMapper;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override @Override
public Long createThemes(KeyboardThemesSaveReqVO createReqVO) { public Long createThemes(KeyboardThemesSaveReqVO createReqVO) {
// 插入 // 插入
KeyboardThemesDO themes = BeanUtils.toBean(createReqVO, KeyboardThemesDO.class); KeyboardThemesDO themes = BeanUtils.toBean(createReqVO, KeyboardThemesDO.class);
themesMapper.insert(themes); themesMapper.insert(themes);
// 同步更新 Redis 缓存
refreshThemeStyleCache(themes.getThemeStyle());
// 返回 // 返回
return themes.getId(); return themes.getId();
} }
@@ -47,25 +54,57 @@ public class KeyboardThemesServiceImpl implements KeyboardThemesService {
@Override @Override
public void updateThemes(KeyboardThemesSaveReqVO updateReqVO) { public void updateThemes(KeyboardThemesSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
KeyboardThemesDO oldTheme = themesMapper.selectById(updateReqVO.getId());
validateThemesExists(updateReqVO.getId()); validateThemesExists(updateReqVO.getId());
// 更新 // 更新
KeyboardThemesDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardThemesDO.class); KeyboardThemesDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardThemesDO.class);
themesMapper.updateById(updateObj); themesMapper.updateById(updateObj);
// 同步更新 Redis 缓存(如果风格变更,需要刷新新旧两个风格的缓存)
refreshThemeStyleCache(updateReqVO.getThemeStyle());
if (oldTheme != null && oldTheme.getThemeStyle() != null
&& !oldTheme.getThemeStyle().equals(updateReqVO.getThemeStyle())) {
refreshThemeStyleCache(oldTheme.getThemeStyle());
}
} }
@Override @Override
public void deleteThemes(Long id) { public void deleteThemes(Long id) {
// 校验存在 // 校验存在
KeyboardThemesDO theme = themesMapper.selectById(id);
validateThemesExists(id); validateThemesExists(id);
// 删除 // 删除
themesMapper.deleteById(id); themesMapper.deleteById(id);
// 同步更新 Redis 缓存
if (theme != null && theme.getThemeStyle() != null) {
refreshThemeStyleCache(theme.getThemeStyle());
}
} }
@Override @Override
public void deleteThemesListByIds(List<Long> ids) { public void deleteThemesListByIds(List<Long> ids) {
// 获取要删除的主题列表,记录其风格
List<KeyboardThemesDO> themes = themesMapper.selectBatchIds(ids);
Set<Long> styleIds = new HashSet<>();
if (CollUtil.isNotEmpty(themes)) {
for (KeyboardThemesDO theme : themes) {
if (theme.getThemeStyle() != null) {
styleIds.add(theme.getThemeStyle());
}
}
}
// 删除 // 删除
themesMapper.deleteByIds(ids); themesMapper.deleteByIds(ids);
// 同步更新 Redis 缓存
for (Long styleId : styleIds) {
refreshThemeStyleCache(styleId);
} }
}
private void validateThemesExists(Long id) { private void validateThemesExists(Long id) {
@@ -84,4 +123,32 @@ public class KeyboardThemesServiceImpl implements KeyboardThemesService {
return themesMapper.selectPage(pageReqVO); return themesMapper.selectPage(pageReqVO);
} }
/**
* 刷新主题风格缓存
*
* @param styleId 风格ID
*/
private void refreshThemeStyleCache(Long styleId) {
if (styleId == null) {
return;
}
// 1. 刷新指定风格的缓存
String styleKey = THEME_STYLE_KEY_PREFIX + styleId;
List<KeyboardThemesDO> themesByStyle = themesMapper.selectList(KeyboardThemesDO::getThemeStyle, styleId);
if (CollUtil.isNotEmpty(themesByStyle)) {
redisTemplate.opsForValue().set(styleKey, themesByStyle);
} else {
redisTemplate.delete(styleKey);
}
// 2. 刷新全部主题缓存theme:style:all
List<KeyboardThemesDO> allThemes = themesMapper.selectList();
if (CollUtil.isNotEmpty(allThemes)) {
redisTemplate.opsForValue().set(THEME_STYLE_ALL_KEY, allThemes);
} else {
redisTemplate.delete(THEME_STYLE_ALL_KEY);
}
}
} }