2013-08-14 8 views
7

Ich bin sowohl Scala als auch Slick sehr neu und versuche es zu lernen. Ich schreibe eine kleine Anwendung, die mit einer einfachen Datenbank arbeitet.Scala Slick und komplexe Typen in meiner Datenbank

Die meisten meiner bisherigen Erfahrung kommt von .Net und der Entity Framework, also ich frage mich, ob wie in Entity Framework mit dem ComplexType Attribut, wenn Slick würde mir erlauben, das gleiche zu tun.

Grundsätzlich ist eine meiner Tabellen eine Beziehung 1-1 und für einige von ihnen würde ich lieber ein Objekt erstellen und es als einen komplexen Typ verwenden. Offensichtlich sind das in der Datenbank nur zusätzliche Spalten in der Tabelle, aber ich habe mich gefragt, ob Slick diese Spalten auf ein Objekt in meiner Klasse Table abbilden könnte. Siehe Beispiel unten.

Ich werde ein Blog-Eintrag Beispiel verwenden.

Meine Hauptklasse, die Tabelle erweitert, ist BlogEntry und es enthält den Text des Eintrags. Dann sage ich, dass ich in dieser Klasse eine andere Klasse namens EntryDetails wollte, die die Zeit, zu der der Eintrag gepostet wurde, und die Zeit, zu der er zuletzt aktualisiert wurde, enthielt.

In der Datenbank befinden sich alle diese Felder in der gleichen Tabelle, aber beim Einlesen wird es ein Objekt sein, das das andere Objekt enthält. Ist das mit Slick möglich?

+1

Ja, das ist möglich. Sie müssen dazu einen benutzerdefinierten 'TypeMapper' implementieren (http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and-types). (Ich werde später eine echte Antwort schreiben.) – Carsten

+0

Awesome vielen Dank. Ja, wenn du es tust, werde ich es als Antwort akzeptieren. Vielen Dank für die schnelle Antwort. – twreid

+0

Haben Sie Ihr Problem mit TypeMapper gelöst? Brauchen Sie noch eine Probe, wie es geht? – dirceusemighini

Antwort

5

Ich denke, dass dies Ihr 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] 
} 

löst ich alles in einem Zug Mapping enthalten ist, den Code für Ihre Antwort zu packen. Soweit ich es verstanden habe, möchten Sie eine Tabelle auf zwei Objekte, eine innerhalb der anderen, abbilden, dies kann durch Erstellen einer anderen Mapping-Methode, hier EntryDetails genannt, erreicht werden, die die Tabellenabfragen dem EntryDetails-Modellobjekt zuordnen. Dann können Sie diese Zuordnungsmethode zu Ihrer Objektzuordnung hinzufügen, die * -Methode. Die Methode entryDetails ist nur ein weiterer Parameter dieser Mapping-Methode.

+0

Süße danke! :) Das tat, was ich gesucht habe, vielen Dank. – twreid

Verwandte Themen