Redis基础

Redis是一个开源的内存数据库,提供高速的数据读写能力,支持多种数据类型如string、hash、list等,并具有原子性操作和事务处理功能。在Springboot中集成Redis可以实现高效的缓存机制,提高应用性能。
摘要由CSDN通过智能技术生成

Redis简介

Redis(Remote Dictionary Server )远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存也可持久化的日志型、Key-Value(NoSQL)数据库。

为什么使用Redis:

  1. 性能极高,基于内存,读的速度是110000次/s,写的速度是81000次/s

  2. 丰富的数据类型,支持string、hash、list、set及zset多种数据类型

  3. 原子性,所有操作都是原子性的,支持事务

  4. 丰富的特性,支持发布订阅、通知、过期策略等

  5. 支持持久化,可以将内存中的数据保存在磁盘中,重启后再次加载

  6. 支持分布式,理论上可以无限扩展

  7. 单线程,没有线程并发问题,Redis5.0后支持多线程

 Redis的数据类型

它主要提供了5种数据类型:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。Redis还提供了Bitmap、HyperLogLog、Geo类型,但这些类型都是基于上述核心数据类型实现的。5.0版本中,Redis新增加了Streams数据类型,它是一个功能强大的、支持多播的、可持久化的消息队列。

1. string可以存储字符串、数字和二进制数据,除了值可以是String以外,所有的键也可以是string,string最大可以存储大小为512M的数据。

2. list保证数据线性有序且元素可重复,它支持lpush、blpush、rpop、brpop等操作,可以当作简单的消息队列使用,一个list最多可以存储2^32-1个元素。

3. hash的值本身也是一个键值对结构,最多能存储2^32-1个元素。

4. set是无序不可重复的,它支持多个set求交集、并集、差集,适合实现共同关注之类的需求,一个set最多可以存储2^32-1个元素。

5. zset是有序不可重复的,它通过给每个元素设置一个分数来作为排序的依据,一个zset最多可以存储2^32-1个元素。
 

事务 

Redis提供的事务是将多个命令打包,然后一次性、按照先进先出的顺序(FIFO)有序的执行。在执行过程中不会被打断(在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中),当事务队列中的所以命令都被执行(无论成功还是失败)完毕之后,事务才会结束。  

  • multi 启动事务

  • exec 提交事务

  • discard 放弃事务

  • watch 监视一个或多个键,如果有其他客户端修改键的值,事务将失败

Springboot集成Redis 

redis读取数据的流程:

  1. 先查询缓存

  2. 如果查到直接返回

  3. 如果查不到,查询数据库

  4. 数据库查到,保存缓存中

  5. 数据库查不到返回null

 集成步骤:

1、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

 2、配置文件

# 主机
spring.redis.host=localhost
# 端口
spring.redis.port=6379
# 数据库
spring.redis.database=0
# 最大连接数
spring.redis.jedis.pool.max-active=100
# 最大闲置时间
spring.redis.jedis.pool.max-wait=100ms
# 最大闲置数
spring.redis.jedis.pool.max-idle=100
# 最小闲置数
spring.redis.jedis.pool.min-idle=10

3、配置类

编程式

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //创建redis的操作对象
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //指定连接工厂
        template.setConnectionFactory(factory);
        // 配置序列化器
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson序列化器
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

   
}

声明式

/**
 * Redis配置
 */
@Configuration
@EnableCaching
public class RedisConfig {

    /**
     * 声明式缓存的配置
     * @return
     */
    @Bean
    public RedisCacheConfiguration provideRedisCacheConfiguration(){
        //加载默认配置
        RedisCacheConfiguration conf = RedisCacheConfiguration.defaultCacheConfig();
        //返回Jackson序列化器
        return conf.serializeValuesWith(
                RedisSerializationContext.SerializationPair
                        .fromSerializer(new GenericJackson2JsonRedisSerializer()));
    }
}

 4、主要实现

 编程式:

public Food getFoodById(Long id) {
        //获得字符串操作对象
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        //先查询redis
        Food food = (Food) ops.get(PREFIX + id);
        //如果redis缓存存在,就返回数据
        if (food != null){
            System.out.println("Redis查到,返回" + food);
            return food;
        }
        //如果redis没有查到,就查数据库
        food = foodMapper.selectById(id);
        //数据库查到数据,就保存到redis
        if (food != null){
            System.out.println("mysql查到,返回" + food);
            ops.set(PREFIX + id,food);
            return food;
        }
        //mysql没有查到数据,就返回null
        return null;
    }

声明式:

@Cacheable(cacheNames = "Food",key = "T(String).valueOf(#id)")
    @Override
    public Food getFoodById(Long id) {
        return foodMapper.selectById(id);
    }

    /**
     * 删除数据同时删除分页缓存
     * @param id
     */
    @Caching(evict = {@CacheEvict(cacheNames = "Food",key = "T(String).valueOf(#id)"),
            @CacheEvict(cacheNames = "food-page",allEntries = true)})
    @Override
    public void removeFoodById(Long id) {
        foodMapper.deleteById(id);
    }


    /**
     * 更新数据,同时删除分页缓存
     * @param food
     * @return
     */
    @Caching(put = @CachePut(cacheNames = "Food",key = "T(String).valueOf(#food.id)"),
            evict = @CacheEvict(cacheNames = "food-page",allEntries = true))
    @Override
    public Food updateFoodById(Food food) {
        foodMapper.updateById(food);
        return food;
    }

    /**
     * 添加数据,同时删除分页缓存
     * @param food
     * @return
     */
    @Caching(put = @CachePut(cacheNames = "Food",key = "T(String).valueOf(#food.id)"),
            evict = @CacheEvict(cacheNames = "food-page",allEntries = true))
    @Override
    public Food addFood(Food food) {
        foodMapper.insert(food);
        return food;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值