前言
最近在复习自己的技术社区的源码时候发现了一个之前自己忽略的一个有趣的地方:
就是在项目的Redis操作封装类RedisClient中(包含封装了redis的几种数据结构的使用姿势)对于redisTemplate.execute() 方法与 template.opsForValue() 的选择。
这里贴上代码:
/**
* 查询缓存
*
* @param key
* @return
*/
public static String getStr(String key) {
return template.execute((RedisCallback<String>) con -> {
byte[] val = con.get(keyBytes(key));
return val == null ? null : new String(val);
});
}
/**
* 设置缓存
*
* @param key
* @param value
*/
public static void setStr(String key, String value) {
template.execute((RedisCallback<Void>) con -> {
con.set(keyBytes(key), valBytes(value));
return null;
});
}
/**
* 删除缓存
*
* @param key
*/
public static void del(String key) {
template.execute((RedisCallback<Long>) con -> con.del(keyBytes(key)));
}
/**
* 设置缓存有效期
*
* @param key
* @param expire 有效期,s为单位
*/
public static void expire(String key, Long expire) {
template.execute((RedisCallback<Void>) connection -> {
connection.expire(keyBytes(key), expire);
return null;
});
}
/**
* 带过期时间的缓存写入
*
* @param key
* @param value
* @param expire s为单位
* @return
*/
public static Boolean setStrWithExpire(String key, String value, Long expire) {
return template.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
return redisConnection.setEx(keyBytes(key), expire, valBytes(value));
}
});
}
在使用 Spring Framework 中的 RedisTemplate 来与 Redis 数据库进行交互时,我们通常可以选择使用 execute()
方法或 opsForValue()
方法来执行 Redis 命令。所以趁着这个机会学习一下这两种方法的区别、优缺点以及在实际开发中的选择。
RedisTemplate.execute() 方法
execute()
方法是 RedisTemplate 类提供的一个通用方法,用于执行 Redis 命令。通过 execute()
方法,我们可以执行任何类型的 Redis 命令,而不仅仅局限于字符串类型操作。具体来说,我们可以传入不同的 RedisCallback 或 SessionCallback 来执行不同的 Redis 命令,从而实现更灵活的操作。
优点:
- 灵活性:
execute()
方法提供了更广泛的灵活性,可以执行任何类型的 Redis 命令,满足各种复杂的需求。 - 性能优化: 在某些场景下,直接使用
execute()
方法可能比使用封装好的方法更高效,因为它减少了额外的封装和开销。
RedisTemplate.opsForValue() 方法
opsForValue()
方法是 RedisTemplate 类提供的一种便捷方法,用于执行与字符串类型相关的 Redis 命令,如设置和获取值。通过 opsForValue()
方法,我们可以获取一个 ValueOperations 对象,从而执行针对字符串类型值的操作,如设置、获取、删除等。
优点:
- 简洁易用:
opsForValue()
方法提供了一种简洁易用的方式来执行字符串类型相关的操作,无需手动构造 Redis 命令。 - 类型安全: ValueOperations 对象提供了一组类型安全的方法来执行字符串类型操作,减少了出错的可能性。
那么为什么项目选择直接使用 execute 方法而不是 opsForValue 呢?
灵活性: execute 方法提供了更广泛的灵活性,可以执行任何类型的 Redis 命令,而不仅仅局限于字符串操作。这意味着开发者可以根据实际需求执行各种复杂的 Redis 命令,而不受 opsForValue 提供的方法的限制。
性能优化: 在一些特定场景下,直接使用 execute 方法可能会比使用 opsForValue 更高效。因为 opsForValue 提供了一种封装,可能会引入额外的开销。而直接使用 execute 方法可以直接执行 Redis 命令,减少了额外的封装和开销。
习惯或个人偏好: 有些开发者可能更习惯于直接使用底层的 Redis 命令,而不使用封装好的方法。这种情况下,他们更倾向于直接使用 execute 方法。
综上所述,虽然 opsForValue 提供了一种方便的方式来执行字符串类型相关的操作,但在一些特定情况下,开发者可能会选择直接使用 execute 方法,以获得更大的灵活性和性能优化。