个人推荐Redis比较好的一种使用规范

本文介绍了在个人项目开发中如何通过合理的Rediskey命名规范和代码组织,提高缓存维护效率,包括使用统一的前缀、缓存类设计、接口实现等,并提供了代码实例。
摘要由CSDN通过智能技术生成

随着对个人项目的不断开发、迭代和重构,博主在这个过程中总结出了一套使用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) { }

}

好了,文章就分享到这里了,后续会持续优化文章内容,感谢大家的支持~

最后,如果看完这篇文章觉得对你有所帮助或者启发,不要忘了点赞+收藏哦~

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#中,有多个优秀的Redis操作类库可供选择。以下是几个受欢迎且适合C#的Redis操作类库: 1. StackExchange.Redis: StackExchange.Redis是一个高性能、功能丰富的Redis客户端库,由StackExchange团队开发和维护。它提供了全面的Redis功能支持,包括键值操作、事务、发布/订阅等。它也是Stack Overflow网站所使用Redis客户端库。 2. ServiceStack.Redis: ServiceStack.Redis是一个功能强大且易于使用Redis客户端库,它提供了简单而直观的API,使得与Redis的交互变得简单和高效。它支持大多数Redis功能,并提供了额外的有用功能,如连接池管理和高级数据结构。 3. DeveloperSharp.Redis: DeveloperSharp.Redis是一个轻量级的Redis客户端库,提供了简单、易用的API,适合快速入门和简单的Redis操作。它支持基本的键值操作、哈希表、列表、集合等功能。 这些Redis操作类库都具有良好的社区支持和广泛的用户群体。你可以根据自己的需求和偏好选择其中之一,并根据它们提供的文档和示例进行使用。 需要注意的是,无论选择哪个Redis操作类库,都需要确保在项目中正确安装并配置了Redis服务器。此外,还需要注意使用适当的连接池管理和错误处理机制,以确保与Redis的交互是稳定和可靠的。 希望这些推荐能帮助你找到适合C#的Redis操作类库。如果你有更多的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值