开发者社区 问答 正文

如何在不加入联接的情况下使用相关表以光滑的方式获取数据?

我正在使用scala,mysql,slick和quill。

这是我的一对多表。(1名员工拥有很多资产)

Employee Table +-------------+-------+--------+ | employee_id | name | salary | +-------------+-------+--------+ | 1 | A | 50 | | 2 | B | 42 | | 5 | C | 28 | | 8 | D | 61 | +-------------+-------+--------+

Asset Table +----------+----------+-------------+ | asset_id | name | employee_id | +----------+----------+-------------+ | 1 | mouse | 1 | | 2 | keyboard | 1 | | 3 | monitor | 1 | | 5 | keyboard | 2 | | 6 | mouse | 5 | | 8 | mouse | 8 | +----------+----------+-------------+ 这是我上表的羽毛笔案例类。

case class Employee(employee_id: Int, name: String, salary: Int) case class Asset(asset_id: Int, name: String, employee_id: Int) 这是用于查看所有员工的查询生成方法。

def viewAll: Future[List[Employee]] ={ val viewAllEmployees = quote{ query[Employee] }

val result = ctx.run(viewAllEmployees) result } 这是调用上述函数的主要方法。

val result = viewAllEmployees result.onComplete{ case result => printList(result.get) } 在其中,我可以获取员工对象的列表,但是我想将员工对象与相关资产对象一起使用。使用联接查询,我可以做到这一点,但是我想要没有联接的结果。我正在寻找带有鹅毛笔和光滑笔迹的答案。

展开
收起
保持可爱mmm 2019-11-15 13:56:09 291 分享 版权
阿里云 AI 助理回答

在Slick和Quill中,处理一对多关系时,通常推荐使用JOIN查询来获取关联数据。但是,如果你希望避免直接使用JOIN操作并仍然能够将员工与其资产关联起来,你可以通过以下方法实现:

使用Slick

在Slick中,你可以先执行两个独立的查询(一个用于员工,一个用于资产),然后在Scala层面手动关联这些数据。这通常涉及使用Scala集合操作,如groupBy或映射结构来关联两个列表。

import slick.jdbc.MySQLProfile.api._

// 假设你已经有了EmployeeTable和AssetTable的对象定义以及DB访问的setup

def fetchEmployeesAndAssets: Future[(List[Employee], List[Asset])] = {
  val employeesFuture = EmployeeTable.query.result
  val assetsFuture = AssetTable.query.result
  
  for {
    employees <- employeesFuture
    assets <- assetsFuture
  } yield (employees, assets)
}

fetchEmployeesAndAssets.map { case (employees, assets) =>
  // 在Scala层面关联数据
  val employeeWithAssets = employees.map { employee =>
    val employeeAssets = assets.filter(_.employee_id == employee.employee_id)
    (employee, employeeAssets)
  }
  // 现在你有了每个员工及其相关资产的列表
}

使用Quill

Quill提供了更灵活的方式来处理关联数据,尽管它也鼓励使用JOIN。但你依然可以通过分步查询并在Scala层做关联来避免直接JOIN。

首先,你需要为Employee和Asset定义Quill的查询DSL上下文。

import io.getquill._
import scala.concurrent.ExecutionContext.Implicits.global

case class Employee(employee_id: Int, name: String, salary: Int)
case class Asset(asset_id: Int, name: String, employee_id: Int)

val ctx = new MirrorContext(MirrorSqlDialect, SnakeCase) with ExtendedDsl
import ctx._

val queryEmployees = quote { query[Employee] }
val queryAssets = quote { query[Asset] }

def fetchEmployeesAndAssets: Future[(List[Employee], List[Asset])] = {
  val employeesFuture = ctx.run(queryEmployees)
  val assetsFuture = ctx.run(queryAssets)
  
  Future.sequence(Seq(employeesFuture, assetsFuture)).map { case (employees, assets) =>
    // 同样的,在Scala层面关联数据
    employees.map { employee =>
      val employeeAssets = assets.filter(_.employee_id == employee.employee_id)
      (employee, employeeAssets)
    }
  }
}

请注意,虽然上述方法可以工作,但它可能不如直接使用JOIN查询高效,特别是当数据量大时。这是因为没有利用数据库的优化能力来处理关联数据。因此,除非有特殊需求,否则建议还是使用JOIN查询来处理这类关系。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: