SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate

 更新时间:2022年12月13日 14:16:49   作者:秦 羽  
Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致。本文介绍了SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate的方法,需要的可以参考一下

Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

注意:

使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口

springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。

jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式

lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式

1.环境准备

1.1.引入依赖

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

1.2.配置application.propertie

# springboot所有的配置类都有一个自动配置类, xxxAutoConfiguration
# 自动配置类都会绑定一个properties 的配置文件,xxxProperties
​​​​​​​
spring.redis.host=127.0.0.1   #localhost
spring.redis.port=6379
spring.redis.database=0

源码分析:

@Bean
@ConditionalOnMissingBean(name = "redisTemplate") 
// 可以自己定义一个redisTemplate来替换这个默认的!
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
    throws UnknownHostException {
    // 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
    // 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 <String, Object>
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

@Bean
@ConditionalOnMissingBean 
//由于String是redis中最常使用的类型,所以单独提一个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
    throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

1.3. 连接测试

可以看一下第二节

redisTemplate 操作不同的数据类型,api和我们的指令是一样的

opsForValue 操作字符串 类似String

opsForList 操作List 类似List

  • opsForSet
  • opsForHash
  • opsForZSet
  • opsForGeo
  • opsForHyperLogLog

除了进本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的CRUD

获取redis的连接对象

RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
connection.flushAll();

2.使用StringRedisTemplate和RedisTemplate

	@Autowired
    private StringRedisTemplate stringRedisTemplate;  //对字符串支持比较友好,不能存储对象
    @Autowired
    private RedisTemplate redisTemplate;  //存储对象

    @Test
    public void testRedisTemplate(){
        System.out.println(redisTemplate);
        //设置redistemplate值使用对象序列化策略
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());//指定值使用对象序列化
        //redisTemplate.opsForValue().set("user",new User("1","qinyu",99,new Date()));
        User user = (User) redisTemplate.opsForValue().get("user");
        System.out.println(user);
        //Set keys = redisTemplate.keys("*");
        //keys.forEach(key -> System.out.println(key));
        /*Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);*/

        //Object qinyu= redisTemplate.opsForValue().get("qinyu");
        //System.out.println(qinyu);
        /*redisTemplate.opsForValue().set("name","xxxx");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);*/
        /*redisTemplate.opsForList().leftPushAll("lists","xxxx","1111");
        List lists = redisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(list-> System.out.println(list));*/
    }


    /*key的绑定操作 如果日后对某一个key的操作及其频繁,可以将这个key绑定到对应redistemplate中,日后基于绑定操作都是操作这个key
      boundValueOps 用来对String值绑定key
      boundListOps 用来对List值绑定key
      boundSetOps 用来对Set值绑定key
      boundZsetOps 用来对Zset值绑定key
      boundHashOps 用来对Hash值绑定key
    */

    @Test
    public void testBoundKey(){
        BoundValueOperations<String, String> nameValueOperations = stringRedisTemplate.boundValueOps("name");
        nameValueOperations.set("1");
        //yuew
        nameValueOperations.set("2");
        String s = nameValueOperations.get();
        System.out.println(s);

    }


    //hash相关操作 opsForHash
    @Test
    public void testHash(){
        stringRedisTemplate.opsForHash().put("maps","name","qinyu");
        Object o = stringRedisTemplate.opsForHash().get("maps", "name");
        System.out.println(o);
    }

    //zset相关操作 opsForZSet
    @Test
    public void testZSet(){
        stringRedisTemplate.opsForZSet().add("zsets","qinyu",10);
        Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1);
        zsets.forEach(value-> System.out.println(value));
    }

    //set相关操作 opsForSet
    @Test
    public void testSet(){
        stringRedisTemplate.opsForSet().add("sets","xiaosan","xiaosi","xiaowu");
        Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
        sets.forEach(value-> System.out.println(value));
    }

    //list相关的操作opsForList
    @Test
    public void testList(){
        // stringRedisTemplate.opsForList().leftPushAll("lists","张三","李四","王五");
        List<String> lists = stringRedisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(key -> System.out.println(key));
    }


    //String相关的操作 opsForValue
    @Test
    public void testString(){
        //stringRedisTemplate.opsForValue().set("166","好同学");
        String s = stringRedisTemplate.opsForValue().get("166");
        System.out.println(s);
        Long size = stringRedisTemplate.opsForValue().size("166");
        System.out.println(size);
    }


    //key相关的操作
    @Test
    public void test(){
        Set<String> keys = stringRedisTemplate.keys("*");//查看所有key
        Boolean name = stringRedisTemplate.hasKey("name");//判断某个key是否存在
        stringRedisTemplate.delete("age");//根据指定key删除
        stringRedisTemplate.rename("","");//修改key的名称
        stringRedisTemplate.expire("key",10, TimeUnit.HOURS);
      	//设置key超时时间 参数1:设置key名 参数2:时间 参数3:时间的单位
        stringRedisTemplate.move("",1);//移动key
    }

