滑动 - 使用ForeignKey约束和访问被引用的对象直接作为列 [英] Slick- use foreignKey constraint and access referenced object directly as column
问题描述
我有两个模型(比如供应商和咖啡),Coffee模型有对供应商模式的外键引用。在ddl期间,我希望这种关系存在于表格创建中。但是我也希望能够通过Coffee对象来引用供应商对象,比如 coffeeObj.supplier.name
。以下是我的虚拟代码。我正在使用 MappedTable , foreignKey 和 TypeMapper 。
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
object SlickTest {
//供应商
案例类别供应商(id:Option [Int],name:String)
对象供应商扩展表[供应商](供应商){
def id =列[ Int](id,O.PrimaryKey,O.AutoInc)
def name = column [String](name)
def * = id。 〜name<> (Supplier,Supplier.unapply _)
def findOneById(id:Int):Supplier =
this.map {e => e} .where(r => r.id === id).firstOption.get
}
//从供应商到Int的隐式转换
implicit val supTypeMapper = MappedTypeMapMap.base [Supplier,Int](
{s => s.id.get},{id => Suppliers.findOneById(id)})
// Coffee
case class咖啡(名称:Option [String],sup:供应商,价格:Double)
对象Coffees extends表[Coffee](coffee){
def name = column [String] (cof_name,O.PrimaryKey)
def sup = column [Supplier](supplier)
def price = column [Double](price)
def * = name。 ?价格<> (Coffee,Coffee.unapply _)
def supplier = foreignKey(SUP_FK,sup,Suppliers)(_。id)
}
}
在 supplier
的定义的最后一行代码失败。任何人都可以点亮任何东西?
在Slick中,您不映射到引用其他案例类的案例类。要解决外键,你使用查询,而不是你可以把它放在方法重用。
另见我的文章: https://groups.google.com/d/msg/scalaquery/esFb2DjoHVE/NtMj7BmpE94J
编辑:
不能在coffeeObj中跟随引用,这是一件好事。因为这需要配置一个类似于ORM的加载策略,这会更加复杂,并且会使代码的执行行为变得不那么明显。
延迟加载可能会加载在控制器和供应商coffeeObj看来,这似乎很奇怪,对不对?您可以这样做:
从<$ c中删除 .firstOption.get
$ c> findOneById 方法,然后:
$ b
val supplierQuery = Query (供应商).findById(id)
val coffeeQuery = supplierQuery.join(Coffee).on(...)。map(_._ 2)
//这里是你想要的,供应商和相应的咖啡:
val supplierWithCoffee =(supplierQuery.firstOption,coffeeQuery.f irstOption)
把连接放入一个函数来保存锅炉板。
I have two models (say, Supplier and Coffee) and Coffee model has foreign key reference to Supplier model. During ddl, I want this relationship to exist in table creation. But I also want to be able to refer the Supplier object through Coffee object like coffeeObj.supplier.name
. Below is my dummy code. I am using MappedTable, foreignKey and TypeMapper.
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
object SlickTest {
// Supplier
case class Supplier(id: Option[Int], name: String)
object Suppliers extends Table[Supplier]("supplier") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = id.? ~ name <> (Supplier, Supplier.unapply _)
def findOneById(id: Int): Supplier =
this.map { e => e }.where(r => r.id === id).firstOption.get
}
// Implicit Conversion from Supplier to Int
implicit val supTypeMapper = MappedTypeMapper.base[Supplier, Int](
{ s => s.id.get }, { id => Suppliers.findOneById(id) })
// Coffee
case class Coffee(name: Option[String], sup: Supplier, price: Double)
object Coffees extends Table[Coffee]("coffee") {
def name = column[String]("cof_name", O.PrimaryKey)
def sup = column[Supplier]("supplier")
def price = column[Double]("price")
def * = name.? ~ sup ~ price <> (Coffee, Coffee.unapply _)
def supplier = foreignKey("SUP_FK", sup, Suppliers)(_.id)
}
}
The code is failing at the last line for the definition of supplier
. Could anyone shed any light?
In Slick you don't map to case classes that reference other case classes. To resolve foreign keys you use queries instead, which you can put into methods for re-usability.
Also see my post at: https://groups.google.com/d/msg/scalaquery/esFb2DjoHVE/NtMj7BmpE94J
EDIT: You can't follow a reference in coffeeObj and that is a good thing. Because that would require configuring a loading strategy like in ORMs, which would be more complicated and would make the execution behavior of your code less obvious.
Lazy loading would probably load the coffeeObj in the controller and the supplier in the view, which seems odd, right? You can do this:
Remove .firstOption.get
from your findOneById
method and then:
val supplierQuery = Query(Suppliers).findById(id)
val coffeeQuery = supplierQuery.join(Coffee).on(...).map(_._2)
// here is what you want, a supplier and the corresponding coffee:
val supplierWithCoffee = (supplierQuery.firstOption,coffeeQuery.firstOption)
Put the join into a function to save boiler plate.
这篇关于滑动 - 使用ForeignKey约束和访问被引用的对象直接作为列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!