数据库sqlite。更新而不会丢失数据

时间:2018-12-18 11:34:40

标签: android sqlite android-sqlite

有一个带有下列字段的表格:ID,标题,诗歌,年份,收藏夹。 因此,收藏夹被写为1或0,默认值为0,如果用户在“收藏夹”中添加一行,它将更改。 问题是,如果我更新数据库(添加更多行),则所有收藏夹将从用户中消失。 在SO的开放空间中,我找到了一个解决方案-附加旧的和更新的数据库。我增加版本,将数据库添加到项目中。在应用程序中,所有内容将保持原样。收藏夹已保留,但未添加新收藏夹。

 public class PoemsDbHelper extends SQLiteOpenHelper {
        private static String DB_NAME = "brodsky.db";
        private static String DB_PATH = "";
        private static final int DB_VERSION = 8;

        private SQLiteDatabase db;
        private final Context context;
        private boolean needUpdate = false;

        public PoemsDbHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
            if (android.os.Build.VERSION.SDK_INT >= 17)
                DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
            else
                DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
            this.context = context;

            copyDataBase();

            this.getReadableDatabase();
        }

        public void updateDataBase() throws IOException {
            if (needUpdate) {
                File dbFile = new File(DB_PATH + DB_NAME);
                if (dbFile.exists()) {
                    //   dbFile.delete();
                    //   copyDataBase();
                    openDataBase();
                    db.execSQL("ATTACH DATABASE '" + DB_PATH + File.separator + DB_NAME + "' AS Old_DB");
                    db.execSQL("INSERT OR IGNORE INTO poems_table (favorite) SELECT id, title, poem, subject, years FROM Old_DB.poems_table;");

                    }
            }
            needUpdate = false;
        }

        private boolean checkDataBase() {
            File dbFile = new File(DB_PATH + DB_NAME);
            return dbFile.exists();
        }

        private void copyDataBase() {
            if (!checkDataBase()) {
                this.getReadableDatabase();
                this.close();
                try {
                    copyDBFile();
                } catch (IOException mIOException) {
                    throw new Error("ErrorCopyingDataBase");
                }
            }
        }

        private void copyDBFile() throws IOException {
            InputStream input = context.getAssets().open(DB_NAME);
            OutputStream output = new FileOutputStream(DB_PATH + DB_NAME);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = input.read(buffer)) > 0)
                output.write(buffer, 0, length);
            output.flush();
            output.close();
            input.close();
        }

        public boolean openDataBase() throws SQLException {
            db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
            return db != null;
        }

        @Override
        public synchronized void close() {
            if (db != null)
                db.close();
            super.close();
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (newVersion > oldVersion) {
                needUpdate = true;

          }
       }
    }



 public class PoemsProvider extends ContentProvider {
 @Override
    public boolean onCreate() {
        poemsDbHelper = new PoemsDbHelper(getContext());
        try {
            poemsDbHelper.updateDataBase();
        } catch (IOException mIOException) {
            throw new Error("UnableToUpdateDatabase");
        }

        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

您的问题是您要覆盖数据库,而不是拥有旧数据库和更新后数据库的两个不同副本。基本上,您是将数据库附加到自身。

已经在Update DB. Sqlite-asset-helper library

提供了一种解决方案

该解决方案使用辅助数据库(从资产文件夹复制更新的数据库),并尝试将行从更新的数据库复制到原始数据库,而不复制(跳过)行(如果已存在)。应用添加的行(与外部数据库加载的行相反)保留在原始数据库中。