Spring Boot 整合redis的两种方式

引入spring-data-redis启动器,屏蔽lettuce客户端;

为了在springboot中使用redis,首先要添加redis启动器;
这里我们使用jedis,需要在pom.xml中屏蔽自带的lettuce;
关于lettuce、jedis的差别见 Redis的三个框架:Jedis,Redisson,Lettuce

    <!--redis集成-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <!--排除lettuce-->
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <!--使用jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

配置redis服务器地址

application.yml中配置redis服务器地址

spring:
#....省略其他配置....
  redis:
    #这里不填写的话默认是 localhost和 6379
    host: 127.0.0.1
    port: 6379
    password: root



注解方式使用

基于注解方式使用redis,操作方便,适合简单的redis应用;

1、在主程序开启注解

application.java主程序开启注解@EnableCaching

@SpringBootApplication
@MapperScan("com.example.test.dao")
@EnableTransactionManagement
@EnableCaching  //开启redis缓存
public class Application extends SpringBootServletInitializer {
		//以下省略
2、在服务层使用注解

我们常用的注解是@Cacheable和 @CacheEvict,前者新增缓存,后者删除缓存;

@Cacheable

当redis缓存中没有对应的数据时,向数据库查询,并将查询结果新增到redis缓存;

@CacheEvict

此方法执行后,删除对应的redis缓存;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private SysuserMapper mapper;
    
    @Cacheable(cacheNames = "Sysuserinfo",key = "#uid",unless = "#result==null")
    @Override
    public Sysuser select(Integer uid){
        Sysuser user= mapper.selectByPrimaryKey(uid);
        return user;
    }

    @CacheEvict(cacheNames = "Sysuserinfo",key = "#uid")
    @Override
    public boolean delete(Integer uid){
        int resul=mapper.deleteByPrimaryKey(uid);
        return resul>0;
    }
}
cacheNames 和 key

cacheNames 和 key 组成一个索引,指向一个值;
在这里插入图片描述
这里@Cacheable、@CacheEvict注解的cacheNames 和 key 两个属性相同,所以操作的是redis数据库中的同一条数据;

unless属性

当满足此条件时,不执行本次缓存操作;

unless = "#result==null"

体现在这里就是:当查询到的结果为null时,不执行此次缓存操作;




Template模板方式使用

注解方式生成的redis缓存,是以默认模板存储的,无法被阅读,也和一些其他工具不兼容;
在这里插入图片描述
使用模板方式,可是设置缓存的格式;

1、创建一个redis设置类

创建redisConfig.java ,设置key和value的序列化方式;

@Configuration
public class RedisConfig {
	//这种方式bean name固定是这个
    @Bean(name = "redisTemplate")
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> template=new RedisTemplate<>();
        //设置序列化方式
        template.setKeySerializer(new StringRedisSerializer());		//key设置string序列化方式
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());	//value设置json序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        //这一步是redis基本配置 包括前面设置端口和ip
        template.setConnectionFactory(factory);
        return template;
    }
}

redisSerializer的实现类:
在这里插入图片描述

在接口上按ctrl+H可以查看所有实现类

2、使用template

和使用jedis差不多,先从缓存数据库中取,缓存穿透再去数据库取;
在删除和修改时,则是根据key删除对应的缓存;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    protected SysuserMapper mapper;
    @Autowired
    private RedisTemplate<String,Object> template;	

    @Override
    public Sysuser get(Integer uid){	//方法:查询用户
        Sysuser user= null;
        ValueOperations<String,Object> operations=template.opsForValue();
        Object object=operations.get(""+uid);	//先尝试从缓存中取
        if(object==null){
            user=mapper.selectByPrimaryKey(uid);	//缓存穿透 再去数据库取
            operations.set(""+uid,user);	//并存到缓存数据库中
        }else {
            user=(Sysuser)object;
        }
        return user;
    }

    @Override
    public boolean update(Integer uid,String uname){	//方法:更新用户名
        Sysuser sysuser=new Sysuser();
        sysuser.setUid(uid);
        sysuser.setUname(uname);
        int result=mapper.updateByPrimaryKey(sysuser);
        if(result>0){
            template.delete(""+uid);	//删除缓存
            return true;
        }
        return false;
    }
}

可以看到,更改序列化方式后,数据格式和之前不同了:
在这里插入图片描述

这里使用到的opsForValue是用来处理字符串的;

ValueOperations<String,Object> operations=template.opsForValue();

另外还有opsForHash、opsForList、opsForSet、opsForZset来操作其他类型的数据;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值