1

在许多情况下,需要在数据库操作之前和之后应用函数。一个例子是加密。数据需要在 INSERT 和 UPDATE 之前加密。它需要在 SELECT 之后解密。可以用 SORM 添加这样的钩子吗?

4

1 回答 1

1

好吧,理论上你可以通过简单地覆盖它的方法来连接 SORM,如下所示:

case class Thing( normalField : String, encryptedField : String )

object Db extends Instance (...) {

  override def save
    [ T <: AnyRef : TypeTag ]
    ( value : T )
    : T with Persisted
    = value match {
        case value : Thing => 
          super.save(value.copy(encryptedField = encrypt(value.encryptedField)))
        case _ => super.save(value)
      }

}

但是 SORM 0.3.* 并不是为这样的自定义而设计的,并且连接到查询功能将需要更多的努力和样板。我很不确定 SORM 是否关心这样的问题,因为你有一个相当令人困惑的案例。

无论如何,您还有其他方法可以在应用程序方面解决您的问题。这是一对直截了当的头脑:

1. 经典的 DAO 方法:

object Dao {
  def saveA( a : Thing ) = 
    Db.save(a.copy(encryptedField = encrypt(a.encryptedField)))
  def fetchAByNormalField( a : String ) = 
    Db.query[Thing].whereEqual("normalField", a).fetch()
      .map(a => a.copy(encryptedField = decrypt(a.encryptedField)))
}

这里的缺点是 SORM 的 API 非常简单,以至于在其上创建 DAO 主要只引入了冗余的抽象和样板。

2. 转换器方法:

case class Thing( normalField : String, decryptedField : String ){
  def encrypted = EncryptedThing( normalField, encrypt(decryptedField) )
}
case class EncryptedThing( normalField : String, encryptedField : String ){
  def decrypted = Thing( normalField, decrypt(encryptedField) )
}

请注意,您应该使用 SORM 注册 EncyptedThing,而不是 Thing:

object Db extends Instance( entities = Set(Entity[EncyptedThing]() ) )

你可以像这样使用它:

val thing = Thing(...)
Db.save(thing.encrypted)

val thing = Db.query[EncryptedThing].fetch().map(_.decrypted)

如果你不小心忘记触发转换,SORM 会冲你咆哮,因为你试图保存一个未注册的类型的值。应该注意的是,吠叫将在运行时进行。

于 2013-03-12T14:29:41.017 回答