Slick 3.0 最佳实践

Slick 3.0 best practices

来自 JPA 和 Hibernate,我发现除了使用一些连接和聚合查询之外,使用 Slick 非常直接。

在定义我的表和映射案例 classes 时,我可以采用一些最佳实践吗?我目前有一个 class 包含所有查询、Table 定义和查询数据库时映射到的案例 classes。这个 class 处理了 10 到 15 个表,文件变得相当大。

我现在想知道是否应该将它分成不同的包以便于阅读。大家怎么看?

您可以将灵活的映射 table 与灵活的查询分开。将光滑映射 table 放入特征中。在你想写查询的地方混合这个特征并加入 table。例如:

package com.knol.db.repo

import com.knol.db.connection.DBComponent
import scala.concurrent.Future

trait BankRepository extends BankTable { this: DBComponent =>

   import driver.api._

   def create(bank: Bank): Future[Int] = db.run { bankTableAutoInc += bank }

   def update(bank: Bank): Future[Int] = db.run { bankTableQuery.filter(_.id === bank.id.get).update(bank) }

   def getById(id: Int): Future[Option[Bank]] = db.run {   bankTableQuery.filter(_.id === id).result.headOption }

   def getAll(): Future[List[Bank]] = db.run { bankTableQuery.to[List].result }

   def delete(id: Int): Future[Int] = db.run { bankTableQuery.filter(_.id === id).delete }

 }

   private[repo] trait BankTable { this: DBComponent =>

  import driver.api._

  private[BankTable] class BankTable(tag: Tag) extends Table[Bank](tag,"bank") {
     val id = column[Int]("id", O.PrimaryKey, O.AutoInc)
      val name = column[String]("name")
      def * = (name, id.?) <> (Bank.tupled, Bank.unapply)
    }

   protected val bankTableQuery = TableQuery[BankTable]

   protected def bankTableAutoInc = bankTableQuery returning bankTableQuery.map(_.id)

   }

 case class Bank(name: String, id: Option[Int] = None)

加入两个table:

 package com.knol.db.repo

 import com.knol.db.connection.DBComponent
 import scala.concurrent.Future

 trait BankInfoRepository extends BankInfoTable { this: DBComponent =>

 import driver.api._

  def create(bankInfo: BankInfo): Future[Int] = db.run { bankTableInfoAutoInc += bankInfo }

  def update(bankInfo: BankInfo): Future[Int] = db.run { bankInfoTableQuery.filter(_.id === bankInfo.id.get).update(bankInfo) }

  def getById(id: Int): Future[Option[BankInfo]] = db.run { bankInfoTableQuery.filter(_.id === id).result.headOption }

  def getAll(): Future[List[BankInfo]] = db.run { bankInfoTableQuery.to[List].result }

 def delete(id: Int): Future[Int] = db.run { bankInfoTableQuery.filter(_.id === id).delete }

 def getBankWithInfo(): Future[List[(Bank, BankInfo)]] =
  db.run {
  (for {
    info <- bankInfoTableQuery
    bank <- info.bank
  } yield (bank, info)).to[List].result
 }


  def getAllBankWithInfo(): Future[List[(Bank, Option[BankInfo])]] =
  db.run {
  bankTableQuery.joinLeft(bankInfoTableQuery).on(_.id ===   _.bankId).to[List].result
 }
  }


 private[repo] trait BankInfoTable extends BankTable { this: DBComponent =>

 import driver.api._

private[BankInfoTable] class BankInfoTable(tag: Tag) extends Table[BankInfo](tag,"bankinfo") {
   val id = column[Int]("id", O.PrimaryKey, O.AutoInc)
   val owner = column[String]("owner")
   val bankId = column[Int]("bank_id")
   val branches = column[Int]("branches")
    def bank = foreignKey("bank_product_fk", bankId, bankTableQuery)(_.id)
    def * = (owner, branches, bankId, id.?) <> (BankInfo.tupled, BankInfo.unapply)
 }

    protected val bankInfoTableQuery = TableQuery[BankInfoTable]

    protected def bankTableInfoAutoInc = bankInfoTableQuery returning bankInfoTableQuery.map(_.id)

   }

   case class BankInfo(owner: String, branches: Int, bankId: Int, id: Option[Int] = None)

有关更多说明,请参阅 Blog and github。 可能会有帮助!!!