Жизненный цикл базы данных Android Ugrade - PullRequest
1 голос
/ 23 декабря 2011

Что ж, это вопрос "наилучшей практики" с базами данных Android SQL Lite.

Я получил DBHandler, который создает SQLiteDatabase с внутренним классом, называемым DBHelper, например:

    private final DBHelper dbhelper;
    SQLiteDatabase db = dbhelper.getReadableDatabase();

    // Call the helper  
    private static class DBHelper extends SQLiteOpenHelper {

    DBHelper(Context context){      
        super(context, DB_NAME, null, DB_VERSION);  
    }
        @Override   
        public void onCreate(SQLiteDatabase db){
            // create Table01       
            String sql =    "create table " + "... SQL stuff here";     
            db.execSQL(sql);
        }

        @Override   
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
            db.execSQL("drop table if exists " + Table01);
            onCreate(db);
        } 
    }

Также DBHandler предлагает функции для добавления / извлечения данных в / из таблиц, например, например:

public void insertOrIgnore(String table, ContentValues values){
    SQLiteDatabase db = this.dbhelper.getWritableDatabase();
    try{
        db.insertOrThrow(table, null, values);
    } 
    catch (SQLException e){
        e.printStackTrace();
        Log.e(TAG, e.toString());
    }
    finally {
        db.close();
    }
}

public Cursor getTable1(){
    SQLiteDatabase db = dbhelper.getReadableDatabase();
    Cursor cursor = db.query(Table1, null, null, null, null, null, TABEL_ID + " ASC");

    return cursor;
}

Когда мне нужны данные из БД, я создаю объект DBHandlerи использовать его методы.

Итак, при первом запуске приложения я вызываю метод insertOrIgnore и добавляю данные, которые я хочу использовать позже.Всякий раз, когда я делаю изменения в БД, мне нужно удалить приложение и переустановить его, чтобы изменения вступили в силу.это отстой, поэтому я хочу использовать DB_VERSION для обработки этого материала.После внесения изменений в базу данных (схема ИЛИ данные) я изменяю идентификатор DB_VERSION на большее число.

Итак, мои вопросы:

  1. Если newDBversion> oldDBversion, SQLiteDatabase не использует onCreate, но onUpdate.Это работает нормально, но ТОЛЬКО схема обновляется, и в результате появляются пустые таблицы.Я хочу ознакомиться с наилучшей практикой, поэтому после обновления данных методы из DBHandler вызываются снова.Помните, что DBHelper является внутренним классом DBHandler .
  2. . Насколько я понимаю, метод SQLiteDatabase onCreate вызывается ТОЛЬКО, если БДотсутствует, и метод onUpdate вызывается, только если newDBversion> oldDBversion, это правильно?
  3. Должен ли DBHandler быть статическим или одноэлементным?или это просто нормально без, так как класс SQLiteDatabase обрабатывает несколько операций чтения / записи сам по себе?

Я открыт для лучших решений, но из чего яТакой способ добавления данных в базу данных SQL найден в сети и в некоторых книгах по Android.Но никто не объясняет, как обновить данные (НЕ схему, которая выполняется автоматически при изменении dbversion)

1 Ответ

0 голосов
/ 23 декабря 2011

Я могу ответить на третий вопрос, потому что я немного исследую этот вопрос.Я решил, что хорошо иметь следующий способ определения этих классов (посмотрите на мой код)