3.自定义RedisTemplate

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    // 自己定义一个 RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 我们为了自己开发方便,一般直接使用 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String,Object>();
        template.setConnectionFactory(factory);
        // Json序列化配置
        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);
        // String 的序列化
        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.配置文件

启动的时候,就通过配置文件来启动!

单位 容量单位不区分大小写,G和GB有区别

1.配置文件 unit单位 对大小写不敏感!

2.包含 可以使用 include 组合多个配置问题

例如:include /path/to/local.conf

3.网络

bind 127.0.0.1 # 绑定的ip
protected-mode yes # 保护模式
port 6379 # 端口设置

4.通用 GENERAL

daemonize yes # 以守护进程的方式运行(就是后台运行),默认是 no,我们需要自己开启为yes!
pidfile /var/run/redis_6379.pid # 如果以后台的方式运行,我们就需要指定一个 pid 文件!
# 日志
# Specify the server verbosity level.
# This can be one of:
redis 是内存数据库,如果没有持久化,那么数据断电及失!
REPLICATION 复制,我们后面讲解主从复制的,时候再进行讲解
SECURITY 安全
可以在这里设置redis的密码,默认是没有密码!
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 生产环境
# warning (only very important / critical messages are logged)
loglevel notice
logfile "" # 日志的文件位置名
databases 16 # 数据库的数量,默认是 16 个数据库
always-show-logo yes # 是否总是显示LOGO

5.快照

持久化, 在规定的时间内,执行了多少次操作,则会持久化到文件 .rdb. aof

redis 是内存数据库,如果没有持久化,那么数据断电及失!

# 如果900s内,如果至少有一个1 key进行了修改,我们及进行持久化操作
save 900 1
# 如果300s内,如果至少10 key进行了修改,我们及进行持久化操作
save 300 10
# 如果60s内,如果至少10000 key进行了修改,我们及进行持久化操作
save 60 10000
# 之后学习持久化,会自己定义这个测试!
stop-writes-on-bgsave-error yes # 持久化如果出错,是否还需要继续工作! 默认保存出错的话停止操作
rdbcompression yes # 是否压缩 rdb 文件,需要消耗一些cpu资源!
rdbchecksum yes # 保存rdb文件的时候,进行错误的检查校验!
dir ./ # rdb 文件保存的目录!

6.SECURITY 安全

可以在这里设置redis的密码,默认是没有密码!

127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get requirepass # 获取redis的密码
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass "123456" # 设置redis的密码
OK
127.0.0.1:6379> config get requirepass # 发现所有的命令都没有权限了
(error) NOAUTH Authentication required.
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456 # 使用密码进行登录!
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456"

7.限制 CLIENTS

maxclients 10000 # 设置能连接上redis的最大客户端的数量
maxmemory <bytes> # redis 配置最大的内存容量
maxmemory-policy noeviction # 内存到达上限之后的处理策略
 # redis 中的默认的过期策略是 volatile-lru 。
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误
------------------------------------------------
# 设置方式
config set maxmemory-policy volatile-lru 

