在许多情况下,需要在数据库操作之前和之后应用函数。一个例子是加密。数据需要在 INSERT 和 UPDATE 之前加密。它需要在 SELECT 之后解密。可以用 SORM 添加这样的钩子吗?
问问题
77 次
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 回答