想象一下下列關係油滑3加入查詢一對多關係
一本書包含很多章節,一章只屬於一本書。古典一對多關係。
我模仿它,因爲這:
case class Book(id: Option[Long] = None, order: Long, val title: String)
class Books(tag: Tag) extends Table[Book](tag, "books")
{
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def order = column[Long]("order")
def title = column[String]("title")
def * = (id, order, title) <> (Book.tupled, Book.unapply)
def uniqueOrder = index("order", order, unique = true)
def chapters: Query[Chapters, Chapter, Seq] = Chapters.all.filter(_.bookID === id)
}
object Books
{
lazy val all = TableQuery[Books]
val findById = Compiled {id: Rep[Long] => all.filter(_.id === id)}
def add(order: Long, title: String) = all += new Book(None, order, title)
def delete(id: Long) = all.filter(_.id === id).delete
// def withChapters(q: Query[Books, Book, Seq]) = q.join(Chapters.all).on(_.id === _.bookID)
val withChapters = for
{
(Books, Chapters) <- all join Chapters.all on (_.id === _.bookID)
} yield(Books, Chapters)
}
case class Chapter(id: Option[Long] = None, bookID: Long, order: Long, val title: String)
class Chapters(tag: Tag) extends Table[Chapter](tag, "chapters")
{
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def bookID = column[Long]("book_id")
def order = column[Long]("order")
def title = column[String]("title")
def * = (id, bookID, order, title) <> (Chapter.tupled, Chapter.unapply)
def uniqueOrder = index("order", order, unique = true)
def bookFK = foreignKey("book_fk", bookID, Books.all)(_.id.get, onUpdate = ForeignKeyAction.Cascade, onDelete = ForeignKeyAction.Restrict)
}
object Chapters
{
lazy val all = TableQuery[Chapters]
val findById = Compiled {id: Rep[Long] => all.filter(_.id === id)}
def add(bookId: Long, order: Long, title: String) = all += new Chapter(None, bookId, order, title)
def delete(id: Long) = all.filter(_.id === id).delete
}
現在我想做的事:
我想查詢他們的所有章節全部或特定的書(由ID)
轉換爲純SQL,如下所示:
SELECT * FROM books b JOIN chapters c ON books.id == c.book_id WHERE books.id = 10
但在Slick中,我無法真正把這整個事情工作。
我試了一下:
object Books
{
//...
def withChapters(q: Query[Books, Book, Seq]) = q.join(Chapters.all).on(_.id === _.bookID)
}
還有:
object Books
{
//...
val withChapters = for
{
(Books, Chapters) <- all join Chapters.all on (_.id === _.bookID)
} yield(Books, Chapters)
}
,但無濟於事。 (我使用ScalaTest和我得到一個空結果(爲def withChapters(...)
)或另一個例外val withChapters = for...
)
如何繼續關於此?我試圖保持文檔,但我顯然做錯了什麼。
另外:有沒有簡單的方法來查看實際的查詢作爲一個字符串?我只找到query.selectStatement
之類的東西,但這不適用於我加入的查詢。對於查看實際查詢是否錯誤將非常有用。
編輯:我的測試是這樣的:
class BookWithChapters extends FlatSpec with Matchers with ScalaFutures with BeforeAndAfter
{
val db = Database.forConfig("db.test.h2")
private val books = Books.all
private val chapters = Chapters.all
before { db.run(setup) }
after {db.run(tearDown)}
val setup = DBIO.seq(
(books.schema).create,
(chapters.schema).create
)
val tearDown = DBIO.seq(
(books.schema).drop,
(chapters.schema).drop
)
"Books" should "consist of chapters" in
{
db.run(
DBIO.seq
(
Books.add(0, "Book #1"),
Chapters.add(0, 0, "Chapter #1")
)
)
//whenReady(db.run(Books.withChapters(books).result)) {
whenReady(db.run(Books.withChapters(1).result)) {
result => {
// result should have length 1
print(result(0)._1)
}
}
}
}
這樣,我得到一個IndexOutOfBoundsException
。
我用這個作爲我的方法:
object Books
{
def withChapters(id: Long) = Books.all.filter(_.id === id) join Chapters.all on (_.id === _.bookID)
}
也:
logback.xml
看起來是這樣的:
<configuration>
<logger name="slick.jdbc.JdbcBackend.statement" level="DEBUG/>
</configuration>
我在哪裏可以看到日誌?或者我還需要做些什麼才能看到它們?
我在'res/main'下創建了.xml文件並找到它,但是日誌在哪裏?它應該去控制檯嗎?我試着用'info'來代替,但我只得到異常,沒有查詢字符串。有什麼我錯過了嗎? – Sorona
另外,謝謝,但它不適合我,我不知道爲什麼。我更新了我的問題。 – Sorona
您需要在XML配置中使用「appender」,並在build.xml中使用日誌記錄庫。這個要點給出了一個SBT依賴和一個完整的日誌配置,應該爲你工作:https://gist.github.com/d6y/fdc780164c044460217b –