【问题标题】:Slick 3.0 best practicesSlick 3.0 最佳实践
【发布时间】:2015-09-28 14:36:48
【问题描述】:

来自 JPA 和 Hibernate,我发现除了使用一些 Joins 和 Aggregate 查询之外,使用 Slick 非常简单。

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

我现在想知道是否应该将其拆分为不同的包以提高可读性。大家觉得呢?

【问题讨论】:

  • 我通常使用(就像我对 JPA 所做的那样)每个模型一个文件。所以每个文件都包含一个案例类定义和一个表定义。我将查询放在每个也有一个文件的 DAO 中(从 BaseDAO 继承,包含一些通用的东西,如分页、byId 等)
  • 我已经这样做了,这听起来很合乎逻辑!

标签: slick


【解决方案1】:

您可以将 slick 映射表从 slick 查询中分离出来。将光滑的映射表放入特征中。在您想要编写查询并加入表格的地方混合此特征。例如:

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)

用于连接两个表:

 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)

更多解释见Bloggithub。 可能有用!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2014-12-21
    相关资源
    最近更新 更多