8.APPEND ONLY 模式 aof配置

appendonly no # 默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有的情况下,
rdb完全够用!
appendfilename "appendonly.aof" # 持久化的文件的名字
# appendfsync always # 每次修改都会 sync。消耗性能
appendfsync everysec # 每秒执行一次 sync,可能会丢失这1s的数据!
# appendfsync no # 不执行 sync,这个时候操作系统自己同步数据,速度最快!

9.bgsave

bgsave 是异步进行,进行持久化的时候,redis 还可以将继续响应客户端请求 ;

bgsave和save对比

命令savebgsave
IO类型同步异步
阻塞?是(阻塞发生在fock(),通常非常快)
复杂度O(n)O(n)
优点不会消耗额外的内存不阻塞客户端命令
缺点阻塞客户端命令需要fock子进程,消耗内存

5.自定义工具类

可以参考下面的链接

SpringBoot整合Redis及Redis工具类撰写实例

到此这篇关于SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate的文章就介绍到这了,更多相关SpringBoot整合Redis内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 学习C语言对后期java有帮助吗

    学习C语言对后期java有帮助吗

    在本篇文章里小编给大家整理的是一篇关于学习C语言对后期java有帮助吗的基础文章,有兴趣的朋友们可以参考下。
    2020-11-11
  • java整数(秒数)转换为时分秒格式的示例

    java整数(秒数)转换为时分秒格式的示例

    这篇文章主要介绍了java整数(秒数)转换为时分秒格式的示例,需要的朋友可以参考下
    2014-04-04
  • 解析SpringSecurity自定义登录验证成功与失败的结果处理问题

    解析SpringSecurity自定义登录验证成功与失败的结果处理问题

    这篇文章主要介绍了SpringSecurity系列之自定义登录验证成功与失败的结果处理问题,本文通过实例给大家讲解的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • 详解SpringBoot实现ApplicationEvent事件的监听与发布

    详解SpringBoot实现ApplicationEvent事件的监听与发布

    这篇文章主要为大家详细介绍了SpringBoot如何实现ApplicationEvent事件的监听与发布,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • 简单了解Spring中的事务控制

    简单了解Spring中的事务控制

    这篇文章主要介绍了简单了解Spring中的事务控制,事务是一组操作的执行单元,下面我们来简单学习一下吧
    2019-05-05
  • Java实现的微信公众号获取微信用户信息示例

    Java实现的微信公众号获取微信用户信息示例

    这篇文章主要介绍了Java实现的微信公众号获取微信用户信息,结合实例形式分析了Java微信公众号获取微信用户信息相关原理、步骤与操作注意事项,需要的朋友可以参考下
    2019-10-10
  • Java数据结构篇之实现二叉搜索树的核心方法

    Java数据结构篇之实现二叉搜索树的核心方法

    二叉搜索树是一种常用的数据结构,它是一棵二叉树,且每个节点的值都大于其左子树中任何节点的值,而小于其右子树中任何节点的值,这篇文章主要给大家介绍了关于Java数据结构篇之实现二叉搜索树的核心方法,需要的朋友可以参考下
    2023-12-12
  • java返回前端实体类json数据时忽略某个属性方法

    java返回前端实体类json数据时忽略某个属性方法

    这篇文章主要给大家介绍了关于java返回前端实体类json数据时忽略某个属性的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Netty分布式行解码器逻辑源码解析

    Netty分布式行解码器逻辑源码解析

    这篇文章主要为大家介绍了Netty分布式行解码器逻辑源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • java调用通义千问API的详细完整步骤

    java调用通义千问API的详细完整步骤

    通义千问是阿里云自主研发的大语言模型,能够在用户自然语言输入的基础上,通过自然语言理解和语义分析,理解用户意图,在不同领域、任务内为用户提供服务和帮助,下面这篇文章主要给大家介绍了关于java调用通义千问API的详细完整步骤,需要的朋友可以参考下
    2024-02-02

最新评论