`

征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

阅读更多

有日子没写博客了,真的是忙得要疯掉。 完成项目基础架构搭建工作,解决了核心技术问题,接着需要快速的调研下基于Spring框架下的Redis操作。

 

相关链接:

征服 Redis

征服 Redis + Jedis

征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

征服 Redis + Jedis + Spring (三)—— 列表操作

 

前文有述,Spring提供了对于Redis的专门支持:spring-data-redis。此外,类似的还有:


 

我想大部分人对spring-data-hadoopspring-data-mongodbspring-data-redis以及spring-data-jpa表示关注。

一、简述

spring把专门的数据操作独立封装在spring-data系列中,spring-data-redis自然是针对Redis的独立封装了。

当前版本1.0.1,主要是将jedisjredisrjc以及srpRedis Client进行了封装,同时支持事务。已经让我垂涎欲滴了。当然,当前版本不支持Sharding。例如,前文曾经通过Jedis通过Client配置,实现一致性哈希,达到Sharding的目的。再一点,如果你早在spring1.x写过SpringJdbc的话,现在会觉得似曾相识。

 

在经过一番思想斗争后,我最终放弃了Jedis原生实现,拥抱spring-data-redis了。为什么?因为,我需要一个有事务机制的框架,一个不需要显式调用对象池操作的框架。这些spring-data-redis都解决了。至于Sharding,当前数据量要求还不大,期待Redis 3.0吧。

 

二、配置

对象池配置:

 

<bean
		id="jedisPoolConfig"
		class="redis.clients.jedis.JedisPoolConfig"
	>
		<property
			name="maxActive"
			value="${redis.pool.maxActive}" />
		<property
			name="maxIdle"
			value="${redis.pool.maxIdle}" />
		<property
			name="maxWait"
			value="${redis.pool.maxWait}" />
		<property
			name="testOnBorrow"
			value="${redis.pool.testOnBorrow}" />
	</bean>

 

 

工厂实现:

 

	<bean
		id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
	>
		<property
			name="hostName"
			value="${redis.ip}" />
		<property
			name="port"
			value="${redis.port}" />
		<property
			name="poolConfig"
			ref="jedisPoolConfig" />
	</bean>

 

 

模板类:

 

<bean
		class="org.springframework.data.redis.core.RedisTemplate"
		p:connection-factory-ref="jedisConnectionFactory" />

 

 

是不是很像配置一个JdbcTemplate?其实就这么简单。

redis.properties配置如下:

 

#最大分配的对象数
redis.pool.maxActive=1024
#最大能够保持idel状态的对象数
redis.pool.maxIdle=200
#当池内没有返回对象时,最大等待时间
redis.pool.maxWait=1000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true

#IP
redis.ip=10.11.20.140
#Port
redis.port=6379

 

 

当前只能用一个节点,期待Redis 3.0,Sharding吧!

 

三、GET、SET、DEL操作

Redis初来乍练,目前也就是用Memcached多些,只会这些基本的操作,在这里献丑了!

 

假定做一个UserDao:

 

public interface UserDao {
	/**
	 * @param uid
	 * @param address
	 */
	void save(User user);

	/**
	 * @param uid
	 * @return
	 */
	User read(String uid);

	/**
	 * @param uid
	 */
	void delete(String uid);
}

 

 

User对象就这么两个属性:

 

public class User implements Serializable {

	private static final long serialVersionUID = -1267719235225203410L;

	private String uid;

	private String address;
}

 

 

实现这三个方法需要得到RedisTemplate的支持:

 

	@Autowired
	private RedisTemplate<Serializable, Serializable> redisTemplate;

 为什么用序列化泛型?我存的数据都是可序列化的内容。还有更多为什么?其实我也解答不了很多,边练边学,我弄通了一定告诉你!

 

 

1.保存-SET

 

做一个保存造作,使用RedisSET命令:

 

	@Override
	public void save(final User user) {
		redisTemplate.execute(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				connection.set(
						redisTemplate.getStringSerializer().serialize(
								"user.uid." + user.getUid()),
						redisTemplate.getStringSerializer().serialize(
								user.getAddress()));
				return null;
			}
		});
	}

 这里是通过模板类,实现方法回调。在spring框架下,可以方便的控制事务,如果你研究过spring的dao源代码,对此一定熟悉。

 

 

  1. 传入参数,需要final标识,禁止方法内修改。
  2. 调用RedisConnectionset方法实现RedisSET命令。
  3. 不管是Key,还是Value都需要进行Serialize
  4. 序列化操作,最好使用RedisTemplate提供的Serializer来完成。

 

这跟当年的SpringJdbcTemplate有那么一拼!

 

2.获取-GET

想要将对象从Redis中取出来,就麻烦一些,需要序列化key,最好判断下这个key是否存在,避免无用功。如果键值存在,需要对数据反序列化。

 

	@Override
	public User read(final String uid) {
		return redisTemplate.execute(new RedisCallback<User>() {
			@Override
			public User doInRedis(RedisConnection connection)
					throws DataAccessException {
				byte[] key = redisTemplate.getStringSerializer().serialize(
						"user.uid." + uid);
				if (connection.exists(key)) {
					byte[] value = connection.get(key);
					String address = redisTemplate.getStringSerializer()
							.deserialize(value);
					User user = new User();
					user.setAddress(address);
					user.setUid(uid);
					return user;
				}
				return null;
			}
		});
	}

 当年写SpringJdbc的时候,就是这样一个字段一个字段拼装的,甭提多累人。好吧,用Spring-Data-Redis,又让我回归了!

 

 

  1. 记得使用泛型,如RedisCallback<User>()
  2. 使用同一的序列化/反序列化Serializer
  3. 建议使用connection.exists(key)判别键值是否存在,避免无用功

 

3.删除-DEL

删除,就简单点,不过也需要这样折腾一会:

 

	@Override
	public void delete(final String uid) {
		redisTemplate.execute(new RedisCallback<Object>() {
			public Object doInRedis(RedisConnection connection) {
				connection.del(redisTemplate.getStringSerializer().serialize(
						"user.uid." + uid));
				return null;
			}
		});
	}

 

做个TestCase,暂时够我用了!

 

4. TestCase

 

 

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.zlex.redis.dao.UserDao;
import org.zlex.redis.domain.User;

public class UserDaoTest {
	private ApplicationContext app;
	private UserDao userDao;

	@Before
	public void before() throws Exception {
		app = new ClassPathXmlApplicationContext("applicationContext.xml");
		userDao = (UserDao) app.getBean("userDao");
	}

	@Test
	public void crud() {
		// -------------- Create ---------------
		String uid = "u123456";
		String address1 = "上海";
		User user = new User();
		user.setAddress(address1);
		user.setUid(uid);
		userDao.save(user);

		// ---------------Read ---------------
		user = userDao.read(uid);

		assertEquals(address1, user.getAddress());

		// --------------Update ------------
		String address2 = "北京";
		user.setAddress(address2);
		userDao.save(user);

		user = userDao.read(uid);

		assertEquals(address2, user.getAddress());

		// --------------Delete ------------
		userDao.delete(uid);
		user = userDao.read(uid);
		assertNull(user);
	}
}

 貌似少了update,也许以后操作Hash时,会用上。

 

看看控制台获得了什么: 

 

redis 127.0.0.1:6379> get user.uid.u123456
(nil)
redis 127.0.0.1:6379> get user.uid.u123456
"\xe5\x8c\x97\xe4\xba\xac"
redis 127.0.0.1:6379> get user.uid.u123456
"\xe4\xb8\x8a\xe6\xb5\xb7"
redis 127.0.0.1:6379> del user.uid.u123456
(integer) 1
redis 127.0.0.1:6379> get user.uid.u123456
(nil)
redis 127.0.0.1:6379> get user.uid.u123456
"\xe4\xb8\x8a\xe6\xb5\xb7"

 好吧,可以开始用它来存点什么了!

 

相关链接:

征服 Redis

征服 Redis + Jedis

征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

征服 Redis + Jedis + Spring (三)—— 列表操作

  • 大小: 87.7 KB
22
3
分享到:
评论
7 楼 string2020 2014-12-29  
spring封装之后,怎么搞复杂了?
6 楼 opentan 2014-10-20  
请问spring jedis sharding怎么配置?
5 楼 dbh0512 2013-08-16  
这样操作只是在缓存中读取吗?
项目中是不是只有在海量频繁读取某一组数据时使用jedis才最合适?
真正持久化数据到数据库jedis 合适吗?
4 楼 sxchen0603 2013-06-20  
序列化、反序列化都要耗时吧,而且在取值之前做是否存在判断,也会增加对redis的访问次数。
3 楼 yhc13429826359 2013-01-04  
楼主,现在有更新吗,期待楼主更新....
2 楼 oaoist 2012-12-29  
为什么把testOnReturn去掉了?
1 楼 HeartArea 2012-12-15  
值得借鉴一下

相关推荐

    jedis操作redis工具类,使用该工具类无需配置spring

    1. **连接Redis**:`Jedis getJedis()` - 这个方法负责建立到Redis服务器的连接,可能包括设置连接池、配置连接参数等。 2. **关闭连接**:`void closeJedis(Jedis jedis)` - 在操作完成后,调用此方法关闭连接,...

    redis常用命令以及在java中的具体实现以及配置.docx

    在实际项目中,根据需求的不同,还可以选择使用 Jedis 或者 Spring Data Redis 来进行更加灵活的操作。同时,正确的配置也是保证应用正常运行的关键。希望本文能帮助开发者更好地理解和使用 Redis。

    redis utils 工具类

    RedisUtils工具类应包含一系列用于执行基本Redis操作的方法,如`set(String key, String value)`、`get(String key)`、`exists(String key)`、`del(String key)`等。这些方法封装了Jedis实例的操作,使得在业务代码...

    redis缓存实例

    // 其他如set、get、del等操作方法 } ``` - 使用`jedisUtils`工具类可以避免频繁创建和关闭Jedis对象,提高代码的可读性和效率。 3. **Redis可视化工具** - **Windows客户端**: Redis提供了一个名为`Redis ...

    redis-redis.zip

    - **基本操作**:如`jedis.set("key", "value")`设置键值,`jedis.get("key")`获取值,`jedis.del("key")`删除键。 - **事务操作**:`jedis.multi()`开始事务,`jedis.exec()`提交事务。 3. **Lettuce使用**: -...

    Redis安装部署与Java调用.zip

    Redis是一款高性能的键值对数据库,常用于缓存和数据持久化。...在实际开发中,还可以结合Spring Data Redis等框架进一步简化操作。了解这些基本知识后,你可以根据业务需求进行更复杂的数据结构使用和性能优化。

    java与redis学习例子

    Redis支持多种命令,如`SET`、`GET`、`DEL`、`PUSH`、`POP`、`SORT`等,用于操作字符串、哈希、列表、集合和有序集合等数据结构。通过编写测试脚本,你可以熟悉这些命令的用法,并理解它们在实际应用中的作用。 3....

    redis jar包

    2. 数据操作:使用`set`方法存储键值对,`get`方法获取键对应的值,`del`方法删除键,`keys`方法查找所有键。 3. 高级操作:利用Jedis支持的哈希(`hset`、`hget`等)、列表(`lpush`、`rpop`等)、集合(`sadd`、`...

    Redis 缓存代码

    3. **基本操作**:Redis支持的操作包括SET(设置键值)、GET(获取键值)、DEL(删除键)、EXPIRE(设置过期时间)等。在Java代码中,你可以通过Jedis实例调用对应的方法实现这些操作。 4. **数据类型**:Redis支持...

    ssm框架整合redis实现缓存

    这里可以定义如`get`、`set`、`del`等基本操作,以及`expire`来设置过期时间等方法。 4. **整合Spring Cache**:如果使用Spring Cache,可以在配置中开启Redis作为缓存提供者,并指定注解如`@Cacheable`、`@...

    redis缓存技术入门

    Jedis是更常见的一种选择,它提供了丰富的API来操作Redis服务器。首先,你需要在项目中引入Jedis的依赖,然后配置Redis服务器的连接参数,如主机名、端口号、密码等。以下是一个简单的Jedis连接示例: ```java ...

    redis中demo文档

    - **配置文件**: 创建`applicationContext_jedis.xml`用于配置Redis连接信息。 - **业务逻辑修改**: - 修改`EmpBiz`类,集成Jedis客户端进行缓存操作。 - 更新`applicationContext_biz.xml`,注入Jedis实例到`...

    在java中操作redis博客源码

    - **基本操作**:例如设置键值`set(key, value)`,获取键值`get(key)`,删除键`del(key)`等。 - **数据类型操作**:Jedis支持对字符串、哈希、列表、集合、有序集合的操作,如`hset(hashKey, field, value)`(哈希...

    redis应用案例_缓存歌曲最新评论.zip

    例如,Jedis是官方推荐的Java客户端,提供了一系列API用于执行Redis命令。以下是一些基本操作示例: ```java Jedis jedis = new Jedis("localhost"); // 设置键值对 jedis.set("song:comments:last", "最新评论内容...

    Redis命令.docx

    Redis 的事务机制允许一系列的操作组合在一起作为一个单独的命令执行,从而提高数据处理的安全性。事务的基本步骤包括: 1. **MULTI**:标记一个事务块的开始。 2. **EXEC**:执行所有事务块内的命令。 3. **...

    SpringBoot整合Redis、mybatis实战,封装RedisUtils工具类.docx

    如上所述,引入`spring-boot-starter-data-redis`是为了实现SpringBoot与Redis的集成,这个依赖包含了连接Redis所需的组件,如`Lettuce`或`Jedis`客户端。同时,为了整合MyBatis,我们需要引入`mybatis-spring-boot-...

    java基于redis 全栈开发.rar

    在本项目"java基于redis 全栈开发"中,我们将探讨如何使用Java语言与Redis数据库进行集成,构建一个全栈应用程序。Redis是一个高性能的键值数据存储系统,常用于缓存、消息队列以及多种数据结构服务。Java作为广泛...

    SSM框架详解6

    以下是一个简单的示例代码,用于演示如何使用Jedis连接Redis并执行基本的CRUD操作: ```java import redis.clients.jedis.Jedis; public class RedisExample { public static void main(String[] args) { // ...

    Redis详细使用说明书

    客户端提供了各种命令,如set和get用于设置和获取键值对,sadd用于添加元素到集合中,hset用于设置哈希表中的字段,keys用于获取符合特定模式的所有键,del用于删除指定的键,exists用于检查键是否存在等。...

    javaredis源码-jredis-master:java实现redis

    jedis,spring-data-redis,spring-boot-starter-redis support redisDesktop management tool with v0.9+ 建筑学 RAM中仅使用键,该值是延迟加载 逐出政策 LRU algorithm 线性存储 1.based on jdk's MappedByteBuffer...

Global site tag (gtag.js) - Google Analytics