Redis基础学习


Redis基础

可当数据库也可用于当缓存(cache),redis存储的方式是key-value的键值对形式

Redis的应用场景:

  • 缓存(cache)

  • 任务队列

  • 消息队列

  • 分布式锁

一、下载安装与使用

1.1.下载安装

Redis安装包分为windows版和Linux版:

Windows版下载地址:https://github.com/microsoftarchive/redis/releases

Linux版下载地址: https://download.redis.io/releases/

在Linux系统安装Redis步骤:

1.将Redis安装包上传到Linux

2.解压安装包,命令:tar -zxvf redis-4.0.0.tar.gz -C /usr/local

3.安装Redis的依赖环境gcc,命令:yum install gcc-c++

4.进入/usr/local/redis-4.0.0,进行编译,命令:make

5.进入redis的src目录,进行安装,命令:make install

1.2.redis服务启动、连接与停止

Linux中redis服务启动与停止

Linux中redis服务启动,可以使用redis-server(安装redis目录里的src下),默认端口号为6379

在这里插入图片描述

Ctrl + C停止Redis服务

连接redis服务(客户端连接):redis-cli

优化:将redis服务于后台运行

  • 修改src下的redis-conf配置文件,令daemonize yes

  • 再次启动redis显示加载配置文件: src/redis-service ./redis-conf

关闭连接,重新连接:

  • 找到进程:ps -ef | grep reids
  • 关闭:kill -9 进程端口号

Windows中redis服务启动与停止:

Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

在这里插入图片描述

Windows系统中启动Redis,直接双击redis-server.exe即可启动Redis服务,redis服务默认端口号为6379

在这里插入图片描述

Ctrl + C停止Redis服务

1.3.设置密码和远程连接

为了安全,当客户连接redis服务的时候,要登录,为此我们给Linux系统中设置密码认证:

  • 在redis conf配置文件中修改即可,

requirepass foobared

  • 关闭连接,重新连接:
    • 找到进程:ps -ef | grep reids
    • 关闭:kill -9 进程端口号
  • 重新启动redis(当前在redis目录下): src/redis-server ./redis.conf
  • 然后就可以通过客户端连接(登陆的同时完成认证):src/redis-cli -h localhost -p 6379 -a 123456

修改配置文件,使得可以远程连接Linux虚拟机中的redis服务

  • 进入 redis-conf,快捷方式bind,将只能由本机连接的信息注释# bind 127.0.0.1
  • 然后重新启动服务(杀掉进程 然后重启)
  • Windows系统尝试连接远程redis服务,记得关闭防火墙(或者开启特定端口号)
    • 在windows安装redis的目录下,打开终端.\redis-cli.exe -h 192.168.245.100 -p 6379 -a 123456

在这里插入图片描述

防火墙相关指令:

systemctl start firewalld

systemctl status firewalld / firewall-cmd --state

firewall-cmd --zone=public --add-port=6379/tcp --permanent

firewall-cmd --reload

二、redis数据类型

在这里插入图片描述

redis中通过命令操作数据!

更多命令可以参考Redis中文网:https://www.redis.net.cn

2.1.字符串 string 操作命令

在这里插入图片描述

2.2.哈希 hash 操作命令

该指令常用于存储对象!

在这里插入图片描述

2.3.列表 list 操作命令

常用于做任务队列!

在这里插入图片描述

BRPOP当删除列表的最后一个元素后,会堵塞timeout

在这里插入图片描述

2.4.集合 set 操作命令

在这里插入图片描述

2.5.有序集合 sorted set 操作命令

在这里插入图片描述

2.6.通用命令

以下指令是针对key的,也就说适用于所有类型!

在这里插入图片描述

三、在 Java 中操作 Redis

3.1.介绍

Redis 的 Java 客户端很多,官方推荐的有三种:

  • Jedis
  • Lettuce
  • Redisson

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即spring-boot-starter-data-redis

3.2.Jedis(不常用略过)

3.3.Data Redis(常用)

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:简单K-V操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对map类型的数据操作
  • ListOperations:针对list类型的数据操作

实现步骤:

1、引入maven坐标

在Spring Boot 项目中,可以使用Spring Data Redis(boot项目自带)来简化Redis操作,maven坐标:

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

2、配置yml配置文件,一定要保证基本信息是正确的!

