前言
本节主要论述如何在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种数据类型是十分有用的,它除了提供简单的存储功能,还能对存储的数据进行一些计算,比如字符串可以支持浮点数的自增、自减、字符求子串,集合求交集、并集,有序集合进行排序等,所以使用它们有利于对一些不太大的数据集合进行快速计算,简化编程,同时它也比数据库要快得多,所以它们对系统性能的提升十分有意义。