You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Scala-cache API将对象集合存储至Memcache?

使用Scala-cache + Memcached存储自定义Person对象集合的完整实现

首先先确认你已经配置的依赖是没问题的:

libraryDependencies += "com.github.cb372" %% "scalacache-memcached" % "0.24.0"

你已经尝试为Person类实现Codec,但看起来只写了部分encode方法。要顺利存储和读取自定义对象(包括集合),我们需要完整实现Codec的encode和decode逻辑,或者直接用现成的序列化库来简化操作。下面给你两种可行的方案:

方案一:手动实现基于分隔符的Codec(简单直观)

这种方式适合字段内容不会包含特殊分隔符的场景,实现起来很直接:

1. 完善Person类的Codec实现

import scalacache.Codec

final case class Person(id: Int, name: String, company: String)

// 为单个Person实例实现Codec
implicit val personCodec: Codec[Person] = new Codec[Person] {
  // 把Person的字段用|拼接成字符串,再转成字节数组
  override def encode(value: Person): Array[Byte] = {
    s"${value.id}|${value.name}|${value.company}".getBytes("UTF-8")
  }

  // 把字节数组转成字符串,拆分后还原成Person对象
  override def decode(bytes: Array[Byte]): Person = {
    // 用split("\\|", 3)确保company字段里如果有|也不会被拆分
    val parts = new String(bytes, "UTF-8").split("\\|", 3)
    Person(parts(0).toInt, parts(1), parts(2))
  }
}

2. 实现List[Person]的Codec

要存储集合,我们需要为List[Person]也实现Codec,基于上面的单个Person的Codec来扩展:

implicit val personListCodec: Codec[List[Person]] = new Codec[List[Person]] {
  // 选一个不会出现在Person字段里的分隔符,比如;;;
  private val itemSeparator = ";;;"

  override def encode(value: List[Person]): Array[Byte] = {
    // 先把每个Person转成字节数组再转成字符串,然后用分隔符拼接
    value.map(personCodec.encode)
         .map(new String(_, "UTF-8"))
         .mkString(itemSeparator)
         .getBytes("UTF-8")
  }

  override def decode(bytes: Array[Byte]): List[Person] = {
    new String(bytes, "UTF-8")
      .split(itemSeparator)
      .filter(_.nonEmpty) // 过滤空字符串,避免解析出错
      .map(str => personCodec.decode(str.getBytes("UTF-8")))
      .toList
  }
}

3. 完整的存储/读取示例

import scalacache.memcached.MemcachedCache
import scalacache.modes.sync._

// 初始化本地Memcached缓存(假设你的Memcached运行在11211端口)
val cache = MemcachedCache("localhost:11211")

// 准备要存储的Person集合
val engineeringTeam = List(
  Person(1, "Alice", "Tech Corp"),
  Person(2, "Bob", "Design Studio"),
  Person(3, "Charlie", "Startup Inc")
)

// 存入缓存,设置过期时间(可选,比如1小时)
cache.put("engineering-team", ttl = Some(scalacache.ttl.Hours(1)))(engineeringTeam)

// 从缓存读取
val retrievedTeam = cache.get("engineering-team")
retrievedTeam.foreach(team => println(s"从缓存获取到团队:$team"))

方案二:用Jackson实现JSON序列化(更健壮)

如果你的Person字段可能包含特殊字符,或者需要更通用的序列化方式,推荐用Scala-cache提供的Jackson集成,这样不需要手动写Codec:

1. 添加Jackson依赖

libraryDependencies += "com.github.cb372" %% "scalacache-jackson" % "0.24.0"

2. 自动生成Codec

Jackson会自动为case class生成序列化/反序列化逻辑,集合类型也能自动支持:

import scalacache.Codec
import scalacache.jackson.JacksonCodec

final case class Person(id: Int, name: String, company: String)

// 自动生成Person的Codec
implicit val personCodec: Codec[Person] = JacksonCodec[Person]
// 自动生成List[Person]的Codec
implicit val personListCodec: Codec[List[Person]] = JacksonCodec[List[Person]]

3. 存储/读取示例和方案一完全一样

直接用上面的缓存初始化、存取值代码即可,这种方式更省心,也能处理复杂字段的情况。

内容的提问来源于stack exchange,提问作者Puneeth Reddy V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:08:20