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) )
}

モノではなく、EncryptedThing を SORM に登録する必要があることに注意してください。

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 に答える