我正在使用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) } 在其中,我可以获取员工对象的列表,但是我想将员工对象与相关资产对象一起使用。使用联接查询,我可以做到这一点,但是我想要没有联接的结果。我正在寻找带有鹅毛笔和光滑笔迹的答案。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Slick和Quill中,处理一对多关系时,通常推荐使用JOIN查询来获取关联数据。但是,如果你希望避免直接使用JOIN操作并仍然能够将员工与其资产关联起来,你可以通过以下方法实现:
在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提供了更灵活的方式来处理关联数据,尽管它也鼓励使用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查询来处理这类关系。