Java中使用Redis Hash的3种方法


前言:

   不用说Map是Java中最流行的数结构。Redis提供了一个与Java的Map结构非常相似的数据结构,它吸引了许多Java开发者的兴趣。已经有越来越多的Java库与Redis进行对话,其中大多数都提供了与Redis哈希进行交互的方法。让我们通过使用三个最流行的Redi Java客户机JEDIS、Spring Data Redis和Redisson的例子,来比较Java中三种不同的与Redis Hash的交互方式。为了使它们易于理解和比较,每个示例都使用相同的流行二进制编解码器kryo来提供虚拟数据的序列化/反序列化。

1. Jedis

      Jedis只处理原始二进制数据,因此每次调用redis命令时都需要编码/解码逻辑。每次调用任何命令之前,还需要从实例池中获取jedis实例。


private static byte[] encode(Kryo kryo, Object obj) {
    ByteArrayOutputStream objStream = new ByteArrayOutputStream();
    Output objOutput = new Output(objStream);
    kryo.writeClassAndObject(objOutput, obj);
    objOutput.close();
    return objStream.toByteArray();
}
private static  T decode(Kryo kryo, byte[] bytes) {
   return (T) kryo.readClassAndObject(new Input(bytes));
}
public static void main(String[] args) {
    JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
    Kryo kryo = new Kryo();
    kryo.register(MyKey.class);
    kryo.register(MyValue.class);
    Jedis jedis = jedisPool.getResource();
    MyKey key = new MyKey("Jhon", "+138129129113");
    byte[] keyArray = encode(kryo, key);
    MyValue value = new MyValue("Kremlin street", "Moscow");
    byte[] valueArray = encode(kryo, value);
    byte[] name = "myMap".getBytes();
    // put
    jedis.hset(name, keyArray, valueArray);
    // get
    byte[] mappedValueArray = jedis.hget(name, keyArray);
    MyValue mappedValue = decode(kryo, mappedValueArray);
    MyValue newValue = new MyValue("Kremlin street", "Moscow");
    byte[] newValueArray = encode(kryo, newValue);
    // putIfAbsent
    jedis.hsetnx(name, keyArray, newValueArray);
    jedis.close();
    jedisPool.close();
}

2. Spring Data Redis

      Spring Data  Redis允许您通过Redisserializer接口实现自己的数据序列化程序,并在其下使用Jedis Excutor。所以需要实现kryoserializer才能使用kryo编解码器。

KryoSerializer Implementation

public static class KryoSerializer implements RedisSerializer {
    private Kryo kryo;
    public KryoSerializer(List> classes) {
        kryo = new Kryo();
        for (Class clazz : classes) {
            kryo.register(clazz);
        }
    }
    @Override
    public byte[] serialize(T t) throws SerializationException {
        ByteArrayOutputStream objStream = new ByteArrayOutputStream();
        Output objOutput = new Output(objStream);
        kryo.writeClassAndObject(objOutput, t);
        objOutput.close();
        return objStream.toByteArray();
    }
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        return (T) kryo.readClassAndObject(new Input(bytes));
    }
}

Configuration

@Configuration
@ComponentScan
public static class Application {
    @Bean
    JedisConnectionFactory connectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setUsePool(true);
        return factory;
    }
    @Bean
    RedisTemplate redisTemplate(JedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setDefaultSerializer(new KryoSerializer<>(Arrays.asList(MyKey.class, MyValue.class)));
        template.setConnectionFactory(factory);
        return template;
    }
}

Usage Example:

@Component
public static class MapBean {
    @Autowired
    private RedisTemplate redisTemplate;
    public void execute() {
        Kryo kryo = new Kryo();
        kryo.register(MyKey.class);
        kryo.register(MyValue.class);
        MyKey key = new MyKey("Jhon", "+138129129113");
        MyValue value = new MyValue("Pushkina street", "Moscow");
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("myKey", key, value);
        MyValue mappedValue = hashOperations.get("myKey", key);
        MyValue newValue = new MyValue("Tverskaya street", "Moscow");
        hashOperations.putIfAbsent("myKey", key, newValue);
    }
}
public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
    context.getBean(MapBean.class).execute();
    context.close();
}

3. Redisson

     Redisson支持许多流行的编解码器,包括Kryo。它维护集群、主/从服务器和单个Redis服务器的连接池和拓扑更新。Redisson API不仅涵盖了Redis哈希操作,还完全实现了java.util.map和java.util.concurrent.concurrent map接口。它还支持映射条目收回和映射实体的本地缓存。


public static void main(String[] args) {
    Config config = new Config();
    config.setCodec(new KryoCodec(Arrays.asList(MyKey.class, MyValue.class)))
            .useSingleServer().setAddress("127.0.0.1:6379");
    RedissonClient redisson = Redisson.create(config);
    RMap map = redisson.getMap("myMap");
    MyKey key = new MyKey("Jhon", "+138129129113");
    MyValue value = new MyValue("Broad street", "New York");
    map.put(key, value);
    MyValue mappedValue = map.get(key);
    MyValue newValue = new MyValue("Narrow street", "New York");
    map.fastPutIfAbsent(key, newValue);
    redisson.shutdown();
}

总结:

在代码简单性方面,与RediIs哈希一起使用时,Redisson是比其他Redis Java客户端更好的选择。

原文地址:https://dzone.com/articles/3-ways-to-use-redis-hash-in-java


 

你可能感兴趣的:(java,redis,Redis)