//本文作者:cuifuan

首先,Redis是什么?

Redis是一个开源的,基于内存的键值数据存储,用作数据库,缓存和消息代理。在实现方面,Key-Value存储代表NoSQL空间中最大和最老的成员之一。Redis支持数据结构,如字符串,散列,列表,集和带范围查询的有序集。

 

在spring data redis的框架,可以很容易地编写,通过提供一个抽象的数据存储使用Redis的键值存储的Spring应用程序。 非关系型数据库,基于内存,存取数据的速度不是关系型数据库所能比拟的 redis是键值对(key-value)的数据库

有5中主要数据类型:

  • 字符串类型 string

  • 散列类型 hash

  • 列表类型 list

  • 集合类型 set

  • 有序集合类型 zset

redis缓存为啥速度快

这么说吧,别人问你什么是“redis”,如果你知道,你可以直接吧啦吧啦一大堆,其实这个时候你的大脑就类似redis缓存,别人问的“redis”就是key,你说出来的结果就是value,而你如果不知道,你就去上网查,然后再告诉别人,这就类似于查询数据库了,你查了再告诉别人当然慢了!

你把脑袋里的东西写进笔记就类似redis持久化保存了;

你过了两个月把这玩意忘了,就是redis的定期删除了;

准备工作

项目工具环境:

  • IDEA 2018.2

  • Gradle 4+

  • JDK1.8以上

  • redis服务器

设置Redis服务器

redis下载地址:https://redis.io/download

如果你的电脑是Mac:

brew install redis



