База данных onUpgrade – oldVersion – newVersion

Я использую этот DataBaseHelper.class, и я застрял в методе onUpgrade (). Я не знаю, как определить, какой номер версии базы данных. Я могу установить версию в 1, когда я впервые опубликую ее, и когда я опубликую обновление, я просто могу установить версию на 2 (myDataBase.setVersion(2);) . Но это будет всего 2, пока приложение работает. В следующий раз, когда он будет запущен, он снова будет 1. То же самое происходит с private static int DATABASE_VERSION . Я думал о сохранении номера версии в дополнительной таблице, но это не похоже на лучшую практику на мой взгляд.

Итак, как вы убедитесь, что число версий увеличилось после обновления и что оно хранит его (значение, которое было назначено private static int DATABASE_VERSION или myDataBase.getVersion(); )?

Класс DataBaseHelper:

 public class DataBaseHelper extends SQLiteOpenHelper { //The Android's default system path of your application database. private static String DB_PATH = "/data/data/com.mydatabase.db/databases/"; private static String DB_NAME = "database.sl3"; private SQLiteDatabase myDataBase; private final Context myContext; // Do you need this? private static int DATABASE_VERSION = 2; // or is this correct: // private static int DATABASE_VERSION = myDataBase.getVersion(); /** * Constructor * Takes and keeps a reference of the passed context in order to access to * the application assets and resources. * * @param context */ public DataBaseHelper(Context context) { super(context, DB_NAME, null, DATABASE_VERSION); this.myContext = context; } /** * Creates an empty database on the system and rewrites it with your own * database. * */ public void createDataBase() throws IOException { boolean dbExist = checkDataBase(); if (dbExist) { } else { //By calling this method and empty database will be created into the default system path //of your application so we are gonna be able to overwrite that database with our database. this.getWritableDatabase(); try { copyDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } } } /** * Check if the database already exist to avoid re-copying the file each * time you open the application. * * @return true if it exists, false if it doesn't */ private boolean checkDataBase() { SQLiteDatabase checkDB = null; try { String myPath = DB_PATH + DB_NAME; checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); } catch (SQLiteException e) { //database does't exist yet. } if (checkDB != null) { checkDB.close(); } return checkDB != null ? true : false; } /** * Copies your database from your local assets-folder to the just created * empty database in the * system folder, from where it can be accessed and handled. * This is done by transfering bytestream. * */ private void copyDataBase() throws IOException { //Open your local db as the input stream InputStream myInput = myContext.getAssets().open(DB_NAME); // Path to the just created empty db String outFileName = DB_PATH + DB_NAME; //Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); //transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } //Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } public void openDataBase() throws SQLException { //Open the database String myPath = DB_PATH + DB_NAME; myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); // Which parameters do I have to pass? onUpgrade(myDataBase, DATABASE_VERSION, 2); } @Override public synchronized void close() { if (myDataBase != null) myDataBase.close(); super.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion) { Log.d ("onUpgrade first log", Integer.toString(myDataBase.getVersion())); if (oldVersion == 1) { // do something // And then do this!? DATABASE_VERSION = 2; // or do this myDataBase.setVersion(2); Log.d ("onUpgrade sedond log", Integer.toString(myDataBase.getVersion())); } else { Log.d("onUpgrade", "else-clause: Already upgraded!"); } } 

 // Do you need this? private static int DATABASE_VERSION = 2; 

Да, вам это нужно. (Еще лучше, сделайте это final тоже.)

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

Когда ваше приложение запускается, помощник выполняет проверку во время выполнения, что идея вашего кода о последней версии такая же, как версия, которая была активной, когда база данных была в последний раз создана или обновлена. (Для этого используется db.getVersion() .) Если числа не совпадают, то помощник знает, что сохраненная база данных устарела в отношении кода вашего приложения, и поэтому она запускает процедуру обновления.

Похоже, что вы не создаете базу данных с нуля, а импортируете существующую базу данных из своих активов. Когда вы выполняете этот первоначальный импорт, это время, в течение которого сохраненная версия соответствует версии вашего кода; Либо применить его непосредственно к файлу базы данных в ваших активах, либо, если вы уверены, что файл базы данных в ваших активах соответствует коду, вы вызываете setVersion(DATABASE_VERSION) .

В любом случае вам не следует пытаться изменить номера версий в onUpgrade() . Это когда-либо вызывается, если версии не совпадают, и все, что вы должны здесь делать, это сделать все изменения, необходимые для обновления базы данных. Помощник будет управлять сохранением нового номера версии после завершения обновления.

Добавляем некоторую информацию в ответ Грэма Борланд. Я объясню сценарий приложения, в котором ваша база данных находится в папке с ресурсами, и вы скопируете ее в свою папку с папкой, если ее еще не существует. Теперь, если вы хотите обновить приложение с помощью обновленной базы данных. Вам необходимо установить

  private final static int DB_VERSION=2; // Database Version 

В вашем вспомогательном классе базы данных.

(Любое целое число, которое должно быть больше, чем начальная версия db, которую вы задали в этом классе)

После этого вам нужно добавить код для переопределения onUpgrade () В этом сценарии я перезаписываю старый db с последним. Вы можете изменить свой код по своему вкусу

 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub CopyNewDatabaseFromAsset(); } 

Если вам нужно какое-либо объяснение, напишите в комментарии 🙂