ExposedのDAO APIを使って次のようなモデルを定義してみる。
object Posts : UUIDTable() { val text = varchar("text", 144) val createdAt = datetime("created_at") } class Post(id: EntityID<UUID>) : UUIDEntity(id) { companion object : UUIDEntityClass<Post>(Posts) var text by Posts.text var createdAt by Posts.createdAt }
この時ページネーションを行いたいときに、次のような条件を考えてみる。
- 取得数とオフセットを使って取得する範囲を特定する。
- 日付を基に降順でデータを取得したい。
色々調べて思いついたのが、sortedByDescending()
を使ってみること。
override suspend fun limitedPosts(n: Int, offset: Long): List<PostRecord> { return transaction { Post.all().limit(n, offset).sortedByDescending { post -> post.createdAt }.map { it.toPostRecord() } } }
ただ、これだとlimit()
で既に取得した値に対してソートを行った結果を取得することになってしまう。
これを回避するために、orderBy()
とlimit()
を組み合わせる。
override suspend fun limitedPosts(isActive: Boolean, n: Int, offset: Long): List<PostRecord> { return transaction { Post.all().orderBy(Posts.createdAt to SortOrder.DESC).limit(n, offset) .filter { post -> post.isActive == isActive } .map { it.toPostRecord() } } }
これにより、ソートされた結果に基づいてlimit()
を呼び出した内容を取得することができる。
参考
How does sorting work with limit in kotlin exposed model? - Stack Overflow