spring:
  application:
    name: redis-demo
  #Redis相关配置
  redis:
    host: 192.168.245.100 #安装redis的服务器ip
    port: 6379 #redis进程端口号
    password: 123456
    database: 0 #操作的是0号数据库
    jedis:
      #Redis连接池配置
      pool:
        max-active: 8 #最大连接数
        max-wait: 1ms #连接池最大阻塞等待时间
        max-idle: 4 #连接池中的最大空闲连接
        min-idle: 0 #连接池中的最小空闲连接

3、编写测试类测试

package com.itheima.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作String类型数据
     */
    @Test
    public void testString(){
        redisTemplate.opsForValue().set("city123","beijing");

        String value = (String) redisTemplate.opsForValue().get("city123");
        System.out.println(value);

        redisTemplate.opsForValue().set("key1","value1",10l, TimeUnit.SECONDS);

        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city1234", "nanjing");
        System.out.println(aBoolean);
    }

    /**
     * 操作Hash类型数据
     */
    @Test
    public void testHash(){
        HashOperations hashOperations = redisTemplate.opsForHash();

        //存值
        hashOperations.put("002","name","xiaoming");
        hashOperations.put("002","age","20");
        hashOperations.put("002","address","bj");

        //取值
        String age = (String) hashOperations.get("002", "age");
        System.out.println(age);

        //获得hash结构中的所有字段
        Set keys = hashOperations.keys("002");
        for (Object key : keys) {
            System.out.println(key);
        }

        //获得hash结构中的所有值
        List values = hashOperations.values("002");
        for (Object value : values) {
            System.out.println(value);
        }
    }

    /**
     * 操作List类型的数据
     */
    @Test
    public void testList(){
        ListOperations listOperations = redisTemplate.opsForList();

        //存值
        listOperations.leftPush("mylist","a");
        listOperations.leftPushAll("mylist","b","c","d");

        //取值
        List<String> mylist = listOperations.range("mylist", 0, -1);
        for (String value : mylist) {
            System.out.println(value);
        }

        //获得列表长度 llen
        Long size = listOperations.size("mylist");
        int lSize = size.intValue();
        for (int i = 0; i < lSize; i++) {
            //出队列
            String element = (String) listOperations.rightPop("mylist");
            System.out.println(element);
        }
    }

    /**
     * 操作Set类型的数据
     */
    @Test
    public void testSet(){
        SetOperations setOperations = redisTemplate.opsForSet();

        //存值
        setOperations.add("myset","a","b","c","a");

        //取值
        Set<String> myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

        //删除成员
        setOperations.remove("myset","a","b");

        //取值
        myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

    }

    /**
     * 操作ZSet类型的数据
     */
    @Test
    public void testZset(){
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();

        //存值
        zSetOperations.add("myZset","a",10.0);
        zSetOperations.add("myZset","b",11.0);
        zSetOperations.add("myZset","c",12.0);
        zSetOperations.add("myZset","a",13.0);

        //取值
        Set<String> myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }

        //修改分数
        zSetOperations.incrementScore("myZset","b",20.0);

        //取值
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }

        //删除成员
        zSetOperations.remove("myZset","a","b");

        //取值
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
    }

    /**
     * 通用操作,针对不同的数据类型都可以操作
     */
    @Test
    public void testCommon(){
        //获取Redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }

        //判断某个key是否存在
        Boolean itcast = redisTemplate.hasKey("itcast");
        System.out.println(itcast);

        //删除指定key
        redisTemplate.delete("myZset");

        //获取指定key对应的value的数据类型
        DataType dataType = redisTemplate.type("myset");
        System.out.println(dataType.name());

    }
}

发现key乱码:

在这里插入图片描述

  • 原因集成的RedisTemplate带有默认的Key序列化器
  • 解决方案:编写配置类,修改掉默认序列化器,用我们自己的即可

方式一:编写配置类,自定义序列化器

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置
 *
 * @author MinghanSui
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(mapper);

        // key采用StringRedisSerializer 序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value采用GenericJackson2JsonRedisSerializer 序列化方式
        template.setValueSerializer(genericJackson2JsonRedisSerializer);

        // Hash key采用StringRedisSerializer 序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // Hash value采用GenericJackson2JsonRedisSerializer 序列化方式
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
}

方式二:编写配置类,自定义序列化器

RedisTemplate改为使用StringRedisTemplate即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值