Redis的使用及Spring-data-redis对Redis的简化开发

在这里插入图片描述
redis 是一款开源的 Key-Value 数据库,运行在内存中,由 ANSI C 编写。企业开发通常采用 Redis 来实现缓存。同类的产品还有 memcache 、memcached 、MongoDB 等。

Redis支持丰富的数据结构,常用的有string、list、hash、set、sortset这几种。学习这些数据结构是使用Redis的基础!

首先还是得声明一下,Redis的存储是以key-value的形式的。Redis中的key一定是字符串,value可以是string、list、hash、set、sortset这几种常用的。

一,Redis的下载和使用

目前官网只提供了linux版本的下载,我们想要使用windows版本的,只能在github上下载。

官网下载地址:http://redis.io/download

windows版本的Redis在github下载地址:https://github.com/MSOpenTech/redis/tags

为了大家使用方便,博主在文章末的示例项目提供了redis的windows版本,里面中win32位和win64位,供大家使用。

将下载的redis解压到指定的目录
在这里插入图片描述

主要有三个核心文件:

redis.windows.conf 配置文件,里面是关于redis的一些配置,一般情况下,使用默认即可。
redis-cli.exe 启动客户端执行文件。
redis-server.exe启动服务端执行文件

点击redis-server.exe启动redis服务

在这里插入图片描述

二,把Redis设置成windows下的服务

上面这种方式,虽然启动了Redis服务,但是只要一关闭cmd窗口,redis就会消失。所以要把redis设置成windows下的服务。

设置服务命令
redis-server --service-install redis.windows.conf --loglevel verbose

打开cmd,进入到redis的安装目录,执行上面的命令

在这里插入图片描述

我们win + R 键 打开运行窗口,输入services.msc 查看windows服务

在这里插入图片描述

在这里插入图片描述

选中Redis服务,右键属性

在这里插入图片描述

点击服务状态下的启动按钮这个服务就进行了开启。如果你想让这个服务在电脑开机的时候就启动,在这个服务启动之后,启动类型保持默认自动就可以了,如果不想电脑开机时就启动这个服务,可以设置启动类型为手动。博主在这里选择手动启动类型,在需要这个服务时,再进行启动,给电脑减轻负担,嘿嘿,有没有很机智!

这个服务被设置为windows服务之后,还有一种方便的启动与停止的方式。

管理员身份打开cmd窗口,输入 net start 服务名 即可启动windows服务

在这里插入图片描述

输入net stop 服务名 ,停止windows服务

在这里插入图片描述

这样方式有没有看起来逼格更高一点呢,小小嘚瑟一下?

注意:

1.一定要以管理员的身份运行cmd窗口

2.服务名对应windows服务列表中的服务名称

三, redis-cli.exe 启动客户端

言归正传,我们下面介绍使用redis-cli.exe客户端可执行文件启动redis客户端来操作Redis

点击redis安装目录下的redis-cli.exe启动客户端(服务端要保存开启状态)

redis的常用操作命令:

查看所有的key:keys*

设置值: set key的名称 value值

获取指定key的值: get key的名称

在这里插入图片描述

四,Jedis 使用和图形界面工具

Jedis 是 Redis 官方推出的一款面向 Java 的客户端,提供了很多接口供 Java 语言调用。可以在 Redis 官网下载,当然还有一些开源爱好者提供的客户端,如 Jredis、SRP 等等,推荐使用 Jedis。

Jedis网址: https://github.com/xetorthio/jedis

在这里插入图片描述

创建一个maven项目
在这里插入图片描述

主要引入的依赖:
Jedis : redis的java客户端
Junit :方便进行代码测试

引入的插件:
maven-compiler-plugin : 由于maven项目默认的编译插件版本过低,需要这个编译插件来设置编译的版本

<dependencies>
  	<!-- Jedis -->
  	<dependency>
	    <groupId>redis.clients</groupId>
	    <artifactId>jedis</artifactId>
	    <version>2.9.0</version>
	    <type>jar</type>
	    <scope>compile</scope>
    </dependency>

	<!-- 单元测试 -->
  	<dependency>
  		<groupId>junit</groupId>
  		<artifactId>junit</artifactId>
  		<version>4.12</version>
  	</dependency>
  </dependencies>
  
  <build>
  	<plugins>
  		<!-- 编译插件 -->
  		<plugin>
  			<groupId>org.apache.maven.plugins</groupId>
  			<artifactId>maven-compiler-plugin</artifactId>
  			<version>3.5.1</version>
  			<configuration>
  				<source>1.7</source>
  				<target>1.7</target>
  				<encoding>utf-8</encoding>
  			</configuration>
  		</plugin>
  	</plugins>
  </build>

