​Redis hash​实际应用

本文介绍了Redis,一个高性能的Key-Value数据库,特别强调了Redis的Hash数据类型和其在存储对象时的内存优化。文章展示了如何在Java中配置RedisTemplate以实现对象的序列化,并提供了示例代码展示如何使用Redis进行缓存操作,包括设置过期时间和删除操作。此外,讨论了使用Redis作为缓存的好处,如速度、数据类型丰富和事务支持。
摘要由CSDN通过智能技术生成

redis全称:REmote DIctionary Server,是可支持网络、可基于内存亦可持久化的日志型、Key-Value高性能数据库,并提供多种语言的API,它通常被称为数据结构服务器。

  • Redis hash是一个键值对集合,一个键对应多个值对[field,value]
  • 也就是key-field+value形式,可以理解成java的map< string,map<string,string>> ,三个string依次对应key、field、value。

 

Redis hash是一个string类型的field和value的映射表,适合于存储对象
例如,在key名为SERIAL_TASK的情况下:

 


先配置redis的配置类

package com.cascade.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;



@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        // Json 配置序列化
        // 使用 jackson 解析任意的对象
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 使用 objectMapper 进行转义
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key 采用 String 的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // Hash 的 key 采用 String 的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value 采用 jackson 的序列化方式
        template.setValueSerializer(stringRedisSerializer);
        // Hash 的 value 采用 jackson 的序列化方式
        template.setHashValueSerializer(stringRedisSerializer);
        // 把所有的配置 set 进 template
        template.afterPropertiesSet();

        return template;


    }

    @Bean
    public HashOperations<String, String, String> hashOperations(RedisTemplate<String, String> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    @Bean
    public RedisSerializer<String> redisSerializer(RedisTemplate<String, String> redisTemplate) {
        return redisTemplate.getStringSerializer();
    }

}


使用 Redis 有哪些好处?

  • 速度快,因为数据存在内存中,类似于 HashMap ,HashMap 的优势就是查找和操作的时间复杂度是O(1)

  • 支持丰富的数据类型,支持:String、list、set、sortedset、hash

  • 支持事务,操作的原子性,所谓的原子性就是对数据的更改要么全部执行,要么不执行

  • 丰富的特性,可用于缓存,消息,按 key 设置过期时间,过期后会自动删除 

java代码引用


@Service
@Slf4j
public class RedisCacheFetchStrategy implements CacheFetchStrategy {
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private RedisSerializer<String> redisSerializer;
    @Resource
    private HashOperations<String, String, String> hashOperations;
    /**
     * 分割
     */
    String PARTING = "@";

    /**
     *
     * @param hashkey
     * @param sysUser
     * @param hashName
     */
    @Override
    public void fetchSysUser(String hashkey, SysUser sysUser, String hashName) {

      
        Map<byte[], byte[]> map = new HashMap<>();
        String hashValue = String.valueOf(sysUser.getId()).concat(PARTING).concat(sysUser.getName())
                .concat(PARTING).concat(StringUtils.isEmpty(sysUser.getProvince()) ? "":sysUser.getProvince());
        map.put(redisSerializer.serialize(hashkey), redisSerializer.serialize(hashValue));
        log.info("开始缓存添加,hashName=>{}, hashkey=>{}, hashvalue=>{}", hashName, hashkey, hashValue);
        this.redisTemplate.executePipelined((RedisCallback<Void>) redisConnection -> {
            RedisHashCommands redisHashCommands = redisConnection.hashCommands();
            //redis所在的key
            byte[] serialize = redisSerializer.serialize(hashName);
            if (serialize != null) {
                redisHashCommands.hMSet(serialize, map);
            }
            return null;
        });
        
        log.info("开始设置过期时间,时间{},单位{}=>",24,TimeUnit.HOURS);
        this.redisTemplate.expire(hashName,24, TimeUnit.HOURS);
        
        log.info("获取hashkey 中fieId数据");
        String message = hashOperations.get(InsideStationMessage.FILE_AUDIT_TASK, hashkey);
        log.info("删除某个hashkey");
        hashOperations.delete(InsideStationMessage.FILE_AUDIT_TASK, hashkey);

        log.info("直接销毁hash");
        this.redisTemplate.unlink(hashName);
    }

使用hash 省内存。

在hash类型中,一个key可以对应多个多个field,一个field对应一个value。

将一个对象存储为hash类型的好处:

  • 较于每个字段都单独存储成string类型来说,更能节约内存;

  • 将具有同一类规则的数据放到redis中的一个数据容器里,防止数据上不同规则的key值上的相斥,便于查找数据。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖中的阿龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值