在 PlaySlick DAO 中导出 Slick table

Exporting Slick table in PlaySlick DAO

下面的代码是演示 DAO class 的 PlaySlick 示例。我将其用作示例,但我的问题是我在多个 DAO 中使用相同的 table(例如 CatTable class),并且由于 table 是一个内部 class,我不能将它导入其他 DAO,因为它不在伴随对象中。有办法解决这个问题吗?

package dao

import scala.concurrent.Future

import javax.inject.Inject
import models.Cat
import play.api.db.slick.DatabaseConfigProvider
import play.api.db.slick.HasDatabaseConfigProvider
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import slick.driver.JdbcProfile

class CatDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) 
                   extends HasDatabaseConfigProvider[JdbcProfile] {
  import driver.api._

  private val Cats = TableQuery[CatsTable]

  def all(): Future[Seq[Cat]] = db.run(Cats.result)

  def insert(cat: Cat): Future[Unit] = db.run(Cats += cat).map { _ => () }

  private class CatsTable(tag: Tag) extends Table[Cat](tag, "CAT") {

    def name = column[String]("NAME", O.PrimaryKey)
    def color = column[String]("COLOR")

    def * = (name, color) <> (Cat.tupled, Cat.unapply _)
  }
}

当然可以。我们经常使用的经典方法是:

// student course segment
  case class StudentCourseSegment(studentId: Id[Student],
                                  courseId: Id[Course],
                                  semesterId: Id[Semester],
                                  id: Id[StudentCourseSegment] = Id.none)

  class StudentCourseSegmentTable(tag: Tag) extends 
    Table[StudentCourseSegment](tag, "STUDENT_COURSE_SEGMENT") {
    def studentId = column[Id[Student]]("STUDENT_ID")
    def courseId = column[Id[Course]]("COURSE_ID")
    def semesterId = column[Id[Semester]]("SEMESTER_ID")
    def id = column[Id[StudentCourseSegment]]("ID", O.PrimaryKey, O.AutoInc)

    def * = (studentId, courseId, semesterId, id) <> (StudentCourseSegment.tupled, 
                                                      StudentCourseSegment.unapply)

    // foreign keys
    def student = foreignKey("fk_segment_student", studentId, StudentTable)(_.id)
    def course = foreignKey("fk_segment_course", courseId, CourseTable)(_.id)
    def semester = foreignKey("fk_segment_semester", semesterId, SemesterTable)(_.id)
  }

  lazy val StudentCourseSegmentTable = TableQuery[StudentCourseSegmentTable]

(我的演示文稿中的示例:http://slides.com/pdolega/slick-101#/69

所以你有(在同一级别):

  • 案例 class - 又名 解压类型(您在申请中的域)
  • table 定义 - 又名 混合类型
  • table查询对象

这个 table 的主 DAO 将使用这个定义,但其他 DAO 也会使用这个定义(例如 joins)。

我想这里的要点是:没有什么强迫你将 TableQuery(或其他提到的工件)保留为私有内部成员/classes。您可以将它们作为内部 classes、顶级 classes 保存在同一文件中或完全保存在其他地方。

还有一件事 - 与问题无关,但我在你的例子中看到了。我建议保持 DBIO 水平,就像您的 DAO classes 一样;如果您立即将所有内容转换为 Futures,您将失去可组合性(您将无法在同一事务中执行多个操作)。