Scala 使用封闭数据库会话初始化特征

Scala 使用封闭数据库会话初始化特征,scala,session,initialization,slick,Scala,Session,Initialization,Slick,我们有几个traits/classes/case类和VAL,它们是使用数据库会话初始化的(我们在MySql上使用,所以下面所有的会话都有类型scala.slick.session.session)。初始化trait的方法已经有一个开放的数据库会话,因此我希望能够将它传递到trait中,以便在初始化时使用;但是,一旦trait初始化,会话将自动关闭,因此我不希望trait保留对已关闭会话的引用,以消除我们意外尝试使用它的可能性 trait MyTrait { private def initF

我们有几个traits/classes/case类和VAL,它们是使用数据库会话初始化的(我们在MySql上使用,所以下面所有的
会话都有类型
scala.slick.session.session
)。初始化trait的方法已经有一个开放的数据库会话,因此我希望能够将它传递到trait中,以便在初始化时使用;但是,一旦trait初始化,会话将自动关闭,因此我不希望trait保留对已关闭会话的引用,以消除我们意外尝试使用它的可能性

trait MyTrait {
  private def initField1(implicit session: Session) = // init code
  val field1 = db withSession { implicit sesssion: Session => initField1 }
}

def initMyTrait(implicit session: Session) = new MyTrait {}
这就是我的代码当前的样子-我找不到一个好方法将
initMyTrait
的会话传递到
MyTrait
,因此我需要打开第二个会话来初始化
MyTrait.field1
。我可以做类似的事情

trait MyTrait {
  private val _session: Session

  private def initField1(implicit session: Session) = // init code
  val field1 = initField1(_session)
}

def initMyTrait(implicit session: Session) = new MyTrait { private val _session = session }

但这将在初始化后在
MyTrait
中留下一个关闭的会话

我会尽量避免需要数据库连接来初始化trait。另一种方法是使用缓存方法代替val,例如

private var field1Cache: ... = null
def field1(implicit session:Session) = {
  if( field1Cache == null ){
    field1Cache = initField1
  }
  field1Cache
}
或者你可以把trait变成一个类,然后进行一个私人的论证