Spring全家桶——SpringBoot入门Redis

首先,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的定期删除了;
引自:https://blog.csdn.net/angleflyyy/article/details/81627785

准备工作

项目工具环境:

  • IDEA 2018.2
  • Gradle 4+
  • JDK1.8以上
  • redis服务器

设置Redis服务器

redis下载地址:https://redis.io/download
如果你的电脑是Mac:

brew install redis

然后运行redis服务器

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开始界面初始化一个项目

[图片上传失败...(image-ac4c06-1547717625717)]

这里选择的是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

[图片上传失败...(image-979a74-1547717625717)]

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

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

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

[图片上传失败...(image-3fdf56-1547717625717)]

是乱的,是因为在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;
    }

}

再去执行一下刚刚的方法

[图片上传失败...(image-cf2646-1547717625717)]

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

opsForList()添加操作
    @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));
    }

[图片上传失败...(image-3d98b-1547717625717)]

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

[图片上传失败...(image-f2e0dc-1547717625717)]

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

  • key 对应的是redis中存的key值
  • count 正数就是从左边开始删除 负数是从右面 例如-1就从右删除第一个值为value的,0代表删除全部值为value的
  • value 就是需要从list移除的值
opsForSet()添加操作

利用了set值的不可重复

    @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"));
    }

结果

[图片上传失败...(image-c3fbae-1547717625717)]

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

opsForSet()的删除操作

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

    @Test
    public void EsetRedisRemove(){
        redisTemplate.opsForSet().remove("userSet","张无忌");
    }
opsForHash()操作
    //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");
    }

结果

[图片上传失败...(image-211600-1547717625717)]

测试类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是为了让日志书写更方便

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容