在SpringBoot整合Redis之前,先来简单认识下Redis。

1. Redis 简介

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库
Redis 与其他 key - value 缓存产品有以下三个特点

  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供strings(字符串),list(列表),set(集合),zset(有序集合),hash(哈希)等数据结构的存储(支持多种数据结构)。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • Redis 典型的应用场景:缓存、计数器、排行榜、消息队列、社交网络等。

    2. Redis 优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    3. Redis与其他key-value存储有什么不同?

  • Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

  • Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是, 相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。 同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

    4. 使用SpringBoot整合Redis

    4.1 导入依赖:在 pom.xml 文件中导入对应的依赖

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-data-redis</artifactId>
    4. </dependency>

    4.2 配置Redis

    在 application.properties 或 application.yml 中配置:
    1. # RedisProperties
    2. # 这个是redis所在主机的ip地址,安装在本机直接写 localhost 或者127.0.0.0,安装在云服务器写对应的云服务器的ip地址
    3. spring.redis.host= 59.xxx.xxx.xxx
    4. # redis 的端口号
    5. spring.redis.port=6379
    6. # redis 的密码
    7. spring.redis.password= xxx
    8. spring.redis.database=0
    9. # 连接超时时间
    10. spring.redis.timeout=1800000
    11. # 连接池最大连接数(使用负值表示没有限制)
    12. spring.redis.lettuce.pool.max-active=20
    13. # 连接池最大阻塞等待时间(使用负值表示没有限制)
    14. spring.redis.lettuce.pool.max-wait=-1
    15. # 连接池中的最大空闲连接
    16. spring.redis.lettuce.pool.max-idle=5
    17. # 连接池中的最小空闲连接
    18. spring.redis.lettuce.pool.min-idle=0
    编写 RedisConfig 配置类,构造 RedisTemplate ```java 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.RedisSerializer;

@Configuration public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { // 当你在定义一个 bean 的时候,方法中声明的 factory 参数,spring会自动把这个 bean 注入进来 RedisTemplate template = new RedisTemplate<>(); //配置了连接工厂,具备了访问数据库的能力 template.setConnectionFactory(factory); //配置Template主要配置序列化的方式

  1. //设置Key的序列化方式
  2. template.setKeySerializer(RedisSerializer.string());
  3. //设置普通value的序列化方式
  4. template.setValueSerializer(RedisSerializer.json());
  5. //设置hash的key的序列化方式
  6. template.setHashKeySerializer(RedisSerializer.string());
  7. //设置hash的value的序列化方式
  8. template.setHashValueSerializer(RedisSerializer.json());
  9. template.afterPropertiesSet();
  10. return template;
  11. }

}

  1. <a name="K5xKE"></a>
  2. ### 4.3 测试:
  3. ```java
  4. @RunWith(SpringRunner.class)
  5. @ContextConfiguration(classes = CommunityApplication.class)
  6. @SpringBootTest
  7. public class RedisTests {
  8. // 注入 RedisTemplate
  9. @Autowired
  10. private RedisTemplate redisTemplate;
  11. @Test
  12. public void testStrings(){
  13. String redisKey = "test:count";
  14. redisTemplate.opsForValue().set(redisKey,1);
  15. System.out.println(redisTemplate.opsForValue().get(redisKey));
  16. System.out.println(redisTemplate.opsForValue().increment(redisKey));
  17. System.out.println(redisTemplate.opsForValue().decrement(redisKey));
  18. }
  19. @Test
  20. public void testHash(){
  21. String redisKey = "test:user";
  22. redisTemplate.opsForHash().put(redisKey,"id",1);
  23. redisTemplate.opsForHash().put(redisKey,"name","张三");
  24. System.out.println(redisTemplate.opsForHash().get(redisKey,"id"));
  25. System.out.println(redisTemplate.opsForHash().get(redisKey,"name"));
  26. }
  27. @Test
  28. public void testLists(){
  29. String redisKey = "test:ids";
  30. redisTemplate.opsForList().leftPush(redisKey,101);
  31. redisTemplate.opsForList().leftPush(redisKey,102);
  32. redisTemplate.opsForList().leftPush(redisKey,103);
  33. System.out.println(redisTemplate.opsForList().size(redisKey));
  34. System.out.println(redisTemplate.opsForList().index(redisKey,0));
  35. System.out.println(redisTemplate.opsForList().range(redisKey,0,2));
  36. System.out.println(redisTemplate.opsForList().leftPop(redisKey));
  37. System.out.println(redisTemplate.opsForList().leftPop(redisKey));
  38. System.out.println(redisTemplate.opsForList().leftPop(redisKey));
  39. }
  40. @Test
  41. public void testSet(){
  42. String redisKey = "test:teachers";
  43. redisTemplate.opsForSet().add(redisKey,"liubei","guanyu","zhangfei","zhaoyun","zhugeliang");
  44. System.out.println(redisTemplate.opsForSet().size(redisKey));
  45. System.out.println(redisTemplate.opsForSet().pop(redisKey));
  46. System.out.println(redisTemplate.opsForSet().members(redisKey));
  47. }
  48. @Test
  49. public void testSortedSet(){
  50. String redisKey = "test:students";
  51. redisTemplate.opsForZSet().add(redisKey,"唐僧",80);
  52. redisTemplate.opsForZSet().add(redisKey,"悟空",100);
  53. redisTemplate.opsForZSet().add(redisKey,"猪八戒",50);
  54. redisTemplate.opsForZSet().add(redisKey,"沙僧",20);
  55. redisTemplate.opsForZSet().add(redisKey,"白龙马",10);
  56. System.out.println(redisTemplate.opsForZSet().zCard(redisKey));
  57. System.out.println(redisTemplate.opsForZSet().score(redisKey,"猪八戒"));
  58. System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey,"猪八戒"));
  59. System.out.println(redisTemplate.opsForZSet().range(redisKey,0,2));
  60. }
  61. @Test
  62. public void testKeys(){
  63. redisTemplate.delete("test:student");
  64. System.out.println(redisTemplate.hasKey("test:student"));
  65. redisTemplate.expire("test:teachers",10, TimeUnit.SECONDS);
  66. }
  67. //多次访问redisKey,可以绑定
  68. @Test
  69. public void testBoundOperations(){
  70. String redisKey = "test:count";
  71. BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
  72. operations.increment();
  73. operations.increment();
  74. operations.increment();
  75. operations.increment();
  76. operations.increment();
  77. System.out.println(operations.get());
  78. }
  79. //编程式事务管理
  80. @Test
  81. public void testTransactional(){
  82. Object obj = redisTemplate.execute(new SessionCallback() {
  83. @Override
  84. public Object execute(RedisOperations operations) throws DataAccessException {
  85. String redisKey = "test:tx";
  86. operations.multi();
  87. operations.opsForSet().add(redisKey,"zhangsan");
  88. operations.opsForSet().add(redisKey,"lisi");
  89. operations.opsForSet().add(redisKey,"wangwu");
  90. //在事务中进行查询是无效的
  91. System.out.println(operations.opsForSet().members(redisKey));
  92. return operations.exec();
  93. }
  94. });
  95. System.out.println(obj);
  96. }
  97. }

4.4 小结:

1、当项目报以下错误:Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
报错的原因:是redis服务没设置密码,而项目配置文件中写了有redis密码
解决方案:
1)把项目配置文件中的密码password设置为空或者不设置。
2)设置redis服务密码
——可通过直接修改redis.conf配置文件中的requirepass属性方式,如果修改不生效,可通过命令方式修改,进入redis的客户端

  1. redis 127.0.0.1:6379> CONFIG SET requirepass root
  2. OK
  3. redis 127.0.0.1:6379> AUTH root
  4. OK

然后重启项目就可以连接本机的redis服务了。