2014-06-30 46 views
4

我使用slick 2.x's codegen功能從數據庫模式生成Scala模型。然而,是否有可能遍歷外鍵約束來生成相關模型,例如如果我有這個模式油滑:Codegen外鍵引用

CREATE TABLE people(id INT PRIMARY KEY AUTO INCREMENT, name VARCHAR(31)); 
CREATE TABLE dogs(name VARCHAR(31), ownerId INT FOREIGN KEY people(id)); 

我從光滑以下型號:

case class PeopleRow(id: Int, name: String) 
case class DogsRow(name: String, ownerId: Int) 

但是,我真正想要的是這樣的:

case class PeopleRow(id: Int, name: String) 
case class DogsRow(name: String, owner: PeopleRow) 

甚至更​​好:

case class PeopleRow(id: Int, name: String) { 
    def dogs: List[DogsRow] // return items from dogs table that has this.id as ownerId 
} 

case class DogsRow(name: String, ownerId: People) { 
    lazy val owner: People // lazy on-demand or, can be a def too 
} 

有無論如何覆蓋sl ick codegen做到這一點?

+0

@EndeNeu:雖然問題相關不相關。他將從Scala模式轉換爲生成的SQL。我想要另一種方式。我想修改** SQL-> Scala **代碼生成器爲我執行此操作... – pathikrit

+0

我鏈接了這個問題,因爲您不能將case類定義爲外鍵,您需要明確指定它們,並且它們必須是一些原始類型(Int,Long等)。你不能把結構化類型當作鍵,除非你的用例與sql父子關係不同,在那種情況下,是的,那個問題是不相關的。 –

+0

@EndeNeu:我想知道是否我可以重寫代碼庫本身,這樣我就可以在生成的case類中添加helper「def dogs」(參見上面的例子) – pathikrit

回答

5

不要這樣做。 Slick的核心優勢之一來自撰寫查詢。雖然你打算有可能你打破了這種力量。反而寫查詢!

implicit class PersonExtension(q: Query[Person,PersonRow]){ 
    def dogs = q.join(Dog).on(_.id === _.ownerId).map(_._2) 
} 
implicit class DogExtension(q: Query[Person,PersonRow]){ 
    def owner = q.join(Person).on(_.ownerId === _.id).map(_._2) 
} 

val personQuery = Person.filter(_.id === someId) 
val person = personQuery.first 
val dogsQuery = personQuery.dogs 
val dogs = dogsQuery.run 
val ownerQuery = dogsQuery.owner 
val owner = ownerQuery.first 

因此,使用舊的查詢來根據您的新的狗查詢。優點是你不用這種方式硬編碼一個查詢,但你可以進一步撰寫。只想要棕色的狗?沒問題:

val brownDogsQuery = personQuery.dogs.filter(_.color === "brown") 

你當然可以使用代碼生成器自動生成這些隱式類。

相關視頻:

  • 斯卡拉交換2013
  • 斯卡拉用戶組柏林說話月,2013
  • 斯卡拉天2014談

http://slick.typesafe.com/docs/

+0

表中的隱式類不是更好嗎?例如'隱式類PersonExtension(p:Person){def dogs = Dogs.filter(_。ownerId === p.id)}'這樣你可以在monadic連接中使用它們。 – mbee

+0

不!讓他們在查詢中允許在應用過濾器後繼續使用它們。 – cvogt

+0

爲什麼不在一元連接中應用過濾器(etc)?示例(來自我的業務領域): 'val query = for'' '{' 'user < - Users if user.lastName ===「Miller」' 'relation < - user.loginRelations' 'role < relation.role if role.isCentralMonitor' 'study < - relation.study' '} yield(user.firstName,user.lastName,role.name,study.name)' – mbee