Android SQLite:使用新数据库替换旧数据库或使用迁移脚本

时间:2016-10-10 20:50:20

标签: android database sqlite

我有一个使用SQLite数据库和Active Android作为ORM的Android应用。在每次应用更新时,我需要使用新的/更新的数据发送我的数据库。这就是我一直在做的事情

  1. 我有 my_app.db 数据库
  2. 我对 my_app.db
  3. 的行,表格等进行了修改
  4. 我将修改后的 my_app.db 保存为 my_app_v2.db (依此类推)
  5. 我用 my_app_v2.db 替换assets文件夹的 my_app.db 文件,并将其设置为默认数据库
  6. 我使用新创建的 my_app_v2.db
  7. 编译并运行程序

    因此,当用户获取应用时,它将使用带有新内容的 my_app_v2.db

    我知道Active Android supports migration scripts,但在每次数据库更新时,我需要添加/更新大约2000多条记录。因此,对于每个数据库更新,我需要一个包含2000多个插入/更新语句的迁移脚本,这意味着对于3个以上的连续升级,应用程序必须执行大约6000多个语句。

    我想知道我的方法是用新方法替换整个数据库是不好的做法,应该首选迁移脚本。

3 个答案:

答案 0 :(得分:5)

你不需要这样做(重命名的东西或任何东西)

您只需更改数据库版本并编写sql命令即可更改上一个表以从A版迁移到B.

请看这个链接:

Android: upgrading DB version and adding new table

答案 1 :(得分:0)

我不确定您是否可以在您的应用上应用这种方式,但我正在做的是从另一个数据库中检索新数据。

对于我的应用,我使用同步系统,每天都会检查GoogleDrive上是否有新的数据库(如果用户使用不同的设备)。

当新的数据库备份可用时(意味着我必须检索此设备的数据),我将使用以下命令取回数据库备份并将其附加到现有数据库备份:

attach database database/path as new_db

然后我只为每个表执行此命令,以便使用我检索到的记录更新现有数据库:

INSERT OR REPLACE INTO table SELECT * FROM retrieved_database.table

当然它将替换所有现有数据,但这样我也会处理已修改的记录。这种方法避免了完全替换现有数据库,我只是在最后运行完整性检查,以确保一切正常。

这个方法对我来说没问题,因为我有几个表,数据很轻,对于繁重的数据库来说可能不是一个好主意。

答案 2 :(得分:0)

在我的项目中,我像这样使用

public class DatabaseHelper extends SQLiteOpenHelper {

private final static String TAG = DatabaseHelper.class.getSimpleName();
private static DatabaseHelper sInstance;
private Context mContext;
private static final String DATABASE_NAME = "xxxx";
private static final String DATABASE_NAME_OLD = "xxxx_old";
private static final int DATABASE_VERSION = 12;
private String pathToSaveDBFile, absolutepathToSaveDBFile;
private SQLiteDatabase db;
private Cursor cursor;



public static synchronized DatabaseHelper getInstance(Context mContext) {
    if (sInstance == null) {
        sInstance = new DatabaseHelper(mContext);
    }
    return sInstance;
}

/**
 * initialization constructor
 *
 * @param context
 */

private DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.mContext = context;
    pathToSaveDBFile = new StringBuffer(context.getFilesDir().getAbsolutePath()).append("/").append(DATABASE_NAME).toString();
    absolutepathToSaveDBFile = new StringBuffer(context.getFilesDir().getAbsolutePath()).append("/").append(DATABASE_NAME_OLD).toString();

}

/**
 * prepare database related process
 *
 * @throws IOException
 */
public void prepareDatabase() throws IOException {
    //boolean dbExist = checkDataBase();
    if (checkDataBase()) {
        Log.d(TAG, "Database exists.");
  //            int currentDBVersion = getVersionId();
        if (DATABASE_VERSION > getVersionId()) {
            Log.d(TAG, "Database version is higher than old.");
                  if (renameDatabase()) {
                      Log.d(TAG, "renameDatabase() ");

                       try {
                           if (copyDataBase()) {


                                     deleteDb();
                                      setVersionId(DATABASE_VERSION);
                                 }




                    } catch (Exception e) {
                        Log.e(TAG, e.getMessage());
                    }
                }


        }
    } else {
        try {
            /// copy db
            copyDataBase();
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }
}


/**
 * db exist or not?
 *
 * @return db checked status
 */
private boolean checkDataBase() {
    Log.d(TAG, "checkDataBase()");
    boolean checkDB = false;
    try {
        File file = new File(pathToSaveDBFile);
        checkDB = file.exists();
    } catch (SQLiteException e) {
        Log.d(TAG, e.getMessage());
    }
    Log.d(TAG, "checkDataBase: " + checkDB);
    return checkDB;
}

/**
 * db copying
 *
 * @return db copy status
 */
private Boolean copyDataBase() {
    try {
        Log.d(TAG, "copyDataBase()");
        OutputStream os = new FileOutputStream(pathToSaveDBFile);
        InputStream is = mContext.getAssets().open("db/" + DATABASE_NAME);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        is.close();
        os.flush();
        os.close();
        return true;
    } catch (IOException e) {
        e.getMessage();
        return false;
    }

}

/**
 * db renaming
 *
 * @return boolean status
 */
private boolean renameDatabase() {
    try {
        Log.d(TAG, "renameDatabase: ");
        File from = new File(pathToSaveDBFile);
        File to = new File(absolutepathToSaveDBFile);
        if (from.renameTo(to)) {
            return true;
        }
        return false;

    } catch (Exception e) {
        e.getMessage();
        return false;
    }

}

/**
 *
 *
 * @return boolen status
 */
private boolean revertBack_to_OlderName() {
    try {
        Log.d(TAG, "renameDatabase: ");
        File from = new File(absolutepathToSaveDBFile);
        File to = new File(pathToSaveDBFile);
        if (from.renameTo(to)) {
            return true;
        }
        return false;

    } catch (Exception e) {
        e.getMessage();
        return false;
    }

}

/**
 * db deletion
 *
 * delete db
 */
public void deleteDb() {
    File file = new File(absolutepathToSaveDBFile);
    if (file.exists()) {
        file.delete();
        Log.d(TAG, "Database deleted.");
    }
}


@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {

}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}

@Override
public synchronized void close() {
    db.close();
    super.close();
}



/**
 * get db version info
 *
 * @return version no
 */
private int getVersionId() {
    try {
        db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READONLY);
        String query = "SELECT " + AS_DB_VERSION_NUMBER + " FROM " + AS_DB_VERSION_TABLE;
        cursor = db.rawQuery(query, null);
        cursor.moveToFirst();
        int v = cursor.getInt(0);
        cursor.close();
        close();
        return v;
    } catch (SQLiteException e) {
        e.getMessage();
        return 0;
    }


}

/**
 * set db version no to
 * @param version
 *
 * @return status
 */
private boolean setVersionId(int version) {
    try {
        db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READWRITE);
        ContentValues values = new ContentValues();
        values.put(AS_DB_VERSION_NUMBER, version);
        db.update(AS_DB_VERSION_NUMBER, values, AS_DB_VERSION_ID + " = 1", null);
        close();
        return true;
    } catch (SQLiteException e) {
        e.getMessage();
        return false;
    }
  }
 }

您可以在比赛中使用这些代码