Метод onUpgrade когда-либо вызывался?

- Это onUpgrade метод SQLiteOpenHelper когда-нибудь называли? Если да, то когда он называется и чем? Если он не вызван разработчиками, то почему он там? Что на самом деле происходит с этой функцией? Я видел примеры, когда он отбрасывает все таблицы, но затем комментарий говорит, что отбрасывание всех таблиц-это не то, что вы должны делать. Есть предложения?

6 ответов


он вызывается при построении SQLiteOpenHelper с версией более новой, чем версия открытой базы данных. Что делать, зависит от изменений в базе данных, что между старой и новой версиями. Единственный случай, когда вы не удаляете измененную таблицу, - это когда изменение отмечает больше, чем добавленный столбец. Затем можно использовать инструкцию ALTER TABLE для добавления нового столбца в подпись таблицы.


для тех из вас, кто хотел бы знать точный момент, когда onUpgrade() получает вызов, это во время вызова либо getReadableDatabase() или getWriteableDatabase().

для тех, кто не понимает, как он обеспечивает его срабатывание, ответ: он запускается, когда версия базы данных предоставляется конструктору SqLiteOpenHelper обновляется. Вот пример

public class dbSchemaHelper extends SQLiteOpenHelper {

private String sql;
private final String D_TAG = "FundExpense";
//update this to get onUpgrade() method of sqliteopenhelper class called
static final int DB_VERSION = 2; 
static final String DB_NAME = "fundExpenseManager";

public dbSchemaHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    // TODO Auto-generated constructor stub
}

теперь...onUpgrade ()

@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
    sql = "ALTER TABLE " + fundExpenseSchema.Expense.TABLE_NAME + " ADD COLUMN " + fundExpenseSchema.Expense.FUNDID + " INTEGER";
    arg0.execSQL(sql);
}

Если вы используете SQLiteOpenHelper, onUpgrade будет вызываться при каждом изменении версии БД. Существует дополнительное требование, чтобы это сработало. Имя БД должно оставаться неизменным.

Old Version:
dbName = "mydb.db"
dbVersion = 1

New Version:
dbName = "mydb.db"
dbVersion = 2

в onCreate поставщика контента вы создаете экземпляр SQLiteOpenHelper, который принимает эти параметры. Ваша реализация SQLiteOpenHelper будет выглядеть следующим образом:

public static final class MySQLiteOpenHelper extends SQLiteOpenHelper {

        public MySQLiteOpenHelper(Context context, int dbVersion, String dbName) {
            super(context, dbName, null, dbVersion);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            //Code to create your db here
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // Code to upgrade your db here
        }

}

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

информация на этой странице привела меня к моему окончательному решению. Большое спасибо всем участникам!

это решило его для меня...

public class DatabaseHelper extends SQLiteOpenHelper {
    public static String TAG = DatabaseHelper.class.getName();
    private static final int DATABASE_VERSION = 42;
    private static final String DATABASE_NAME = "app_database";
    private static final String OLD_TABLE = "old_and_useless";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion ) {
        if( newVersion > oldVersion) {
            Log.d( TAG, "cool! you noticed." );

            db.execSQL( "DROP TABLE IF EXISTS " + OLD_TABLE );
            // other calls like onCreate if necessary

        } else {
            Log.d( TAG, "Hey! didn't you see me?" );
        }

    }

    public void checkDatabaseVersion() {
        SQLiteDatabase db = this.getWritableDatabase();

        // if the DATABASE_VERSION is newer
        //    onUpgrade is called before this is reached
    }


    // other code removed for readability...
}

это правда, что getWritableDatabase () и getReadableDatabase () приводят к вызову onUpgrade. Я не проверял другие методы, так как они подходят для моих нужд.

продолжайте читать, Кикер идет...

этот код в моей первоначальной деятельности просветил меня, когда я наконец понял, что версия db обновляется во время отладки... тьфу!

DatabaseHelper dbHelper = new DatabaseHelper( this );
dbHelper.checkDatabaseVersion();

Примечание: вызов конструктора DatabaseHelper обновляет версию БД

после вызова конструктора БД была помечена новым версия. Убейте приложение перед вызовом getWritableDatabase() или getReadableDatabase (), и вы находитесь в новой версии. После новых казней никогда не назовет способ запись до DATABASE_VERSION снова увеличивается. (вздох! теперь это кажется до смешного очевидным :)

мое предложение-добавить своего рода" checkDatabaseVersion () " на ранних стадиях вашего приложения. Кроме того, при создании объекта SQLiteOpenHelper убедитесь, что вызывается один из методов (getWritableDatabase(), getReadableDatabase () и т. д.) прежде чем ваше приложение умрет..

Я надеюсь, что это спасет кого-то другого от того же почесывания головы!... : p


заглядывая в SqliteOpenHelper исходный код, мы можем знать onCreate(),onUpgrade() и onDowngrade позвонил в getWritableDatabase() или getReadableDatabase() метод.

public SQLiteDatabase getWritableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(true);
    }
}
public SQLiteDatabase getReadableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(false);
    }
}

private SQLiteDatabase getDatabaseLocked(boolean writable) {
    if (mDatabase != null) {
        if (!mDatabase.isOpen()) {
            // Darn!  The user closed the database by calling mDatabase.close().
            mDatabase = null;
        } else if (!writable || !mDatabase.isReadOnly()) {
            // The database is already open for business.
            return mDatabase;
        }
    }
          . . . . . .  

        final int version = db.getVersion();
        if (version != mNewVersion) {
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
            }

            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

        onOpen(db);

        if (db.isReadOnly()) {
            Log.w(TAG, "Opened " + mName + " in read-only mode");
        }

        mDatabase = db;
        return db;
    } finally {
        mIsInitializing = false;
        if (db != null && db != mDatabase) {
            db.close();
        }
    }
}

это назвал когда вы называете getReadableDatabase или getWritableDatabase.

глубокое погружение:

вы передаете номер версии в конструкторе SQLiteOpenHelper, который хранится в переменной с именем mNewVersion. Вот и все. В этот момент ничего не происходит.

каждый раз, когда вы вызываете getReadableDatabase или getWritableDatabase, он вызовет метод с именем getDatabaseLocked. Этот метод получит существующий номер версии базы данных и сравнит его с mNewVersion.

  1. если база данных с заданным именем не существует, она вызовет onCreate
  2. если новая версия больше, чем старая версия, она будет вызывать onUpgrade.
  3. если новая версия ниже существующей версии, будет создано исключение.
  4. если они равны, он будет идти вперед и откройте базу данных.

что я должен написать в onCreate и onUpgrade ?

onCreate должен содержать код, который создает схему в первый раз.

вы можете оставить onUpgrade пустой первый раз, так как это не в первый раз. Если вы хотите изменить структуру таблицы на более позднем этапе, этот код должен войти сюда.

SQLiteOpenHelper.java(исходный код)

public SQLiteDatabase getWritableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(true);
    }
}

 public SQLiteDatabase getReadableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(false);
    }
}

private SQLiteDatabase getDatabaseLocked(boolean writable) {
   .
   .

     final int version = db.getVersion();

        if (version != mNewVersion) {
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
            }

            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
       }

       onOpen(db);
 }