(4)Redis的Java API

时间:2024-04-07 18:42:57

前言

本节主要论述如何在Java中使用Redis。在Java中,可以简易地使Redis,或者通过Spring的RedisTemplate使用Redis。为了实际的工作和学习的需要,以下内容会以Spring的视角为主来介绍在Java中如何使用Redis,不过在基础部分会以XML方式的配置主,而在实践部分则会以Java的配置为主介绍Redis,我们可以根据需要使用XML或者注解来实现想要的功能。

1. 在Java中使用Redis

首先,在Java中使用Redis工具,要先下载jedis.Jar包,把它加载到工程的路径中。

所以首先打开网站http://mvnrepository.com/artifact/redi s.clients/jedis,下载你需要的jar包,导入到工程路径即可使用。

测试Java连接Redis:

/**
 * 【1】测试Java连接Redis
 */
public static void run1(){
	Jedis jedis = new Jedis("192.168.72.134",6379);
	int i = 0;
	try {
		long start = System.currentTimeMillis();
		while(true){
			long end = System.currentTimeMillis();
			if (end - start >= 1000) {
				break;
			}
			i++;
			jedis.set("key"+i, i+"");
		}
	} finally{
		jedis.close();
	}
	System.out.println("redis每秒操作:" + i + "次");
}

这段主要测试Redis的写入数据的性能,而事实上Redis的速度比上述操作快的多,这里慢是因为我们只是一条一条地将命名发给Redis执行。如果使用流水线技术它就会快的飞起,将达到10次/s的操作,十分有利于系统性能的提高。

注意:这里仅仅是一个简单的测试连接,更多的时候我们会使用连接池去管理它。Java Redis的连接池提供了类redis.clients.jedis.JedisPool用来创建Redis连接池对象。使用这个对象,需要使用类redis.clients.jedis.JedisPoolConfig对连接池进行配置。

使用Redis连接池:

public static void run2(){
        //配置Redis连接池
	JedisPoolConfig poolConfig = new JedisPoolConfig();
	//最大空闲时间
	poolConfig.setMaxIdle(50);
	//最大连接数
	poolConfig.setMaxTotal(100);
	//最大等待毫秒数
	poolConfig.setMaxWaitMillis(20000);
	//使用配置创建连接池
	JedisPool pool = new JedisPool(poolConfig,"192.168.72.134");
	//从连接池中获取单个连接
	Jedis jedis = pool.getResource();
	int i = 0;
	try {
		long start = System.currentTimeMillis();
		while(true){
			long end = System.currentTimeMillis();
			if (end - start >= 1000) {
				break;
			}
			i++;
			jedis.set("key"+i, i+"");
		}
	} finally{
		jedis.close();
	}
	System.out.println("redis每秒操作:" + i + "次");
}

由于Redis只能提供基于字符串型的操作,而在Java中使用的却以类对象为主,所以需要Redis存储的字符串和Java对象相互转换。如果自己编写这些规则,工作量还是比较大的,比如一个角色对象,我们没有办法直接把对象存入Redis中,需要进一步进行转换,所以对操作对象而言,使用Redis还是比较难的。好在Spring对这些进行了封装和支持,它提供了序列化的设计框架和一些序列化的类,使用后它可以通过序列化把Java对象转换,使得Redis能把它存储起来,并且在读取的时候,再把由序列化过的字符串转化为Java对象,这样在Java环境中使用Redis就更加简单了,所以更多的时候可以使用Spring提供的RedisTemplate的机制来使用Redis。

2. 在Spring中使用Redis

我们知道,在没有封装情况下使用JavaAPI的缺点,需要自己编写规则把Java对象和Redis的字符串进行相互转换,而在Spring中这些问题都可以轻松处理。在Spring中使用Redis,除了需要jedis.jar外,还需要下载spring-data-redis.jar,下载网址http://mvnreposit.com/artifact/org.springframework.data/spring-data-redis。

【注意】jar包和Spring版本的兼容性问题

下载的jar包导入到工程环境中,这样就可以在使用Spring提供的RedisTemplate操作Redis了,只是在使用前,需要对Spring提供的方案进行探讨,以便更好地使用它们。在大部分情况下我们都会用到连接池,于是先用Spring配置一个JedisPoolConfig对象,这个配置相对而言比较简单。

使用Spring配置JedisPoolConfig对象:

<!-- 加载数据资源属性文件 -->  
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/> 
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>

<!-- 配置redis(单机) -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
    <!-- 最大空闲数 -->
    <property name="maxIdle" value="${redis.maxIdle}" />  
    <!-- 最大空连接数 -->
    <property name="maxTotal" value="${redis.maxActive}" />  
    <!-- 最大等待时间 -->
    <property name="maxWaitMillis" value="${redis.maxWait}" />  
    <!-- 返回连接时,检测连接是否成功 -->
    <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
