如何反向滚动表格顶部的SQLITE数据库表

时间:2016-02-06 16:45:14

标签: java android database sqlite pagination

我将来自聊天组的消息存储在专用于该组的表中。

现在,只要我在列表视图中打开此组,它就会使用以下代码显示最后N条消息:

    public ArrayList<Post> getRecentPosts(int numOfMessagesGottenAlready,int numOfMessagesNeeded) {
            SQLiteDatabase db = this.getReadableDatabase();

Cursor res = db.rawQuery("select * from "+ROOM_TABLE_NAME+ " LIMIT "+numOfMessagesNeeded +
                    " OFFSET (SELECT COUNT(*) FROM "+ROOM_TABLE_NAME+")-"+
                    (numOfMessagesGottenAlready + numOfMessagesNeeded)+";", null);

            res.moveToFirst();
            ArrayList<Post>posts = new ArrayList<>();
            while (!res.isAfterLast()) {
                posts.add(Post.parseJsonToPost(
                        res.getString(res.getColumnIndex(ROOMS_COLUMN_JSON))) );
                res.moveToNext();
            }

            if (!res.isClosed()) {
                res.close();
            }
            return posts;
        }

每当我需要将更多消息加载到组中时,我会调用上面的方法 它提供先前作为第一个参数加载的消息数以及需要作为第二个参数加载的消息数。

该方法运行良好(或者我认为),当然,从表格底部加载消息。 但是有一个障碍。

当它到达表的顶部,即OFFSET=0然后再次调用该方法时, OFFSET变为否定,因此它会在https://www.sqlite.org/lang_select.html指定的表格顶部继续加载最早的消息。

我希望当OFFSET计算的值小于零时,Cursor中不会返回任何值。

如何修改表达式以实现此目的?

1 个答案:

答案 0 :(得分:0)

好的,所以我通过使用2个单独的查询来解决问题:

我在交易中包含了下面描述的整个过程。

我首先获得了桌面上的消息数量。然后我检查使用Java代码,如果有更多的消息要加载..并根据这个结果,我加载了更多的消息。所以我能够检测到我是否已经到达表的顶部并编写必要的代码以返回该事件中的空列表:

以下是代码:它可用于实现WhatsApp的 LOAD EARLIER MESSAGES 功能......其中加载是从sqlite表完成的。

    /**
     * Very useful for loading a ChatRoom that already has messages loaded from the bottom of this
     * table. It allows to 'load more' messages(just the number needed) without loading the
     * whole ChatRoom.
     * @param numOfMessagesGottenAlready The number of messages that the room has already.
     * @param numOfMessagesNeeded The number of messages to load more.
     * @return an ArrayList of messages loaded in pagination style..from the bottom this time.
     */
    public ArrayList<Post> getRecentPosts(int numOfMessagesGottenAlready,int numOfMessagesNeeded) {
        SQLiteDatabase db = this.getReadableDatabase();
        int add = numOfMessagesGottenAlready + numOfMessagesNeeded;


        boolean success = true;
        try {
            db.beginTransaction();

            Cursor res = db.rawQuery("select COUNT(*) from "+ROOM_TABLE_NAME , null);
            res.moveToFirst();

            int count = res.getInt(0);
            if (!res.isClosed()) {
                res.close();
            }

            Log.e("table row count", count + "");

            Log.e("add", add + "");

            if(count >= numOfMessagesGottenAlready) {
                Cursor set = db.rawQuery("select * from " + ROOM_TABLE_NAME + " ORDER BY " + ROOMS_COLUMN_ID +
                        " ASC LIMIT " + numOfMessagesNeeded +
                        " OFFSET ( " + (count - add) + " )"
                        , null);
set.moveToFirst();
                ArrayList<Post>posts = new ArrayList<>();
                try {
                    while (!set.isAfterLast()) {
                        posts.add(Post.parseJsonToPost(
                                set.getString(set.getColumnIndex(ROOMS_COLUMN_JSON))));
                        set.moveToNext();
                    }
                }
                catch (Exception e){return posts;}
                if (!set.isClosed()) {
                    set.close();
                }
                return posts;
            }

            db.setTransactionSuccessful();
            success = true;
        }
        catch (SQLiteException e){
            e.printStackTrace();
            success = false;
        }
        finally {
            db.endTransaction();
        }

return new ArrayList<Post>();
    }

谢谢!