Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用onUpgrade备份旧数据库、替换数据库和恢复数据_Java_Android_Sqlite - Fatal编程技术网

Java 使用onUpgrade备份旧数据库、替换数据库和恢复数据

Java 使用onUpgrade备份旧数据库、替换数据库和恢复数据,java,android,sqlite,Java,Android,Sqlite,在我的应用程序中,我通过资产文件夹提供数据库的最新版本。为了简单起见,假设我的DB方案是PRIM KEY INTEGER _id、文本名和整数数量。数量是用户可以在应用程序中编辑的唯一内容,其他所有内容都是静态数据。数量默认为0 以下是我目前在Upgrade上尝试做的事情: 1.)遍历所有表,找到数量大于0的条目,并将这些条目存储在包含ID和数量值以及原始表名的对象列表中 2.)删除我刚才遍历的旧数据库 3.)从包含更新静态信息的资产复制新数据库 4.)迭代步骤1中的列表,并使用相应表格中的数量

在我的应用程序中,我通过资产文件夹提供数据库的最新版本。为了简单起见,假设我的DB方案是PRIM KEY INTEGER _id、文本名和整数数量。数量是用户可以在应用程序中编辑的唯一内容,其他所有内容都是静态数据。数量默认为0

以下是我目前在Upgrade上尝试做的事情:

1.)遍历所有表,找到数量大于0的条目,并将这些条目存储在包含ID和数量值以及原始表名的对象列表中

2.)删除我刚才遍历的旧数据库

3.)从包含更新静态信息的资产复制新数据库

4.)迭代步骤1中的列表,并使用相应表格中的数量更新相应的ID

这是我的onUpdate方法(titleArray是包含我的表名的字符串数组):

@覆盖
public void onUpgrade(SQLiteDatabase db,int-oldVersion,int-newVersion){
Log.w(“TaskDBAdapter”,“从版本“+oldVersion+”升级到“+newVersion”);
ArrayList bak=新的ArrayList();
游标=空;
对于(int i=0;i0”,空);
if(cursor.moveToFirst()){
做{
备份密钥=新备份密钥(titleArray[i],
cursor.getInt(cursor.getColumnIndex(“\u id”),
cursor.getInt(cursor.getColumnIndex(“数量”));
添加(键);
}while(cursor.moveToNext());
}
}
cursor.close();
myContext.deleteDatabase(数据库名称);
尝试
{
InputStream myInput=myContext.getAssets().open(DB_NAME);
字符串outFileName=DB_路径+DB_名称;
OutputStream myOutput=新文件OutputStream(outFileName,false);
字节[]缓冲区=新字节[1024];
整数长度;
而((长度=myInput.read(缓冲区))>0){
写入(缓冲区,0,长度);
}
myOutput.flush();
myOutput.close();
myInput.close();
}捕获(IOE异常)
{
Log.w(“taskdadapter”、“failed”);
抛出新错误(“复制数据库时出错”);
}
对于(int i=0;i
我可以确认arraylist已成功填充正确的数据。我以前试图覆盖数据库,但似乎从来没有起过作用。我必须添加myContext.deleteDatabase(DB_NAME);在成功替换数据库的文件写入操作之前。我可以确认我的最终更新迭代没有生成任何奇怪的数据——它具有表名、id和数量的正确值

问题是,数量在我升级后没有更新。静态数据将更新为我在资产文件夹中包含的最新版本,但数量数据不会更新。这是因为我破坏了最初提供给该方法的数据库(在本例中是“db”参数)?这就是参数吗?如何在新数据库中更新数据


另外:如果有更好的方法,我洗耳恭听=)

onUpgarde()
用于更新数据库结构(添加/重命名列等),而不是实际数据。第一次启动时,您可能希望在实际应用程序中执行此操作。此外,尝试就地升级用户输入的数据可能不是最好的主意。为什么没有两个表(甚至数据库)——一个包含您提供的数据,另一个包含用户输入的数据?您可以简单地复制用户编辑的行,并将原始数据保留为只读

我原以为它是用来更新结构的,但在我之前的问题中,我听说它是处理数据更新和模式更新的合适地方。。。好吧,这对我的计划是一个打击。当数据库需要升级时,会调用引用文档。实现应使用此方法删除表、添加表或执行升级到新架构版本所需的任何其他操作。“您当然可以执行任何操作,但由于这是在应用程序首次使用DB时自动调用的,因此您无法对其进行太多控制。如果你需要进行长时间的数据更新,最好在应用程序处于稳定状态时通知用户(并可能为他们提供选项)。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    Log.w("TaskDBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion);


    ArrayList<backupKey> bak = new ArrayList<backupKey>();

    Cursor cursor = null;
        for(int i = 0; i < titleArray.length; i++)
        {
             cursor = db.rawQuery("SELECT * FROM " + titleArray[i] + " WHERE quantity > 0", null);
             if (cursor.moveToFirst()){
                   do{
                       backupKey key = new backupKey(titleArray[i],
                               cursor.getInt(cursor.getColumnIndex("_id")),
                               cursor.getInt(cursor.getColumnIndex("quantity")));
                       bak.add(key);

                   }while(cursor.moveToNext());
                }

        }
        cursor.close();

        myContext.deleteDatabase(DB_NAME);

        try 
        {
            InputStream myInput = myContext.getAssets().open(DB_NAME);

            String outFileName = DB_PATH + DB_NAME;

            OutputStream myOutput = new FileOutputStream(outFileName, false);


            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer))>0){
                myOutput.write(buffer, 0, length);
            }

            myOutput.flush();
            myOutput.close();
            myInput.close();

        } catch (IOException e) 
        {
            Log.w("TaskDBAdapter", "failed");
            throw new Error("Error copying database");

        }

    for (int i = 0; i < bak.size(); i++)
    {

        ContentValues args = new ContentValues();
        args.put("quantity", bak.get(i).quantity);
        String where = "_id = ?";
        String[] whereArgs = {Integer.toString(bak.get(i).id)};
        db.update(bak.get(i).range, args, where, whereArgs);
    }

} //End of onUpgrade