使用Couchbase作为Slick的缓存 [英] Using Couchbase as cache over Slick

查看:69
本文介绍了使用Couchbase作为Slick的缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Couchbase用作使用Slick访问的关系数据库的缓存层.与该问题相关的我的代码框架如下:

I'm trying to use Couchbase as a cache layer for a relational database that is accessed using Slick. The skeleton of my code that's relevant to the question is as follows:

class RdbTable[T <: Table[_]](implicit val bucket: CouchbaseBucket) {
  type ElementType = T#TableElementType
  private val table = TableQuery[T].baseTableRow

  private def cacheAll(implicit session: Session) =
    TableQuery[T].list foreach (elem => cache(elem))

  private def cache(elem: ElementType) =
    table.primaryKeys foreach (pk => bucket.set[ElementType](key(pk, elem), elem))

  private def key(pk: PrimaryKey, elem: ElementType) = ???
  .......
}

如您所见,我想通过其所有主键来缓存每个元素.为此,我需要为给定元素获取该键的值.但是我没有一种明显的方法可以计算主键的值(如果是单列键,则为列值;如果是多列,则为元组值).

As you can see, I want to cache each element by all of its primary keys. For this purpose, I need to obtain the value of that key for the given element. But I don't see an obvious way to compute the value of a primary key (the column value, if single-column key; the tuple value, if multi-column).

关于做什么的任何建议?请注意,代码务必不知道实际的表及其列是什么.它必须是完全通用的.

Any suggestions on what to do? Note that the code MUST NOT know what the actual tables and their columns are. It must be completely general.

推荐答案

我们正在做类似的事情,使用Redis作为缓存.我们的每个记录只有一个主键,但是在某些情况下,我们需要在缓存键中包含其他数据以避免歧义(例如,我们有一个ManyToMany记录,它表示两个记录之间的关联;当我们返回ManyToMany记录时我们将嵌入其中一个(但不是两个)关联记录,因此在缓存键中,我们需要包含要返回的关联记录的类型.

We're doing something similar, using Redis as the cache. Each of our records only has one primary key, but in some cases we need to include additional data with the cache key to avoid ambiguity (for example, we have a ManyToMany record that represents an association between two records; when we return a ManyToMany record we'll embed one (but not both) of the associated records, and so in the cache key we need to include the type of the associated record that we're returning).

abstract trait Record {
  val cacheKey: CacheKey
}

trait ManyToManyRecord extends Record {
  override val cacheKey: ManyToManyCacheKey
}

class CacheKey(recordType: String, key: Int) {
  def getKey: String = recordType + ":" + key.toString
}

class ManyToManyCacheKey(recordType: String, key: Int, assocType: String) extends CacheKey {
  def getKey: String = recordType + ":" + key.toString + ":" + assocType
}

我们所有的表都使用一个称为"id"的整数主键,因此我们很容易弄清楚"key"的值是什么.如果您使用的是更复杂的架构,并且不想为所有记录/表类型手动写出"def key:String"(或其他)定义,则可以尝试使用

All of our tables use an integer primary key called "id", so it's easy for us to figure out what the value of "key" is. If you're working with a more complicated schema and don't want to manually write out the "def key: String" (or whatever) definitions for all of your record / table types, then you could try using Slick code generation to automatically generate record / table classes / objects with "def key" created directly from the schema. However, the learning curve for Slick code generation (or any other code generation tool) is steep, so if this is your only use for it then you'd probably be better off generating "def key" by hand. (We generate somewhere between 20-30% of our code using the code generation tool, so the initial investment in learning how to use the tool has paid off)

这篇关于使用Couchbase作为Slick的缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