随着对个人项目的不断开发、迭代和重构,博主在这个过程中总结出了一套使用redis的较好的规范。主要包含Redis的key命名规范和Redis代码规范。
主要内容
主要包含以下几个内容:
- 同一应用的key在最前面添加统一的前缀,如应用名;
- 案例:appName:业务相关的key前缀:具有代表性的字段的值
- 例如:mhxysy:SEVER:1
- 所有key的前缀,根据业务功能,以常量的形式保存在同一个接口中;
- 一个业务的Redis缓存对应一个缓存类,使代码易于维护,把缓存的代码统一编写在一个类里,如果想要取消缓存,只需要修改这个缓存类的代码即可。缓存类可以根据自己的喜好来命名,如XxxRepository;
- 为了体现面向接口的开发原则,可以让所有Reids得缓存类实现一个代表Reids缓存的顶级接口,如RedisRepository;
代码展示
角色信息的缓存类RoleAccountRepository.java
package cn.edu.sgu.www.mhxysy.redis.repository.impl;
import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixes;
import cn.edu.sgu.www.mhxysy.entity.role.RoleAccount;
import cn.edu.sgu.www.mhxysy.redis.RedisUtils;
import cn.edu.sgu.www.mhxysy.redis.repository.RedisRepository;
import cn.edu.sgu.www.mhxysy.util.TimerUtils;
import cn.edu.sgu.www.mhxysy.vo.role.RoleAccountVO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* @author heyunlin
* @version 1.0
*/
@Slf4j
@Component
public class RoleAccountRepository implements RedisRepository {
private final RedisUtils redisUtils;
public RoleAccountRepository(RedisUtils redisUtils) {
this.redisUtils = redisUtils;
}
@Override
public void put(String id, Object value) {
String key = RedisKeyPrefixes.PREFIX_ROLE_ACCOUNT + id;
redisUtils.set(key, JSON.toJSONString(value));
redisUtils.expire(key, 7, TimeUnit.DAYS);
}
@Override
public RoleAccount get(String id) {
String key = RedisKeyPrefixes.PREFIX_ROLE_ACCOUNT + id;
String value = redisUtils.get(key);
if (value != null) {
log.debug("命中缓存{}", key);
}
return JSON.parseObject(value, RoleAccount.class);
}
@Override
public void putList(Object value) {
String key = RedisKeyPrefixes.PREFIX_ROLE_ACCOUNTS;
redisUtils.set(key, JSON.toJSONString(value), 7, TimeUnit.DAYS);
}
@Override
public List<RoleAccount> getList() {
String key = RedisKeyPrefixes.PREFIX_ROLE_ACCOUNTS;
String value = redisUtils.get(key);
if (value != null) {
log.debug("命中缓存{}", key);
return JSON.parseArray(value, RoleAccount.class);
}
return null;
}
@Override
public void delete() {
String key = RedisKeyPrefixes.PREFIX_ROLE_ACCOUNTS;
redisUtils.delete(key);
}
@Override
public void delete(String primaryKey) {
redisUtils.delete(RedisKeyPrefixes.PREFIX_ROLE_ACCOUNT + primaryKey);
}
@Override
public void delayDoubleDelete(String primaryKey, Consumer<String> consumer) {
delete();
delete(primaryKey);
deleteCache(primaryKey);
consumer.accept(primaryKey);
// 延时双删
TimerUtils.schedule(new TimerTask() {
@Override
public void run() {
delete();
delete(primaryKey);
deleteCache(primaryKey);
}
});
}
public void cacheRole(String roleId, RoleAccountVO roleAccountVO) {
String key = RedisKeyPrefixes.PREFIX_ROLE_DETAIL + roleId;
redisUtils.set(key, JSON.toJSONString(roleAccountVO));
}
public RoleAccountVO getCache(String roleId) {
String key = RedisKeyPrefixes.PREFIX_ROLE_DETAIL + roleId;
String value = redisUtils.get(key);
if (value != null) {
log.debug("命中缓存{}...", key);
return JSON.parseObject(value, RoleAccountVO.class);
}
return null;
}
public void deleteCache(String roleId) {
String key = RedisKeyPrefixes.PREFIX_ROLE_DETAIL + roleId;
redisUtils.delete(key);
}
}
具体的角色service层方法
package cn.edu.sgu.www.mhxysy.service.role.impl;
import cn.edu.sgu.www.mhxysy.base.Pager;
import cn.edu.sgu.www.mhxysy.dto.role.RoleAccountDTO;
import cn.edu.sgu.www.mhxysy.easyexel.impl.RoleAccountExcelData;
import cn.edu.sgu.www.mhxysy.entity.gang.Gang;
import cn.edu.sgu.www.mhxysy.entity.role.Account;
import cn.edu.sgu.www.mhxysy.entity.role.RoleAccount;
import cn.edu.sgu.www.mhxysy.entity.role.RoleModeling;
import cn.edu.sgu.www.mhxysy.entity.school.School;
import cn.edu.sgu.www.mhxysy.entity.server.Server;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.role.JiadianSchemaMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleAccountMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleAttributeMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleJiadianMapper;
import cn.edu.sgu.www.mhxysy.mapper.school.SchoolSkillCategoryMapper;
import cn.edu.sgu.www.mhxysy.mapper.school.SchoolSkillMapper;
import cn.edu.sgu.www.mhxysy.redis.repository.impl.RoleAccountRepository;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.gang.GangService;
import cn.edu.sgu.www.mhxysy.service.role.AccountService;
import cn.edu.sgu.www.mhxysy.service.role.RoleAccountService;
import cn.edu.sgu.www.mhxysy.service.role.RoleModelingService;
import cn.edu.sgu.www.mhxysy.service.school.SchoolService;
import cn.edu.sgu.www.mhxysy.service.server.ServerService;
import cn.edu.sgu.www.mhxysy.vo.role.RoleAccountVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
/**
* @author heyunlin
* @version 1.0
*/
@Service
public class RoleAccountServiceImpl implements RoleAccountService {
private final RoleAccountMapper roleAccountMapper;
private final RoleJiadianMapper roleJiadianMapper;
private final SchoolSkillMapper schoolSkillMapper;
private final JiadianSchemaMapper jiadianSchemaMapper;
private final RoleAttributeMapper roleAttributeMapper;
private final RoleAccountRepository roleAccountRepository;
private final SchoolSkillCategoryMapper schoolSkillCategoryMapper;
private final GangService gangService;
private final ServerService serverService;
private final SchoolService schoolService;
private final AccountService accountService;
private final RoleModelingService roleModelingService;
@Autowired
public RoleAccountServiceImpl(
RoleAccountMapper roleAccountMapper,
RoleJiadianMapper roleJiadianMapper,
SchoolSkillMapper schoolSkillMapper,
JiadianSchemaMapper jiadianSchemaMapper,
RoleAttributeMapper roleAttributeMapper,
RoleAccountRepository roleAccountRepository,
SchoolSkillCategoryMapper schoolSkillCategoryMapper,
GangService gangService,
ServerService serverService,
SchoolService schoolService,
AccountService accountService,
RoleModelingService roleModelingService) {
this.roleAccountMapper = roleAccountMapper;
this.roleJiadianMapper = roleJiadianMapper;
this.schoolSkillMapper = schoolSkillMapper;
this.jiadianSchemaMapper = jiadianSchemaMapper;
this.roleAttributeMapper = roleAttributeMapper;
this.roleAccountRepository = roleAccountRepository;
this.schoolSkillCategoryMapper = schoolSkillCategoryMapper;
this.gangService = gangService;
this.serverService = serverService;
this.schoolService = schoolService;
this.accountService = accountService;
this.roleModelingService = roleModelingService;
}
@Override
public RoleAccount selectById(String roleId) {
RoleAccount roleAccount = roleAccountRepository.get(roleId);
if (roleAccount == null) {
roleAccount = roleAccountMapper.selectById(roleId);
roleAccountRepository.put(roleId, roleAccount);
}
return roleAccount;
}
}
Redis的key前缀常量接口代码展示
package cn.edu.sgu.www.mhxysy.consts;
/**
* redis的key前缀的常量接口
* @author heyunlin
* @version 1.0
*/
public interface RedisKeyPrefixes {
String PREFIX_BASE = "mhxysy:";
/**
* 用户的邮箱
*/
String PREFIX_EMAIL = PREFIX_BASE + "EMAIL:";
/**
* 用户登录的验证码
*/
String PREFIX_CAPTCHA = PREFIX_BASE + "CAPTCHA:";
/**
* 用户的侧栏菜单
*/
String PREFIX_USER_LEFT_MENUS = PREFIX_BASE + "USER_LEFT_MENUS:";
/**
* 角色的菜单树
*/
String PREFIX_ROLE_MENU_TREE = PREFIX_BASE + "ROLE_MENU_TREE:";
/**
* 用户登录的次数
*/
String PREFIX_USER_LOGIN_TIMES = PREFIX_BASE + "USER_LOGIN_TIMES:";
/**
* shiro缓存认证管理
*/
String PREFIX_CACHE_MANAGER = PREFIX_BASE + "AUTHORIZATION:CACHE_MANAGER:";
/**
* 角色高级属性
*/
String PREFIX_ADVANCED_PROPERTY = PREFIX_BASE + "ROLE_GJSX:";
/**
* 角色详情
*/
String PREFIX_ROLE_DETAIL = PREFIX_BASE + "ROLE_DETAIL:";
/**
* 角色
*/
String PREFIX_ROLE_ACCOUNT = PREFIX_BASE + "ROLE_ACCOUNT:";
/**
* 角色列表
*/
String PREFIX_ROLE_ACCOUNTS = PREFIX_BASE + "ROLE_ACCOUNTS:";
/**
* 角色造型
*/
String PREFIX_ROLE_MODELING = PREFIX_BASE + "ROLE_MODELING:";
/**
* 角色造型列表
*/
String PREFIX_ROLE_MODELINGS = PREFIX_BASE + "ROLE_MODELINGS";
/**
* 帮派
*/
String PREFIX_GANG = PREFIX_BASE + "GANG:";
/**
* 帮派列表
*/
String PREFIX_GANGS = PREFIX_BASE + "GANGS";
/**
* 帮派职务
*/
String PREFIX_GANG_JOB = PREFIX_BASE + "GANG_JOB:";
/**
* 帮派职务列表
*/
String PREFIX_GANG_JOBS = PREFIX_BASE + "GANG_JOBS";
/**
* 门派
*/
String PREFIX_SCHOOL = PREFIX_BASE + "SCHOOL:";
/**
* 门派列表
*/
String PREFIX_SCHOOLS = PREFIX_BASE + "SCHOOLS";
/**
* 宠物
*/
String PREFIX_CHONGWU = PREFIX_BASE + "CHONGWU:";
/**
* 宠物列表
*/
String PREFIX_CHONGWUS = PREFIX_BASE + "CHONGWUS";
/**
* 宠物类型
*/
String PREFIX_CHONGWU_CATEGORY = PREFIX_BASE + "CHONGWU_CATEGORY:";
/**
* 宠物类型列表
*/
String PREFIX_CHONGWU_CATEGORIES = PREFIX_BASE + "CHONGWU_CATEGORIES";
/**
* 大区
*/
String PREFIX_AREA = PREFIX_BASE + "AREA:";
/**
* 大区列表
*/
String PREFIX_AREAS = PREFIX_BASE + "AREAS";
/**
* 服务器
*/
String PREFIX_SERVER = PREFIX_BASE + "SERVER:";
/**
* 服务器列表
*/
String PREFIX_SERVERS = PREFIX_BASE + "SERVERS";
/**
* 账号
*/
String PREFIX_ACCOUNT = PREFIX_BASE + "ACCOUNT:";
/**
* 账号列表
*/
String PREFIX_ACCOUNTS = PREFIX_BASE + "ACCOUNTS";
}
Redis缓存顶级接口
package cn.edu.sgu.www.mhxysy.redis.repository;
import java.util.function.Consumer;
/**
* redis仓库的顶级接口:为了满足开闭原则设计了此接口
* @author heyunlin
* @version 1.0
*/
public interface RedisRepository {
void put(String key, Object value);
Object get(String key);
void putList(Object value);
Object getList();
/**
* 删除数据缓存
*/
void delete();
/**
* 删除指定ID的数据缓存
* @param primaryKey 数据的ID
*/
void delete(String primaryKey);
/**
* 延时双删
* @param primaryKey 数据的ID
* @param consumer Consumer<String>
*/
default void delayDoubleDelete(String primaryKey, Consumer<String> consumer) { }
}
好了,文章就分享到这里了,后续会持续优化文章内容,感谢大家的支持~
最后,如果看完这篇文章觉得对你有所帮助或者启发,不要忘了点赞+收藏哦~