在引入编译插件之后,项目会报错,需要选中项目---->右键---->Maven---->Update Project 来更新项目

在这里插入图片描述

项目的编译版本修改成功,变更为1.7

准备工作就绪,接下来编写redis java客户端代码,进行测试

    @Test
	public void redisTest() {
		Jedis jedis = new Jedis("localhost");   //localhost 表示连接的是本地的Redis服务端
		jedis.set("foo", "苹果");    
		String value = jedis.get("foo");  
		System.out.println(value);
	}

控制台输出
在这里插入图片描述

说明连接redis服务端连接成功,可以进行简单的存值和取值

我们可以打开redis-cli.exe客户端查看刚才设置的key和value

在这里插入图片描述

当我们存取中文字符时,用redis-cli.exe客户端查看发现对中文字符进行了转码,查看不很方便,这时,我们可以安装redis 安装图形化界面客户端来进行查看

在这里插入图片描述

这个安装程序,在文章末的示例项目中提供。安装步骤很简单,不再演示。

安装成功之后,按照下面操作即可

在这里插入图片描述

在这里插入图片描述

点击创建的连接,里面有16个db,默认使用的是db0

在这里插入图片描述

TTL 是 redis 的 key 有效时间,显示-1 ,没有设置 key 的有效期

一般通过java程序设置key的有效时间,不会使用图形化界面来进行设置

设置key的有效周期
在这里插入图片描述

使用图形化界面查看

在这里插入图片描述

如果我们要设置key的有效时间为一天,那么需要设置 60 * 60 * 24秒,这样来换算,显得不是很方便。当然,Jedis在很多方面的操作都是比较偏向底层的,使用起来不是很方便,而是在其上在封装一层,作为业务的使用。通常在开发中,使用Spring Data Redis来操作Redis。

五,Spring Data Redis 使用

Spring-data-redis 是 spring 大家族的一部分,提供了在 srping 应用中通过简单的配置访问 redis 服务,对 reids 底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate 提供了 redis 各种操作、异常处理及序列化,支持发布订阅,并对 spring 3.1 cache 进行了实现。

spring-data-redis 针对 jedis提供了如下功能:

1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类

2.针对jedis客户端的大量api进行了归类封装,把同一类型的操作封装成了Operation接口.支持redis中的五种数据类型的操作.

3.针对数据的"序列化与反序列化",提供了多种可以选择的策略(RedisSerializer)

JdkSerializationRedisSerializer:当需要存储java对象时使用.

StringRedisSerializer:当需要存储string类型的字符串时使用.

JacksonJsonRedisSerializer:将对象序列化成json的格式存储在redis中,需要jackson-json工具的支持

redisTemplate有两个方法经常用到,一个是opsForXXX一个是boundXXXOps,XXX是value的类型

opsForXXXboundXXXOps的区别

前者获取到一个Opercation,但是没有指定操作的key,可以在一个连接(事务)内操作多个key以及对应的value;后者会获取到一个指定了key的operation,在一个连接内只操作这个key对应的value.

在实际开发过程中,选择其中任意一种方式都可以。不过在示例项目中,这两种方式都进行演示,大家根据喜好进行选择。

==========================================================

在项目的pom.xml文件中引入的依赖:

spring-data-redis:对 reids 底层开发包(Jedis, JRedis, and RJC)进行了高度封装,提供了一个高度封装的“RedisTemplate”类来操作redis

spring-test:加载spring的配置文件,方便测试

<dependencies>
  	<!-- Jedis -->
  	<dependency>
	    <groupId>redis.clients</groupId>
	    <artifactId>jedis</artifactId>
	    <version>2.9.0</version>
	    <type>jar</type>
	    <scope>compile</scope>
    </dependency>

	<!-- 单元测试 -->
  	<dependency>
  		<groupId>junit</groupId>
  		<artifactId>junit</artifactId>
  		<version>4.12</version>
  	</dependency>
  	<!--spring-data-redis  -->
  	<dependency>
  		<groupId>org.springframework.data</groupId>
  		<artifactId>spring-data-redis</artifactId>
  		<version>1.7.3.RELEASE</version>
  	</dependency>
	<!--spring整合juint测试  -->
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-test</artifactId>
  		<version>4.3.8.RELEASE</version>
  	</dependency>
  </dependencies>

