I am very new to both Scala and Slick and in trying to learn it I am writing a small application that works with a simple database.
Most of my previous experience comes from .Net and the Entity Framework so I was wondering if like in Entity Framework with the ComplexType
attribute if Slick would allow me to do the same.
Basically one of my tables is a 1-1 relationship and for some of them I would prefer to just create an object and use it as a complex type. Obviously in the database this is just extra columns on the table, but I was wondering if Slick could map those columns to an object in my Table
class. See example below.
I will use a Blog entry example.
My main class that extends Table is BlogEntry
and it contains the text of the entry. Then say I wanted in that class another class called EntryDetails
that contained the time the entry was posted and the time it was last updated.
In the database all those fields will be in the same table, but when read in it will be one object containing the other object. Is this possible with Slick?
I think that this solves your 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]
}
I included everything in a trait Mapping, to pack the code for your answer. As far as I understood, you want to map a table to two objects, one inside the other, this can be achieved by creating another mapping method, here called entryDetails, that map the table queries to the EntryDetails model object. Then you can add this mapping method to your object mapping, the * method. The method entryDetails will be just another parameter of that mapping method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With