public class DbWordsAdapter {

private static final String TAG = DbWordsHelper.class.getSimpleName();
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

private static DbWordsHelper dbWordsHelper; 
private Context context;
private SQLiteDatabase mDb;

// database constants
private static final String DB_NAME = "words.db";
private static final int DB_VERSION = 1;
private static final String TABLE_WORDS = "words";

// database columns names
public static final String C_ID = BaseColumns._ID;
public static final String C_WORD = "word";
public static final String C_EXPLANATION = "explanation";
public static final String C_CREATION_DATE = "creation_date";

//Sql Statements
static final String CREATE_TABLE_WORDS = "create table " + TABLE_WORDS
        + "(" + C_ID + " integer primary key autoincrement, " + C_WORD
        + " text not null, " + C_EXPLANATION + " text, "
        + C_CREATION_DATE + " date not null)";
static final String DROP_TABLE_WORDS = "drop table if exists"
        + TABLE_WORDS;      
static final String[] ALL_COLUMNS = { C_ID, C_WORD, C_EXPLANATION,
        C_CREATION_DATE };
static final String ORDER_BY_DATE = C_CREATION_DATE + " desc";
static final String ORDER_BY_ALPH = C_WORD + " asc";
static final String ORDER_BY_RANDOM = "random() limit 1";


/*
 * Inner class that manages database creation and management
 */
private static class DbWordsHelper extends SQLiteOpenHelper {

    private DbWordsHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d(TAG, "SqlCreate Statement: "
                + CREATE_TABLE_WORDS);

        try {
            db.execSQL(CREATE_TABLE_WORDS);
        } catch (SQLException e) {
            Log.e(TAG, "Error while creating database" + TABLE_WORDS, e);
        }

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        // Here in the future should be method that change the schema of the
        // database. Now we just delete
        try {
            db.execSQL(DROP_TABLE_WORDS);
        } catch (SQLException e) {
            Log.e(TAG, "Error while updating database" + TABLE_WORDS, e);
        }

        onCreate(db);

    }
}

public DbWordsAdapter(Context context) {
    this.context = context;
}

public DbWordsAdapter open () {
    if (dbWordsHelper == null) {
        dbWordsHelper = new DbWordsHelper(context);
    }
    mDb = dbWordsHelper.getWritableDatabase();
    return this;
}

public void close () {
    dbWordsHelper.close();
    dbWordsHelper = null;
}

//
//Following methods implement CRUD operations for this database
//

/*
 * This method creates new Word in the database.
 * 
 * @param word that we create
 * 
 * @param explanation of the word
 * 
 * @return id of the word
 */
public long createWord(String word, String explanation) {
    Log.d(TAG, "createWord method");
    ContentValues newWord = createValue(word, explanation,
            createDateString(new Date()));
    return mDb.insert(TABLE_WORDS, null, newWord);
}

В вашем приложении в соответствующем месте вы просто вызываете dbWordsAdapter.open();, а затем свою транзакцию БД (например,dbWordsAdapter.createWord(word, explanation)) и закройте базу данных.Таким образом, для активности вы можете открыть БД в методе onResume() и закрыть в onPause()

. Учитывая второй вопрос, я думаю, что вы правы.

Для первого вопроса я не знаю.Может быть, будет хорошо увидеть, как это реализовано в других приложениях.

Обновление: ответ на первый вопрос В документации и других ресурсах я нашел информацию об обновлениибаза данных.Вы можете использовать таблицу изменений оператора SQL для вставки новых столбцов в вашу базу данных.

Если вы добавляете новые столбцы, вы можете использовать ALTER TABLE, чтобы вставить их в оперативную таблицу.Если вы переименуете или удалите столбцы, вы можете использовать ALTER TABLE, чтобы переименовать старую таблицу, затем создать новую таблицу и затем заполнить новую таблицу содержимым старой таблицы.

Итак, в основном алгоритм дляОбновление в onUpdate должно выглядеть следующим образом:

  1. Сначала, согласно oldVersion и newVersion, вы определяете, что следует обновлять.
  2. Затем, если вы просто хотите добавить столбцы, вы вызываетеALTER TABLE ADD COLUMN SQL заявление.На это есть некоторые ограничения.Вы можете найти их здесь .
  3. Для удаления и переименования вы можете воспользоваться следующим советом: если вы переименовываете или удаляете столбцы, вы можете использовать ALTER TABLE, чтобы переименовать старую таблицу, а затем создать новуютаблицу, а затем заполните новую таблицу содержимым старой таблицы.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...