</bean>

jdbc.properties文件:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
jdbc.username=root
jdbc.password=root
initialSize=0  
minActive=1   
maxActive=20  
maxIdle=20  
minIdle=1  
maxWait=60000  

redis.properties文件:

redis.host=192.168.72.13
redis.port=6379
redis.maxIdle=2000
redis.maxActive=60000
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=100000
defaultCacheExpireTime=60

这样就设置了一个连接池的配置,继续往下配置。

在使用Spring提供的RedisTemplate前,需要配置Spring提供的连接工厂,在Spring Data Redis方案中它提供了4种工厂模型。

JredisConnectionFactory

JedisConnectionFactorydis

LettuceConnectionFactory

SrpConnectionFactory

然使用哪种实现工厂都是可以的,但是要根据环境进行测试,以验证使用哪个方案的性能是最佳的。无论如何它们都是接口RedisConnectionFactory的实现类,更多的时候我们都是通过接口定义去理解它们,所以它们是具有接口适用性特性的。本节以使用最为广泛的JedisConnectionFactory为例。

例如,在Spring中配置一个JedisConnectionFactory对象,

<!-- Spring-Redis连接池管理工厂 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="${redis.host}" />
    <property name="port" value="${redis.port}" />
    <property name="timeout" value="${redis.timeout}" />
    <!-- 注入Redis连接池的配置属性 -->
    <property name="poolConfig" ref="poolConfig" />
</bean> 

  属性配置含义:

hostname,表示服务器,默认localhost,如果是本机可以不配置它

port,接口端口,默认6379

poolConfig,连接池配置对象,可以设置连接池的属性

上述操作将完成一个Redis连接工厂的配置。有了RedisConnectionFactory工厂,就可以使用RedisTemplate了。

然鹅,普通的连接方法是没有办法把Java对象直接存入Redis,此时需要将对象序列化,然后使用Redis进行存储,而取回序列化的内容后,在通过转换为Java对象,Spring模板中提供了封装方案,在它内部提供了RedisSerializer接口和实现类。

JdkSerializationRedisSerializer<T>,使用JDK的序列化器进行转化。

OxmSerializer,使用SpringO/X对象Object和XML相互转换。

StringRedisSerializer,使用字符串进行序列化。

GenericToStringSerializer,通过通用的字符串序列化进行相互转换。

使用它们就能够帮助我们把对象通过序列化存储到Redis中,也可以把Redis存储的内容转换为Java对象,为此Spring提供的RedisTemplate还有两个属性。

keySerializer----------键序列化器

valueSerializer-------值序列化器

StringRedisSerializer作为Redis的key序列化器,使用JdkSerializationRedisSerializer作为value序列化器,

配置Spring RedisTemplate:

<!-- RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。 -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory" />
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>

上述配置了一个RedisTemplate的对象,并且Spring Data Redis知道会用对应的序列化器去转换Redis的键值。

新建一个角色,使用Redis保存它的对象:

public class Role implements Serializable{
	
    private static final long serialVersionUID = 7254053730979367909L;

    private int id;
    private String roleName;
    private String note;
    
    /*此处省略setter和getter方法*/
}

因为要序列化对象,所以需要实现Serializable接口,表名它能够序列化,而serialVersionUID表示序列化的版本编号。

使用RedisTemplate保存Role对象:

/**
 * 测试:单机版的redis连接池与spring整合
 */
public class TestJedis03 {
	
	private ApplicationContext context;

	@Before
	public void init() throws Exception{
		context = new ClassPathXmlApplicationContext("/redisConfig.xml");
	}

	@Test
	public void testJedisPool() throws Exception{
		
		RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
		Role role = new Role();
		role.setId(1);
		role.setRoleName("role_name_1");
		role.setNote("role_note_1");
		
		redisTemplate.opsForValue().set("role_1", role);
		Role role1 = (Role) redisTemplate.opsForValue().get("role_1");
		System.out.println(role1.getRoleName());
	}
}

3. 简介Redis的6种数据类型

Redis是一种基于内存的数据库,并且提供一定的持久化功能,它是一种键值(key-value)数据库,使用key作为索引找到当前缓存的数据,并且返回给程序调用者。当前的Redis支持6种数据类型,它们分别是字符串(String)、列表(List)、集合(set)、哈希结构(hash)、有序集合(zset)和基数(HyperLogLog)。使用Redis编程要熟悉这6种数据类型,并且了解它们常用的命令。Redis定义的这6种数据类型是十分有用的,它除了提供简单的存储功能,还能对存储的数据进行一些计算,比如字符串可以支持浮点数的自增、自减、字符求子串,集合求交集、并集,有序集合进行排序等,所以使用它们有利于对一些不太大的数据集合进行快速计算,简化编程,同时它也比数据库要快得多,所以它们对系统性能的提升十分有意义。

(4)Redis的Java API