AnUpgradeメソッドはこれまでに呼び出されましたか?
-
02-10-2019 - |
質問
それは onUpgrade
の方法 SQLiteOpenHelper
電話したことがありますか?もしそうなら、それはいつ呼ばれ、何によって?開発者から呼び出されていない場合、なぜそこにいるのですか?その機能はどうなりますか?私はそれがすべてのテーブルを落とす例を見ましたが、その後、すべてのテーブルをドロップすることはあなたがすべきことではないとコメントしています。助言がありますか?
解決
開いたデータベースのバージョンよりも新しいバージョンを使用して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を使用している場合、dbバージョンを変更するたびにオンアップグラードが呼び出されます。これが機能するための追加の要件があります。 DB名は同じままでなければなりません。
Old Version:
dbName = "mydb.db"
dbVersion = 1
New Version:
dbName = "mydb.db"
dbVersion = 2
コンテンツプロバイダーの作成では、これらのパラメルを取得する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
}
}
すべての投稿をレビューしてデバッグコードを実行しているのは、オンアップグラードが呼び出されるのを見ると、まだ明確ではありませんでした。 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...
}
getWritableDatabase()およびgetReadableDataBase()がオンアップグラードコールを作成するのは事実です。これらは私のニーズに合った法案に適合しているため、他の方法をチェックしませんでした。
読み続けてください、キッカーが来ています...
私の最初のアクティビティのこのコードは、DBバージョンがデバッグ中に更新されていることにようやく気付いたときに私を啓発しました... うーん!
DatabaseHelper dbHelper = new DatabaseHelper( this );
dbHelper.checkDatabaseVersion();
注:データベースヘルパーコンストラクターを呼び出すDBバージョンが更新されます
コンストラクターの呼び出し後、DBは新しいバージョンでタグ付けされました。 getWritableDatabase()またはgetReadableDataBase()に電話をかける前にアプリを殺してください。新しいバージョンに参加してください。その後、Database_versionが再び増加するまで、新しい実行はOnUpgradeメソッドを呼び出すことはありません。 (はぁ!今では馬鹿げているように見えます :)
私の提案は、アプリの初期段階にある種の「checkdatabaseversion()」を追加することです。あるいは、SQLiteOpenHelperオブジェクトを作成する場合は、アプリが死ぬ前にメソッド(getWritableDABase()、getReadAbleadAbase()など)のいずれかを呼び出すことを確認してください。
これにより、他の誰かが同じ頭を掻くと救うことを願っています!...: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
.
- 指定された名前のデータベースが存在しない場合、それは呼び出します
onCreate
- 新しいバージョンが古いバージョンよりも大きい場合は呼び出します
onUpgrade
. - 新しいバージョンが既存のバージョンよりも低い場合、例外がスローされます。
- それらが等しい場合、それは先に進み、データベースを開きます。
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);
}