scala-cass generic 从 cassandra 读取 table as case class

scala-cass generic read from cassandra table as case class

我正在尝试使用 scala-cass 从 cassandra 读取结果集并使用 resultSet.as[CaseClass] 将结果集转换为案例 class。这在 运行 以下时非常有效。

import com.weather.scalacass.syntax._    
case class TestTable(id: String, data1: Int, data2: Long)
val resultSet = session.execute(s"select * from test.testTable limit 10")
resultSet.one.as[TestTable]

现在我试图使它更通用,但我无法为通用 class.

找到合适的类型约束
import com.weather.scalacass.syntax._    
case class TestTable(id: String, data1: Int, data2: Long)

abstract class GenericReader[T] {
  val table: String
  val keyspace: String

  def getRows(session: Session): T = {
    val resultSet = session.execute(s"select * from $keyspace.$table limit 10")
    resultSet.one.as[T]
  }
}

我使用所需的案例 class 实现此 class 并尝试在创建的对象上调用 getRows。

object TestTable extends GenericReader[TestTable] {
  val keyspace = "test"
  val table = "TestTable"
}

TestTable.getRows(session)

这会引发异常 could not find implicit value for parameter ccd: com.weather.scalacass.CCCassFormatDecoder[T]

我正在尝试向 GenericReader 添加类型约束以确保隐式转换有效。但是,我找不到合适的类型。我正在尝试通读 scala-cass 以找到合适的约束,但到目前为止我运气不好。

我也很乐意使用任何其他可以实现此目的的库。

与其尝试绑定通用 T 类型,不如直接传递缺少的隐式参数可能更容易:

abstract class GenericReader[T](implicit ccd: CCCassFormatDecoder[T]) {
  val table: String
  val keyspace: String

  def getRows(session: Session): T = {
    val resultSet = session.execute(s"select * from $keyspace.$table limit 10")
    resultSet.one.as[T]
  }
}

当您将 T 缩小到特定的 class(如 object TestTable extends GenericReader[TestTable]

时,可以推迟为该隐式找到具体值

看起来 as[T] 需要一个您在范围内没有的隐式值,因此您也需要在 getRows 方法中要求该隐式参数。

def getRows(session: Session)(implicit cfd: CCCassFormatDecoder[T]): T

您可以使用 context bounds:

将其表达为类型约束(您在原始问题中寻找的内容)
abstract class GenericReader[T:CCCassFormatDecoder]