不會覆蓋。SQLiteOpenHelper.onCreate(SQLiteDatabase db) **只有在資料庫檔案不存在時** 才會被呼叫一次。同一個 DBHelper 實例或多個實例,只要資料庫檔案已存在(版號相同),onCreate 就**不會再次執行**。
getWritableDatabase() / getReadableDatabase() 內部呼叫 SQLiteDatabase.openOrCreateDatabase()。onCreate(db)。PRAGMA user_version 取得現有版號 → 與建構子傳入的 newVersion 比較:
onUpgrade(db, oldVersion, newVersion)。SQLiteException(降級不支援)。public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "test.db";
private static final int VERSION = 1;
public DBHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("DB", "onCreate 執行了");
db.execSQL("CREATE TABLE IF NOT EXISTS t (id INTEGER PRIMARY KEY)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
Log.d("DB", "onUpgrade 執行了");
}
}
// Activity 中
new DBHelper(this).getWritableDatabase(); // 第 1 次:印 onCreate
new DBHelper(this).getWritableDatabase(); // 第 2 次:無日誌
new DBHelper(this).getWritableDatabase(); // 第 N 次:無日誌
CREATE TABLE IF NOT EXISTS?IF NOT EXISTS 避免拋出「table already exists」錯誤。// 版本從 1 升至 2
private static final int VERSION = 2;
@Override
public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
if (oldV == 1 && newV == 2) {
db.execSQL("ALTER TABLE t ADD COLUMN name TEXT");
// 或建立新表、遷移資料、刪舊表、改名
}
}
onCreate 由框架保證**僅在資料庫首次建立時執行一次**,重複實例化 DBHelper 不會重複建表。專注於 onUpgrade 實作平滑遷移即可。