Redis开发(二)

文章介绍了使用Spring-Boot进行Redis开发的两种方式:编程式缓存和声明式缓存。编程式缓存涉及RedisTemplate配置、序列化以及缓存操作步骤。声明式缓存通过注解简化了缓存管理,如@Cacheable、@CachePut和@CacheEvict。文章强调了两者在灵活性和开发效率上的区别,并建议根据项目需求选择合适的方式。
摘要由CSDN通过智能技术生成

我们使用java的spring-boot进行redis开发。

Redis开发分为两种:

(一)编程式缓存

        (1)导入Rdis依赖

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

        (2)在application.properties中进行文件配置

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)编写一个配置类

        配置RedisTemplate

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        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;
    }
}

(4)使用缓存的步骤

  1. 先查询缓存

  2. 如果查到直接返回

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

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

  5. 数据库查不到返回null

​
@Service
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements CarService {
    @Autowired
    private CarMapper carMapper;
    public static final String PREFIX="Car-";
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;


    //设置同步锁验证
    @Override
    public Car getCarById(Long id) {
        //获取字符串操作对象
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        //先查询Redis
        Car car = (Car)ops.get(PREFIX + id);
        if (car == null){
            synchronized (this){
                System.out.println("进入同步锁");
                //先查询Redis
                car = (Car)ops.get(PREFIX + id);
                //如果redis是存在的,就会直接返回
                if (car!=null){
                    System.out.println("redis查到了,返回"+car);
                    return car;
                }
                //如果redis没有查到数据,就查mysql
                car = carMapper.selectById(id);
                //mysql查到数据,保存到redis
                if (car!=null){
                    System.out.println("mysql查到,返"+car);
                    ops.set(PREFIX+id,car);
                    return car;
                }else {
                    //mysql没有数据
                    System.out.println("mysql没数据");
                    Car car1 = new Car();
                    //设置存在的期限
                    ops.set(PREFIX+id,car1,50, TimeUnit.SECONDS);
                }
                // mysql没有数据,返回null
                System.out.println("mysql没数据,返回null");
            }
        }else {
            System.out.println("没有执行同步锁");
        }


        return car;
    }
}

​

(5)最后在control层编写接口

@GetMapping("/car/{id}")
    public ResponseResult<Car> getStudentById(@PathVariable Long id){
        return ResponseResult.ok(carService.getCarById(id));
    }

(二)声明式缓存

编程式缓存使用复杂,代码侵入性高,推荐使用声明式缓存,通过注解来实现热点数据缓存。

 (1)在启动类上添加注解

//启动缓存
@EnableCaching

(2)redis配置类

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

 (3)缓存相关的注解

缓存相关注解
@CacheConfig 使用在Service类上,可以配置缓存名称,如: @CacheConfig(cacheNames = "car")

@Cacheable 使用在查询方法上,让方法优先查询缓存

@CachePut 使用在更新和添加方法上,数据库更新和插入数据后同时保存到缓存里

@CacheEvict 使用在删除方法上,数据库删除后同时删除缓存

Redis缓存汽车案例

​
    //查看分页
    @Cacheable(cacheNames = "Car-Page",key = "T(String).valueOf(#current)")
    @Override
    public Page<Car> getCarPage(Long current, Long size) {
        return carMapper.selectCar(new Page<>(current,size));
    }
    
​

组合注解@Cacing

//移除
    @Caching(
            evict = {
                    @CacheEvict(cacheNames = "Car",key = "T(String).valueOf(#id)"),
                    @CacheEvict(cacheNames = "Car-Page",allEntries = true)
            }
    )
    @Override
    public void removeCarById(Long id) {
        carMapper.deleteById(id);

    }
    //修改
    @Caching(
            put = @CachePut(cacheNames = "Car",key = "T(String).valueOf(#car.id)"),
            evict = @CacheEvict(cacheNames = "Car-Page",allEntries = true)

    )
    @Override
    public Car updateCarById(Car car) {
        carMapper.updateById(car);
        return car;
    }
    //添加
    @Caching(
            put = @CachePut(cacheNames = "Car",key = "T(String).valueOf(#car.id)"),
            evict = @CacheEvict(cacheNames = "Car-Page",allEntries = true)
    )
    @Override
    public Car addCarById(Car car) {
        carMapper.insert(car);
        return car;
    }

总结:

编程式缓存适用于复杂的缓存场景,需要更多的灵活性和控制;而声明式缓存适用于简单的缓存需求,可以更快速地实现缓存功能并减少开发工作量。在具体项目中选择缓存方式时,需要根据实际情况综合考虑缓存策略的复杂度、开发效率和维护成本等因素。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值