如何将自定义数据类设为 StatefulRedisConnection 值类型?

问题描述 投票:0回答:1

Lettuce Core API 有包含以下方法的 RedisClient 类:

public StatefulRedisConnection<String, String> connect() {
      return this.connect(this.newStringStringCodec());
}

public <K, V> StatefulRedisConnection<K, V> connect(RedisCodec<K, V> codec) {
      this.checkForRedisURI();
      return (StatefulRedisConnection)this.getConnection(this.connectStandaloneAsync(codec, this.redisURI, this.timeout));
}

我想调用方法

connect(RedisCodec<K, V> codec)
,但我不知道如何配置我的编解码器对象,我应该将其作为参数传递给该方法。

我当前的代码:

val redisClient = RedisClient.create("redis://password@localhost:6379/0");
val connection = redisClient.connect();
// in this case type of connection is StatefulRedisConnection<String, String>
val redisCommands = connection.sync()

我还有我的自定义数据类。

data class MyCustomDataClassName {
  val id: UUID,
  val something: String,
  val foo: String,
  val bar: String
}

我想写这段代码:

val redisClient = RedisClient.create("redis://password@localhost:6379/0");
val codec = /* should be something that returns object of type StatefulRedisConnection<String, MyCustomDataClassName>*/
val connection = redisClient.connect(codec);
val redisCommands = connection.sync()
java kotlin redis lettuce
1个回答
0
投票

这是 Kotlin with Lettuce + Redis 的摘录。我用框架 Ktor 对此进行了测试。

  1. 直接操作自定义类需要结合 RedisCodec 设置序列化器。
  2. 请注意传递到连接的自定义 ModelCodec。
  3. 这是一个非常具体的示例,您可以使其更通用,或者也为其他类型添加多个 RedisCodec。
@Serializable
data class MyCustomDataClassName(
    val id: UUID,
    val something: String,
    val foo: String,
    val bar: String
)

object RedisCache {  

    private val client: RedisClient
    private val connection: StatefulRedisConnection<String, MyCustomDataClassName>
    private val commands: RedisCommands<String, MyCustomDataClassName>

    val redisKey = "key:1"

    init {
        val redisUri = RedisURI.Builder.redis("localhost", 6379).build()
        client = RedisClient.create(redisUri)
        connection = client.connect(ModelCodec())
        commands = connection.sync()
        // Established connection to Redis
    }

    fun set(key: String, value: MyCustomDataClassName) {
        val result = commands.set(key, value)
    }

    fun get(key: String): MyCustomDataClassName {
        return commands.get(key)
    }

}


internal class ModelCodec : RedisCodec<String, MyCustomDataClassName> {
   private val charset: Charset = Charset.forName("UTF-8")

   override fun decodeKey(bytes: ByteBuffer): String {
       return charset.decode(bytes).toString()
   }

   override fun decodeValue(bytes: ByteBuffer): MyCustomDataClassName? {
       try {
           val jsonString = charset.decode(bytes).toString()
           return Json.decodeFromString(jsonString)
       } catch (e: Exception) {
           return null
       }
   }

   override fun encodeKey(key: String): ByteBuffer {
       return charset.encode(key)
   }

   override fun encodeValue(value: MyCustomDataClassName): ByteBuffer? {
       try {

           val jsonString = Json.encodeToString(MyCustomDataClassName.serializer(), value)
           return ByteBuffer.wrap(jsonString.toByteArray(charset))
       } catch (e: IOException) {
           e.printStackTrace()
           return null
       }
   }
}

© www.soinside.com 2019 - 2024. All rights reserved.