Android - эффективный способ использования курсора базы данных

Я реализовал базу данных sqlite в своем приложении и использую курсор Android. Я написал класс базы данных с, например, именем базы данных и именами таблиц и столбцов. Здесь у меня также есть различные методы, такие как следующие:

public Cursor getCorrectQuestions(int topic) {
    SQLiteDatabase db = getReadableDatabase();
    Cursor questionCursor = db.rawQuery(
            "Select * FROM Result, Question WHERE Result.qid = Question._id AND correct = 1 AND topic = " + topic,
            null);
    questionCursor.moveToFirst();
    return questionCursor;
}

public Cursor getExamQuestions() {
    SQLiteDatabase db = getReadableDatabase();
    Cursor questionCursor = db.rawQuery("Select * FROM Question WHERE topic = 7", null);
    questionCursor.moveToFirst();
    return questionCursor;
}

public Cursor getAnswerItems(String id) {
    SQLiteDatabase db = getReadableDatabase();
    Cursor answerCursor = db.rawQuery(
            "Select * FROM Answer, Question WHERE Question._id = " + id + " AND Question._id = Answer.qid", null);
    answerCursor.moveToFirst();
    return answerCursor;
}

public Cursor getUserResults(String qid) {
    SQLiteDatabase db = getReadableDatabase();
    Cursor userResultsCursor = db.rawQuery("SELECT result FROM Result, Answer WHERE Result.qid = " + qid, null);
    userResultsCursor.moveToFirst();
    return userResultsCursor;
}

В QuizActivity, который имеет 3 курсора (answerCursor, questionCursor, userResultCursor), я вызываю эти методы. У меня вопрос: необходимо ли создавать объект SQLiteDatabase в каждом методе или это можно определить один раз в конструкторе базы данных? И мне нужно 3 разных курсора в моей деятельности или есть лучший способ справиться с этим?

1 ответ

Предполагая, что методы, которые вы написали, являются частью SQLiteOpenHelper вы на самом деле не создаете 3 объекта базы данных. Только первый звонок getReadableDatabase() фактически создает объект базы данных, и последующие вызовы повторно используют один и тот же объект.

Вам также нужно сделать новый Cursor для каждого выполняемого запроса, так как они не могут быть отредактированы после создания. В этом смысле нет способа упростить то, что вы уже сделали.

Что касается улучшения вашего кода, есть несколько вещей, на которые вы можете посмотреть:

  • Рассмотрите возможность размещения вашей базы данных в ContentProvider и доступ к нему через URI. Это потребует дополнительной предварительной работы, но сделает это намного проще, если вы захотите поделиться своей базой данных с другими приложениями или синхронизировать свои данные с сервером в будущем.
  • Оставьте курсор в положении по умолчанию (не звоните moveToFirst()). Таким образом, когда вызывающий получает курсор, он может использовать следующий код, чтобы начать итерацию строк курсора без выполнения каких-либо дополнительных проверок:

    while (cursor.moveToNext()) {
        // extract data
    }
    

    Это связано с тем, что курсор, возвращаемый из запроса, изначально располагается перед первой строкой данных, поэтому, если курсор пуст, код внутри цикла while просто никогда не выполняется вообще.

Другие вопросы по тегам