Spring在Spring-data-redis2.0之后取消了对Jedis的支持,取而代之的是Lettuce,Lettuce是一个基于Netty的NIO方式处理redis访问,所以我们今天就来整理使用一下Lettuce,为了学习,我们这里是不使用Spring-data-redis,使用原生的Lettuce。使用Lettuce没有什么特别注意的地方,唯一注意的地方就是他依赖于Netty,需要引入相关的Netty依赖。下面我们就来做一个例子,从配置到最终存储及获取数据整个流程,我们就拿存储对象来演示,因为默认Lettuce是不支持POJO存储的,所以我们使用Map来存储对象,之后再将返回的map转换为POJO好了我们现在上代码。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
@Configuration
public class RedisConfig {
@Bean(destroyMethod = "shutdown")
public ClientResources clientResources() {
return DefaultClientResources.create();
}
@Bean(destroyMethod = "shutdown")
public RedisClient redisClient(ClientResources clientResources) {
return RedisClient.create(clientResources, RedisURI.create("localhost", 6379));
}
@Bean(destroyMethod = "close")
public StatefulRedisConnection<String, String> connection(RedisClient redisClient) {
return redisClient.connect();
}
}
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.stream.Collectors;
import io.lettuce.core.KeyValue;
public class RedisUtil {
public static <T> T convertRedisMapToBean(List<KeyValue<String, String>> kv, Class<T> type) {
T obj = null;
try {
obj = type.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(type);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
Class<?> fieldType = descriptor.getPropertyType();
String propertyName = descriptor.getName();
List<KeyValue<String, String>> lis_item = kv.stream().filter(item -> item.getKey().equals(propertyName))
.collect(Collectors.toList());
if (lis_item.size() > 0) {
String value = lis_item.get(0).getValue();
Object[] args = new Object[1];
args[0] = getFieldTypeValue(fieldType, value);
descriptor.getWriteMethod().invoke(obj, args);
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return obj;
}
public static Object getFieldTypeValue(Class<?> classType, String value) {
String typeName = classType.getName();
switch (typeName) {
case "java.lang.Integer":
return Integer.valueOf(value);
case "java.lang.Long":
return Long.valueOf(value);
case "java.lang.Float":
return Float.valueOf(value);
case "java.lang.Double":
return Double.valueOf(value);
case "java.lang.Boolean":
return Boolean.valueOf(value);
case "java.lang.Short":
return Short.valueOf(value);
case "java.lang.String":
return value;
case "int":
return Integer.valueOf(value);
case "long":
return Long.valueOf(value);
case "float":
return Float.valueOf(value);
case "double":
return Double.valueOf(value);
case "boolean":
return Boolean.valueOf(value);
case "short":
return Short.valueOf(value);
default:
return value;
}
}
}
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.demo.netty.framework.db.entry.User;
import com.demo.netty.framework.utils.ListUtil;
import com.demo.netty.framework.utils.RedisUtil;
import io.lettuce.core.KeyValue;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import reactor.core.publisher.Mono;
@Repository
public class RedisDemoDao {
@Autowired
private StatefulRedisConnection<String, String> connection;
public String save(User user) {
String result = "success save value to redis";
try {
RedisCommands<String, String> syncCommands = connection.sync();
Map<String, String> map = new LinkedHashMap<>();
map.put("id", "1001");
map.put("userName", "2002");
map.put("detail", "This is a Mapdemo");
syncCommands.hmset("test", map);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public Mono<String> get(String key) {
RedisCommands<String, String> syncCommands = connection.sync();
List<String> lisKey = syncCommands.hkeys("test");
List<KeyValue<String, String>> aa = syncCommands.hmget("test", ListUtil.getInstance().getFromList(lisKey));
User user=RedisUtil.convertRedisMapToBean(aa, User.class);
System.out.println(user.getDetail());
return Mono.just(aa.get(0).getValue());
}
}
Lettuce中Map返回的对象类型是KeyValue他本质跟Map的操作一样。所以我们通过一个方法将其转换同时进行数据类型转换,目前演示只支持基本的类型,后续根据实际的业务也可以进行扩展。