2013-08-14 17 views
7

Jestem bardzo nowy zarówno Scala i Slick i próbując się go nauczyć Piszę małą aplikację, która działa z prostą bazą danych.Scala Slick i złożonych typów w mojej bazie danych

Większość mojego wcześniejszego doświadczenia pochodzi z .Net i Entity Framework, więc zastanawiałem się, czy w Entity Framework z atrybutem ComplexType, czy Slick pozwoliłby mi zrobić to samo.

Zasadniczo jedną z moich tabel jest relacja 1-1, a dla niektórych z nich wolałbym po prostu utworzyć obiekt i użyć go jako typu złożonego. Oczywiście w bazie danych to tylko dodatkowe kolumny na stole, ale zastanawiałem się, czy Slick mógłby odwzorować te kolumny na obiekt w mojej klasie Table. Zobacz przykład poniżej.

Będę używał przykładu wpisu blogu.

Moja główna klasa rozszerzająca tabelę to BlogEntry i zawiera tekst wpisu. Następnie powiedz, że chciałem w tej klasie innej klasy o nazwie EntryDetails, która zawierała czas opublikowania wpisu i czas jego ostatniej aktualizacji.

W bazie danych wszystkie te pola będą znajdować się w tej samej tabeli, ale gdy zostanie odczytany, będzie to jeden obiekt zawierający inny obiekt. Czy to możliwe dzięki Slick?

+1

Tak, to jest możliwe. Musisz [zaimplementować niestandardowe 'TypeMapper'] (http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and- typeses) dla tego. (Napiszę później prawdziwą odpowiedź.) – Carsten

+0

Wspaniale, dziękuję bardzo. Tak, kiedy to zrobisz, przyjmuję to jako odpowiedź. Dziękuję bardzo za szybką odpowiedź. – twreid

+0

Czy rozwiązałeś swój problem z TypeMapper? Czy nadal potrzebujesz próbki, jak to zrobić? – dirceusemighini

Odpowiedz

5

myślę, że to rozwiąże problem

trait Mapping { 
    //Need to change JdbcDriver to the driver that you will use in your code (MySql, Postgres, etc) 

    import scala.slick.driver.JdbcDriver.profile.simple._ 

    // Models 
    case class EntryDetails(createDate: Option[DateTime] = None, updateDate: Option[DateTime] = None) 

    case class Entry(id: Int, text: String, details: EntryDetails) 

    //Implicit Joda Mappers for datetime columns 
    implicit def timestamp2dateTime = MappedColumnType.base[DateTime, Timestamp](
    dateTime => new Timestamp(dateTime.getMillis), 
    date => new DateTime(date)) 

    //Table mapping 
    class Entries(tag: Tag) extends Table[Entry](tag, "entry") { 
    def entryDetails = (createDate, updateDate) <>(EntryDetails.tupled, EntryDetails.unapply) 

    def * = (id, text, entryDetails) <>(Entry.tupled, Entry.unapply) 

    val id: Column[Int] = column[Int]("id") 
    val text: Column[String] = column[String]("text") 
    val createDate: Column[Option[DateTime]] = column[Option[DateTime]]("createDate") 
    val updateDate: Column[Option[DateTime]] = column[Option[DateTime]]("updateDate") 
    } 

    //Table query, used in slick 2.0 for querying a table 
    lazy val EntryTableQuery = TableQuery[Entries] 
} 

włączyłem wszystko odwzorowaniem cechy, pakować kod za odpowiedź. Z tego co rozumiem, chcesz zmapować tabelę na dwa obiekty, jeden w drugim, można to osiągnąć, tworząc kolejną metodę mapowania, zwaną tutaj entryDetails, która odwzorowuje zapytania tabeli na obiekt modelu EntryDetails. Następnie możesz dodać tę metodę odwzorowania do mapowania obiektów, metodę *. Metoda entryDetails będzie kolejnym parametrem tej metody mapowania.

+0

Słodkie dziękuję! :) To zrobiło to, czego szukałem, dziękuję bardzo. – twreid

Powiązane problemy