2013-08-14 31 views
7

Tôi rất mới đối với cả Scala và Slick và cố gắng tìm hiểu nó Tôi đang viết một ứng dụng nhỏ hoạt động với một cơ sở dữ liệu đơn giản.Scala Slick và các loại phức tạp trong cơ sở dữ liệu của tôi

Hầu hết các kinh nghiệm trước đây của tôi đến từ .Net và khung Entity vì vậy tôi đã tự hỏi nếu như trong Entity Framework với thuộc tính ComplexType nếu Slick cho phép tôi làm như vậy.

Về cơ bản một trong các bảng của tôi là mối quan hệ 1-1 và đối với một số người trong số họ, tôi muốn tạo một đối tượng và sử dụng nó làm kiểu phức tạp. Rõ ràng trong cơ sở dữ liệu, đây chỉ là các cột phụ trên bảng, nhưng tôi đã tự hỏi liệu Slick có thể ánh xạ các cột đó tới một đối tượng trong lớp Table của tôi hay không. Xem ví dụ bên dưới.

Tôi sẽ sử dụng ví dụ về mục nhập Blog.

Lớp chính của tôi mở rộng Bảng là BlogEntry và nó chứa văn bản của mục nhập. Sau đó nói rằng tôi muốn trong lớp đó một lớp khác được gọi là EntryDetails có chứa thời gian mục nhập đã được đăng và thời gian nó được cập nhật lần cuối.

Trong cơ sở dữ liệu, tất cả các trường đó sẽ nằm trong cùng một bảng, nhưng khi đọc trong đó sẽ là một đối tượng chứa đối tượng khác. Điều này có thể với Slick?

+1

Có, điều đó là có thể. Bạn cần [triển khai một 'TypeMapper' tùy chỉnh] (http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and-types) cho điều đó. (Tôi sẽ viết một câu trả lời thực sự sau.) – Carsten

+0

Tuyệt vời cảm ơn bạn rất nhiều. Yea khi bạn làm tôi sẽ chấp nhận nó như là câu trả lời. Cảm ơn bạn rất nhiều vì đã trả lời nhanh. – twreid

+0

Bạn đã giải quyết được vấn đề của mình với TypeMapper chưa? Bạn vẫn cần một mẫu làm thế nào để làm điều đó? – dirceusemighini

Trả lời

5

Tôi nghĩ rằng điều này giải quyết vấn đề của bạn

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

tôi bao gồm tất cả mọi thứ trong một bản đồ đặc điểm, để đóng gói mã cho câu trả lời của bạn. Theo như tôi đã hiểu, bạn muốn ánh xạ một bảng thành hai đối tượng, một cái bên trong cái kia, điều này có thể đạt được bằng cách tạo một phương thức ánh xạ khác, ở đây gọi là entryDetails, ánh xạ các truy vấn bảng tới đối tượng mô hình EntryDetails. Sau đó, bạn có thể thêm phương thức ánh xạ này vào ánh xạ đối tượng của bạn, phương thức *. Phương thức entryDetails sẽ chỉ là một tham số khác của phương thức ánh xạ đó.

+0

Cảm ơn bạn! :) Điều này đã làm những gì tôi đang tìm kiếm cảm ơn bạn rất nhiều. – twreid

Các vấn đề liên quan