Вызывается ли когда-либо метод onUpgrade?
-
02-10-2019 - |
Вопрос
Это onUpgrade
метод SQLiteOpenHelper
когда-нибудь звонил?Если да, то когда он вызывается и чем?Если он не вызывается разработчиками, то почему он там?Что на самом деле происходит с этой функцией?Я видел примеры, когда он удалял все таблицы, но затем в комментарии говорилось, что удаление всех таблиц — это не то, что вам следует делать.Какие-либо предложения?
Решение
Это называется при создании SQLiteopenheelper с версией новее, чем версия открытой базы данных. Что делать, зависит от изменений в базе данных, выполненных между старыми и новыми версиями. Единственный случай, когда вы не бросаете измененную таблицу, заключается в том, когда изменение является изменением более чем дополнительной колонны. Затем вы можете использовать оператор 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);
}
Если вы используете SQLiteopenheelper, onupgrade будет вызываться всякий раз, когда вы изменяете версию БД. Для этого требуется дополнительное требование. Имя БД должно оставаться прежним.
Old Version:
dbName = "mydb.db"
dbVersion = 1
New Version:
dbName = "mydb.db"
dbVersion = 2
В Oncreate поставщика контента вы создаете экземпляр SQLiteopenheelper, который требует следующих параметров. Ваша реализация 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 вызывается. Я начинал думать, что Android был серьезным недостатком ..
Информация на этой странице привела меня к моему окончательному разрешению. Спасибо кучу всем участникам!
Это решило это для меня ...
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...
}
Это правда, что getwritabledabaseabase () и getReadabledabaseabase () делает результат в вызове onupgrade. Я не проверял другие методы, так как они соответствуют законопроекту за мои потребности.
Продолжайте читать, кикер придет ...
Этот код в моей начальной деятельности просветил меня, когда я наконец понял, что версия БД обновляла во время моей отладки ... фу!
DatabaseHelper dbHelper = new DatabaseHelper( this );
dbHelper.checkDatabaseVersion();
Примечание. Вызов конструктора DatabaseHelper обновляет версию БД
После звонка конструктора DB была помечена новой версией. Убейте приложение перед вызовом getwritabledatabase () или getReadabledabaseabase (), а вы на новой версии. После этого новые казнения никогда не вызывают метод onupgrade до тех пор, пока не будет увеличена database_version. (вздох! Теперь это кажется смешным очевидным :)
Мое предложение состоит в том, чтобы добавить какую-то «CheckDatabaseversion ()» на ранние этапы вашего приложения. Кроме того, если вы создаете объект SQLiteopenHelper, убедитесь, что вы называете один из методов (getWritabledabase (), getReadabledableabase () и т. Д.) Перед умиранием вашего приложения ..
Я надеюсь, что это спасает кого-то еще ту же голову, царапаясь! ...: 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
. Отказ Вот и все. В этот момент ничего не происходит.
Каждый раз, когда вы называете GETREADBALDALDATABASE или GETWRITALDATHATABASE, он будет вызывать метод под названием getDatabaseLocked
. Отказ Этот метод получит существующую версию номер базы данных и сравнивает его с mNewVersion
.
- Если база данных с указанным именем не существует, это позвонит
onCreate
- Если новая версия больше, чем старая версия, она позвонит
onUpgrade
. - Если новая версия ниже существующей версии, будет брошена исключение.
- Если они равны, это будет идти вперед и откройте базу данных.
Что я должен писать в oncreate и Onupgrade?
onCreate
должен содержать код, который создает схему в первый раз.
Ты можешь уйти onUpgrade
Пустой первый раз, поскольку он не будет вызван в первый раз. Когда вы хотите изменить структуру таблицы на более позднем этапе, этот код должен идти здесь.
Sqliteopenheelper.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);
}