2013-08-14 1 views
7

Я новичок в обоих Scala и Slick и пытается узнать его, я пишу небольшое приложение, которое работает с простой базой данных.Scala Slick и сложные типы в моей базе данных

Основная часть моего предыдущего опыта связана с .Net и Entity Framework, поэтому мне было интересно, нравится ли в Entity Framework атрибут ComplexType, если Slick позволит мне сделать то же самое.

В основном одна из моих таблиц 1-1 отношений и для некоторых из них я предпочел бы просто создать объект и использовать его в качестве сложного типа. Очевидно, что в базе данных это дополнительные столбцы таблицы, но мне было интересно, сможет ли Slick сопоставить эти столбцы с объектом в моем классе Table. См. Пример ниже.

Я буду использовать пример записи в блоге.

Мой главный класс, который расширяет таблицу является BlogEntry и содержит текст записи. Тогда скажите, что я хотел в этом классе еще один класс, называемый EntryDetails, который содержал время публикации записи и время последнего обновления.

В базе данных все эти поля будут находиться в одной и той же таблицы, но при чтении в нем будет один объект, содержащий другой объект. Возможно ли это с Slick?

+1

Да, это возможно. Для этого вам необходимо [реализовать пользовательский 'TypeMapper'] (http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and-types). (Я напишу реальный ответ позже.) – Carsten

+0

Удивительное спасибо. Да, когда вы это сделаете, я приму это как ответ. Большое спасибо за быстрый ответ. – twreid

+0

Вы решили свою проблему с помощью TypeMapper? Вам все еще нужен образец того, как это сделать? – dirceusemighini

ответ

5

Я думаю, что это решает проблему

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] 
} 

Я включил все в Mapping признака, чтобы упаковать код для Вашего ответа. Насколько я понял, вы хотите, чтобы отобразить таблицу двух объектов, один внутри другого, это может быть достигнуто путем создания другого метода отображения, здесь называемый entryDetails, что отобразить таблицу запросов к объекту EntryDetails модели. Затем вы можете добавить этот метод сопоставления к вашему сопоставлению объектов - методу *. Метод entryDetails будет всего лишь еще одним параметром этого метода сопоставления.

+0

Сладкое спасибо! :) Это сделало то, что я искал, большое спасибо. – twreid