然后运行redis服务器

  1. cuifuandeMacBook-Pro:~ cuifuan$ redis-server
    
    25336:C 29 Nov 2018 14:53:42.490 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    
    25336:C 29 Nov 2018 14:53:42.490 # Redis version=5.0.2, bits=64, commit=00000000, modified=0, pid=25336, just started
    
    25336:C 29 Nov 2018 14:53:42.490 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    
    25336:M 29 Nov 2018 14:53:42.491 * Increased maximum number of open files to 10032 (it was originally set to 256).
    
                   _._                                                  
    
              _.-``__ ''-._                                            
    
         _.-``    `.  `_.  ''-._           Redis 5.0.2 (00000000/0) 64 bit
    
     .-`` .-```.  ```\/    _.,_ ''-._                                  
    
    (    '      ,       .-`  | `,    )     Running in standalone mode
    
    |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
    
    |    `-._   `._    /     _.-'    |     PID: 25336
    
     `-._    `-._  `-./  _.-'    _.-'                                  
    
    |`-._`-._    `-.__.-'    _.-'_.-'|                                  
    
    |    `-._`-._        _.-'_.-'    |           http://redis.io        
    
     `-._    `-._`-.__.-'_.-'    _.-'                                  
    
    |`-._`-._    `-.__.-'    _.-'_.-'|                                  
    
    |    `-._`-._        _.-'_.-'    |                                  
    
     `-._    `-._`-.__.-'_.-'    _.-'                                  
    
         `-._    `-.__.-'    _.-'                                      
    
             `-._        _.-'                                          
    
                 `-.__.-'                                              
    
    25336:M 29 Nov 2018 14:53:42.492 # Server initialized
    
    25336:M 29 Nov 2018 14:53:42.492 * Ready to accept connections

     

初始化项目

现在去Spring开始界面初始化一个项目

Spring全家桶系列--SpringBoot入门Redis_spring

这里选择的是Gradle,选择完成点击Generate Projrct生成项目,这个时候会自动下载一个压缩包给你,解压过后导入,导入IDEA教程:http://note.youdao.com/noteshare?id=74e2d65e2d22cd684c3fdd6695b3ecdf

Gradle 依赖管理

让我们在build.gradle中为我们正在构建的示例应用程序声明必要的依赖项

buildscript {

   repositories {

       maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }

   }

   dependencies {

       classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.0.RELEASE")

   }

}

apply plugin: 'java-library'

apply plugin: 'org.springframework.boot'

apply plugin: 'io.spring.dependency-management'

group = 'com.example'

version = '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8

repositories {

   maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }

}

dependencies {

   implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

   implementation 'org.springframework.boot:spring-boot-starter-data-redis'

   implementation 'org.springframework.boot:spring-boot-starter-web'

   implementation 'mysql:mysql-connector-java'

   implementation 'org.projectlombok:lombok'

   implementation 'org.apache.commons:commons-pool2:2.4.2'

   implementation 'com.alibaba:fastjson:1.2.51'

   testImplementation 'org.springframework.boot:spring-boot-starter-test'

}


开始使用

凭借着SpringBoot的开箱即用的特点,集成Redis也不例外

  • redisTemplate.opsForValue();//操作字符串

  • redisTemplate.opsForHash();//操作hash

  • redisTemplate.opsForList();//操作list

  • redisTemplate.opsForSet();//操作set

  • redisTemplate.opsForZSet();//操作有序set

 

Spring全家桶系列--SpringBoot入门Redis_spring_02

在Spring的测试类中开始使用:

redisTemplate.opsForValue().set("username","test");



执行过后发现存在redis中的数据:

Spring全家桶系列--SpringBoot入门Redis_java_03

是乱的,是因为在set后redis会序列化key和value,所以我们要在config中重写一下redisTemplate

src/main/java/com/example/springbootredisdemo/config/RedisConfig.java

package com.example.springbootredisdemo.config;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.GenericToStringSerializer;

import org.springframework.data.redis.serializer.RedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration

public class RedisConfig {

   private final RedisTemplate redisTemplate;

   @Autowired

   public RedisConfig(RedisTemplate redisTemplate) {

       this.redisTemplate = redisTemplate;

   }

   @Bean

   @SuppressWarnings("unchecked")

   public RedisTemplate<String, Object> redisTemplate() {

       RedisSerializer<String> stringSerializer = new StringRedisSerializer();

       RedisSerializer<Object> jsonString = new GenericToStringSerializer<>(Object.class);

       redisTemplate.setKeySerializer(stringSerializer);

       redisTemplate.setValueSerializer(jsonString);

       redisTemplate.setHashKeySerializer(stringSerializer);

       redisTemplate.setHashValueSerializer(jsonString);

       return redisTemplate;

   }

}



再去执行一下刚刚的方法

Spring全家桶系列--SpringBoot入门Redis_redis_04

经过自定义的序列化之后可以了,没有乱码了

opsForList()添加操作
  1.  

     @Test
    
       public void CsetListRedis(){
    
           List<String> trap = new ArrayList<>();
    
           trap.add("张三");
    
           trap.add("张无忌");
    
           trap.add("新垣结衣");
    
           //循环向userlist左添加值
    
           trap.forEach(value->redisTemplate.opsForList().leftPush("userlist",value));
    
           //向userlist右添加值
    
           redisTemplate.opsForList().rightPush("userlist","rightValue");
    
           log.info("userlist->{}",redisTemplate.opsForList().range("userlist",0,10));
    
       }

     

Spring全家桶系列--SpringBoot入门Redis_json_05

opsForList()删除操作
  1.  

     @Test
    
       public void DlistRedisRemove(){
    
           redisTemplate.opsForList().remove("userlist",0,"张无忌");
    
       }

     

  1.  

Spring全家桶系列--SpringBoot入门Redis_redis_06

通过源码看这里有三个参数:

  • key 对应的是redis中存的key值

  • count 正数就是从左边开始删除 负数是从右面 例如-1就从右删除第一个值为value的,0代表删除全部值为value的

  • value 就是需要从list移除的值

opsForSet()添加操作

利用了set值的不可重复

  1.  

      @Test
    
       public void CsetRedis(){
    
           List<String> trap = new ArrayList<>();
    
           trap.add("张三");
    
           trap.add("里斯");
    
           trap.add("里斯");
    
           trap.add("张无忌");
    
           trap.add("新垣结衣");
    
           System.out.print(trap.toString());
    
           //循环向userlist左添加值
    
           trap.forEach(value->redisTemplate.opsForSet().add("userSet",value));
    
           log.info("取出userSet->{}",redisTemplate.opsForSet().members("userSet"));
    
       }

     

结果

Spring全家桶系列--SpringBoot入门Redis_maven_07

符合了Set集合的无序和不可重复性

opsForSet()的删除操作

这个删除操作就比较容易了,直接根据set的key值,后面参数写其需要删除的value就可以

  1.     @Test
    
       public void EsetRedisRemove(){
    
           redisTemplate.opsForSet().remove("userSet","张无忌");
    
       }

     

opsForHash()操作
  1.  

      //opsForHash()操作
    
       @Test
    
       public void FhashRedisAdd(){
    
           //添加
    
           redisTemplate.opsForHash().put("user","phone",10086);
    
           redisTemplate.opsForHash().put("user","address","Shanghai");
    
           redisTemplate.opsForHash().put("user","del","mubaba");
    
           redisTemplate.opsForHash().put("user","dada","达达");
    
           //修改
    
           redisTemplate.opsForHash().put("user","address","Beijing");
    
           //删除
    
           redisTemplate.opsForHash().delete("user","del","dada");
    
        

     

  2. }


结果

Spring全家桶系列--SpringBoot入门Redis_java_08

测试类SpringbootRedisDemoApplicationTests

src/test/java/com/example/springbootredisdemo/SpringbootRedisDemoApplicationTests.java

package com.example.springbootredisdemo;

import com.example.springbootredisdemo.service.NovelService;

import lombok.extern.slf4j.Slf4j;

import org.junit.FixMethodOrder;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.junit.runners.MethodSorters;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;

import java.util.List;

//根据测试方法名字搞定执行顺序

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

@RunWith(SpringRunner.class)

@SpringBootTest

@Slf4j

public class SpringbootRedisDemoApplicationTests {

   @Autowired

   private NovelService novelService;

   @Autowired

   private RedisTemplate<String,Object> redisTemplate;

   private final static String KEY = "username";

   private final static String VALUE = "test";

   @Test

   public void AstringRedis(){

       redisTemplate.opsForValue().set(KEY,VALUE);

       log.info("string set存储:{}->{}",KEY,VALUE);

       redisTemplate.opsForValue().get(KEY);

       log.info("string 根据{}取出{}",KEY,VALUE);

   }

   @Test

   public void BlistRedis(){

       List<String> trap = new ArrayList<>();

       trap.add("张三");

       trap.add("张三");

       trap.add("张无忌");

       trap.add("新垣结衣");

       //循环向userlist左添加值

       trap.forEach(value->redisTemplate.opsForList().leftPush("userlist",value));

//        redisTemplate.opsForList().leftPushAll("userlist",trap);

       //向userlist右添加值

       redisTemplate.opsForList().rightPush("userlist","rightValue");

       //取出userlist的值

       log.info("userlist->{}",redisTemplate.opsForList().range("userlist",0,10));

   }

   @Test

   public void CsetRedis(){

       List<String> trap = new ArrayList<>();

       trap.add("张三");

       trap.add("里斯");

       trap.add("里斯");

       trap.add("张无忌");

       trap.add("新垣结衣");

       System.out.print(trap.toString());

       //循环向userlist左添加值

       trap.forEach(value->redisTemplate.opsForSet().add("userSet",value));

       log.info("取出userSet->{}",redisTemplate.opsForSet().members("userSet"));

   }

   @Test

   public void DlistRedisRemove(){

       redisTemplate.opsForList().remove("userlist",0,"张无忌");

   }

   @Test

   public void EsetRedisRemove(){

       redisTemplate.opsForSet().remove("userSet","张无忌");

   }

   //opsForHash()操作

   @Test

   public void FhashRedisAdd(){

       //添加

       redisTemplate.opsForHash().put("user","phone",10086);

       redisTemplate.opsForHash().put("user","address","Shanghai");

       redisTemplate.opsForHash().put("user","del","mubaba");

       redisTemplate.opsForHash().put("user","dada","达达");

       //修改

       redisTemplate.opsForHash().put("user","address","Beijing");

       //删除

       redisTemplate.opsForHash().delete("user","del","dada");

   }

}



小知识

方法名字前加ABCD...是为了让方法有执行顺序,根据测试方法名字搞定执行顺序,在方法上加注解 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
日志注解@Slf4j是为了让日志书写更方便

  1.  //之前写日志  
    
    log.info("输出a"+index+"b");
    
    //现在
    
    log.info("输出a{}b",index) 


    ;


多个参数可以用多个{},总之,喜欢哪个用哪个,谢谢!

码云代码地址

https://gitee.com/cuifuan/SpringBoot

 

 

看完本文有收获?请转发分享给更多人

Spring全家桶系列--SpringBoot入门Redis_redis_09