spring的配置文件applicationContext-cache.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd
	http://www.springframework.org/schema/data/jpa
	http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
	http://cxf.apache.org/jaxws
	http://cxf.apache.org/schemas/jaxws.xsd
	http://www.springframework.org/schema/cache
	http://www.springframework.org/schema/cache/spring-cache.xsd">
	
	
	<!-- Jedis数据库连接池 -->
	 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
       <property name="maxIdle" value="300" />        
       <property name="maxWaitMillis" value="3000" />  
       <!-- 保证获得的每一个Jedis实例都是可用的 -->
       <property name="testOnBorrow" value="true" />  
    </bean>  
	
	<!-- redis连接工厂  跟配置数据库连接池类似,需要配置JedisConnectionFactory来通过服务器或者连接池的方式获取redis服务器的连接 -->
	<bean id="connectionFactory"  
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
        p:host-name="localhost" p:port="6379" p:pool-config-ref="poolConfig"  
        p:database="0" />  
        
     <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>


    <!-- redis模板配置  spring-data-redis提供了一个基础的泛型RedisTemplate封装了基础的crud操作-->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <!-- 序列化配置   可选配置-->
        <property name="defaultSerializer" ref="stringRedisSerializer"/>
        <property name="keySerializer" ref="stringRedisSerializer"/>
        <property name="valueSerializer" ref="stringRedisSerializer"/>
    </bean>  
</beans>

编写代码演示opsForXXX的用法

方法一:opsForValue() 简单 K-V 操作

	/**
	 * 简单key-value类型操作
	 */
	@Test
	public void opsForValue() {
		
		//设置key和value  并设置key的有效时间
		redisTemplate.opsForValue().set("opsForValue", "小鬼",30,TimeUnit.SECONDS);
		
		String value = (String) redisTemplate.opsForValue().get("opsForValue");
		
		System.out.println(value);
	}
	
	/**
	 * 简单key-value类型删除操作
	 */
	@Test
	public void delOpsForValue() {
		
		redisTemplate.delete("opsForValue");
	}

在这里插入图片描述

使用redis客户端图形化界面查看

在这里插入图片描述

方法二:opsForHash() 针对 map 类型的数据操作

这次不再向先前那样,存放字符串,尝试存放的数据是一个装着User对象的List集合

/**
	 * 针对 map 类型的数据操作
	 */
	@Test
	public void opsForHash() {
		
		List<User> list = new ArrayList<>();
		
		User u1 = new User();
		u1.setId(1);
		u1.setAge(1);
		u1.setUsername("小张");
		
		User u2 = new User();
		u2.setId(2);
		u2.setAge(2);
		u2.setUsername("小王");
		
		list.add(u1);
		list.add(u2);
		
		//向redis中存入一个list集合,list集合中存放的是user对象
		
		//第一个参数 属于大key 对应的值value是一个map 第二个参数是map的key  第三个参数是map的value
		redisTemplate.opsForHash().put("opsForHash", "mapKey",list);
	}

执行单元测试,出现了错误

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String

大概就是说类转换异常,不能把ArrayList类转成String类

出现的原因:

在这里插入图片描述

解决方式有两种:

方式一:

1.修改属性keySerializer为hashKeySerializer 2.修改属性valueSerializer为hashValueSerializer 对应的ref="jdkSerializationRedisSerializer"
 <bean id="stringRedisSerializer" 
     class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <bean id="jdkSerializationRedisSerializer" 
    class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>


    <!-- redis模板配置  spring-data-redis提供了一个基础的泛型RedisTemplate封装了基础的crud操作-->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <!-- 序列化配置   可选配置-->
        <property name="defaultSerializer" ref="stringRedisSerializer"/>
        <property name="hashKeySerializer" ref="stringRedisSerializer"/>
        <property name="hashValueSerializer" ref="jdkSerializationRedisSerializer"/>
    </bean> 

2.,注释掉序列化配置,使用默认的即可,推荐使用第二种。可以减少配置的同时,麻烦也少了

第二种实现的原理:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

通过查看RedisTemplate这个类的源码,发现由于defaultSerializer的序列化方式被初始化为JdkSerializationRedisSerializer,再通把defaultSerializer的值赋值给keySerializer,valueSerializer,hashKeySerializer,hashValueSerializer,所以他们的值都为JdkSerializationRedisSerializer。当向redis中存储不是String字符串也是OK的。

修改完配置文件,进行代码测试

