如何使用Scala Slick在来自不同数据库(数据源)的表上执行leftJoin?

She*_*dam 0 scala slick slick-3.0 playframework-2.5

我有2个数据库(database1和database2)。

  • database1具有带有字段ID的table1
  • database2具有带有字段ID的table2

现在如何使用Slick执行leftJoin(如下所示)?

 SELECT tb1.`id`
 FROM `database1`.`table1` t1
 LEFT JOIN `database1`.`table2` t2 ON t1.`id`=t2.`id`
Run Code Online (Sandbox Code Playgroud)

Pau*_*ega 5

我在这里可能是错的,但是大多数现有的关系数据库都不允许您在单个操作中跨越多个数据库。但是,您上面的显示很容易通过使用来实现schema(我坚信这是您真正想要实现的目标-通过粘贴的SQL判断)。

让我们举个例子。假设我们在Slick相关代码中定义了两个表,如下所示:

  // student
  case class Student(name: String,
                     middleName: Option[String],
                     surname: String,
                     nationality: String,
                     id: Id[Student] = Id.none)

  class StudentTable(tag: Tag) extends Table[Student](tag, "STUDENT") {
    def name = column[String]("NAME")
    def middleName = column[Option[String]]("MIDDLE_NAME")
    def surname = column[String]("SURNAME")
    def nationality = column[String]("NATIONALITY")
    def id = column[Id[Student]]("ID", O.PrimaryKey, O.AutoInc)

    def * = (name, middleName, surname, nationality, id) <> (Student.tupled, Student.unapply)
  }

  lazy val StudentTable = TableQuery[StudentTable]

  // document
  case class Document(studentId: Option[Id[Student]],
                      name: String,
                      uuid: String,
                      id: Id[Document] = Id.none)

  class DocumentTable(tag: Tag) extends Table[Document](tag, "DOCUMENT") {
    def studentId = column[Option[Id[Student]]]("STUDENT_ID")
    def name = column[String]("NAME")
    def uuid = column[String]("UUID")
    def id = column[Id[Document]]("ID", O.PrimaryKey, O.AutoInc)

    def * = (studentId, name, uuid, id) <> (Document.tupled, Document.unapply)

    def student = foreignKey("fk_document_student", studentId, StudentTable)(_.id.?)
  }

  lazy val DocumentTable = TableQuery[DocumentTable]
Run Code Online (Sandbox Code Playgroud)

进行以下查询:

    DocumentTable
      .joinLeft(StudentTable).on(_.studentId === _.id)
      .filter { case(doc, student) => student.map(_.name) === "Test" }
Run Code Online (Sandbox Code Playgroud)

将生成以下SQL:

select x2."STUDENT_ID", x2."NAME", x2."UUID", x2."ID", x3."NAME", x3."MIDDLE_NAME", x3."SURNAME", x3."NATIONALITY", x3."ID" 
from "DOCUMENT" x2 
left outer join "STUDENT" x3 on x2."STUDENT_ID" = x3."ID" 
where x3."NAME" = 'Test'
Run Code Online (Sandbox Code Playgroud)

但是,如果我将表定义更改为:

class StudentTable(tag: Tag) extends Table[Student](tag, _schemaName = Option("database2"), "STUDENT") {
...
Run Code Online (Sandbox Code Playgroud)

和这个

class DocumentTable(tag: Tag) extends Table[Document](tag, _schemaName = Option("database1"), "DOCUMENT") {
...
Run Code Online (Sandbox Code Playgroud)

注意,我添加了一个参数-- _schemaName表示特定表应以指定的模式作为前缀。

我现在将生成(相同的Slick查询)以下SQL:

select x2."STUDENT_ID", x2."NAME", x2."UUID", x2."ID", x3."NAME", x3."MIDDLE_NAME", x3."SURNAME", x3."NATIONALITY", x3."ID" 
from "database1"."DOCUMENT" x2 
left outer join "database2"."STUDENT" x3 on x2."STUDENT_ID" = x3."ID" 
where x3."NAME" = 'Test' 
Run Code Online (Sandbox Code Playgroud)

这似乎正是您想要实现的目标。