美文网首页Spring-Boot
Spring全家桶——SpringBoot入门Redis

Spring全家桶——SpringBoot入门Redis

作者: Java_Pro | 来源:发表于2019-01-17 17:34 被阅读0次

    首先,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);
    

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

    相关文章

      网友评论

        本文标题:Spring全家桶——SpringBoot入门Redis

        本文链接:https://www.haomeiwen.com/subject/akzidqtx.html