/**
	 * 针对 map 类型的数据操作
	 */
	@Test
	public void opsForHash() {
		
		List<User> list = new ArrayList<>();
		
		User u1 = new User();
		u1.setId(1);
		u1.setAge(1);
		u1.setUsername("小张");
		
		User u2 = new User();
		u2.setId(2);
		u2.setAge(2);
		u2.setUsername("小王");
		
		list.add(u1);
		list.add(u2);
		
		//向redis中存入一个list集合,list集合中存放的是user对象
		
		//第一个参数 属于大key 对应的值value是一个map 第二个参数是map的key  第三个参数是map的value
		redisTemplate.opsForHash().put("opsForHash", "mapKey",list);
		redisTemplate.opsForHash().put("opsForHash", "mapKey2",list);
		redisTemplate.opsForHash().put("opsForHash", "mapKey3",list);
		
		
		//获取所有的小key
		Set keys = redisTemplate.opsForHash().keys("opsForHash");
		
		System.out.println("获取所有的小key:"+keys);
		
		//获取所有的value
		list =  redisTemplate.opsForHash().values("opsForHash");
		
		System.out.println("获取所有的value: "+list);
		
		
		//获取某一个小key的value
		list =(List<User>) redisTemplate.opsForHash().get("opsForHash", "mapKey");
		
		System.out.println("获取某一个小key的value: "+list);
		
		
		
	}

控制台成功输出

在这里插入图片描述

删除大key中的某一个小key 和 删除整个大key

/**
	 * 针对 map 数据删除操作
	 */
	@Test
	public void delOpsForHash() {
		
		//删除大key中的某一个map
		redisTemplate.opsForHash().delete("opsForHash", "mapKey");
		
		//删除大key
		redisTemplate.delete("opsForHash");
	}

===========================================================

剩下的三种方式使用大致相同,不做演示

opsForSet() set 类型数据操作

opsForList() 针对 list 类型的数据操作

opsForZSet() zset 类型数据操作

编写代码演示BoundXXXOpsTest的用法

方法一:boundValueOps() 简单 K-V 操作

/**
	 * 简单key-value类型操作
	 */
	@Test
	public void boundValueOps() {
		
		//设置key和value  并设置key的有效时间
		redisTemplate.boundValueOps("boundValueOps").set("小鬼",30,TimeUnit.SECONDS);
		
		String value = (String) redisTemplate.opsForValue().get("boundValueOps");
		
		System.out.println(value);
	}
	
	/**
	 * 简单key-value类型删除操作
	 */
	@Test
	public void delBoundValueOps() {
		
		redisTemplate.delete("boundValueOps");
	}

方法二:boundHashOps() 针对 map 类型的数据操作

	/**
	 * 针对 map 类型的数据操作
	 */
	@Test
	public void boundHashOps() {
		
		List<User> list = new ArrayList<>();
		
		User u1 = new User();
		u1.setId(1);
		u1.setAge(1);
		u1.setUsername("小张");
		
		User u2 = new User();
		u2.setId(2);
		u2.setAge(2);
		u2.setUsername("小王");
		
		list.add(u1);
		list.add(u2);
		
		//向redis中存入一个list集合,list集合中存放的是user对象
		
		//第一个参数 属于大key 对应的值value是一个map 第二个参数是map的key  第三个参数是map的value
		redisTemplate.boundHashOps("boundHashOps").put("key1", list);
		redisTemplate.boundHashOps("boundHashOps").put("key2", list);
		redisTemplate.boundHashOps("boundHashOps").put("key3", list);
		
		
		//获取所有的小key
		Set keys = redisTemplate.boundHashOps("boundHashOps").keys();
		
		System.out.println("获取所有的小key:"+keys);
		
		//获取所有的value
		list =  redisTemplate.boundHashOps("boundHashOps").values();
		
		System.out.println("获取所有的value: "+list);
		
		
		//获取某一个小key的value
		list =(List<User>) redisTemplate.boundHashOps("boundHashOps").get("key1");
		
		System.out.println("获取某一个小key的value: "+list);
		
		
		
	}
	
	/**
	 * 针对 map 数据删除操作
	 */
	@Test
	public void delBoundHashOps() {
		
		//删除大key中的某一个map
		redisTemplate.boundHashOps("boundHashOps").delete("key1");
		
		//删除大key
		redisTemplate.delete("opsForHash");
	}
	

剩下的三种方式使用大致相同,不做演示

boundSetOps() set 类型数据操作

boundListOps() 针对 list 类型的数据操作

boundZSetOps() zset 类型数据操作

==================================================================

以上就是有关Spring-data-redis对Redis的常用操作,后续会补充Redis搭建集群的相关知识。

最后分享示例项目在码云的地址:https://gitee.com/xiaoguixiaogege/springdataredis

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值