如何在 Room @Query 中使用 ROW_NUMBER()?

How use ROW_NUMBER() in Room @Query?

问题:

我在我的应用程序中点击了一个 api,它以页面为单位发送日期(页面大小 = 20)。所以目前我正在尝试使用 ROOM 将数据保存在我的本地数据库中,这是一个基本插入 operation.And 当应用程序未连接到网络时我希望应用程序以页面的形式从数据库获取数据。

解决方案(我试过的):

DAO 层 i 使用

 @Query("SELECT * FROM ( SELECT ROW_NUMBER () OVER ( ORDER BY rating ) RowNum,* FROM movie ) t WHERE t.RowNum > 0 AND t.RowNum <= 20")
 suspend fun getPagedMovie(): List<MovieEntity>

我遇到两个编译错误:

< compound operator >, FROM, GROUP, LIMIT, ORDER, WHERE or comma expected,

&

cannot relove t.RowNum

所以,为了解决这个问题,我尝试使用@RawQuery

val query = SimpleSQLiteQuery(
        "SELECT * FROM ( SELECT ROW_NUMBER () OVER ( ORDER BY rating ) RowNum,* FROM movie ) t WHERE t.RowNum > 0 AND t.RowNum <= 20"
    )
return movieDao.getPagedMovie(query).map { it.toGeneralMovie() }

&

 @RawQuery
 suspend fun getPagedMovie(query: SupportSQLiteQuery): List<MovieEntity>

在上述情况下,错误日志如下:

2020-04-18 16:23:33.014 21854-21854/? E/m.andor.watchi: Unknown bits set in runtime_flags: 0x8000 2020-04-18 16:23:34.158 21854-21891/com.andor.watchit E/[Gralloc-ERROR]: sanitize_formats:482 Format [id:0x4] which doesn't support afbc should not have bpp defined 2020-04-18 16:23:34.415 21854-21979/com.andor.watchit E/SQLiteLog: (1) near "(": syntax error 2020-04-18 16:23:34.456 21854-21978/com.andor.watchit E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3 Process: com.andor.watchit, PID: 21854 android.database.sqlite.SQLiteException: near "(": syntax error (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM ( SELECT ROW_NUMBER () OVER ( ORDER BY rating ) RowNum,* FROM movie ) t WHERE t.RowNum > 0 AND t.RowNum <= 20 at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1372) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:811) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:62) at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1959) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1934) at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161) at androidx.room.RoomDatabase.query(RoomDatabase.java:328) at androidx.room.util.DBUtil.query(DBUtil.java:83) at com.andor.watchit.core.framework.db.MovieDao_Impl.call(MovieDao_Impl.java:237) at com.andor.watchit.core.framework.db.MovieDao_Impl.call(MovieDao_Impl.java:234) at androidx.room.CoroutinesRoom$Companion$execute.invokeSuspend(CoroutinesRoom.kt:54) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919)

我想知道使用 ROOM 实现分页的解决方案?

P.S。 :我的查询只是现在获取第 1 个 20 个元素,即第 1 页,我可以稍后在 DB Browser 上进行动态查询 work.On 旁注我不想加载整个结果然后制作页面。

我通过使用 LIMITOFFSET

找到了上述问题的解决方案
@Query("SELECT * FROM movie ORDER BY rating DESC LIMIT :pageSize OFFSET (:pageNumber-1)*:pageSize")
suspend fun getPagedMovie(pageNumber: Int, pageSize: Int): List<MovieEntity>

希望这对其他人也有帮助。

还要感谢@dev-masih 在评论中提供参考。