Android 更新数据库。Sqlite资产助手库

Android 更新数据库。Sqlite资产助手库,android,sqlite,Android,Sqlite,我使用图书馆 有必要进行更新,但用户必须保存数据。表、列的名称保持不变。只有表中的条目数增加了 我增加了数据库版本。将数据库放入存档。如创建文件-brodsky.db\u upgrade\u 1-2.sql的说明所述 ALTER TABLE "poems_table" RENAME TO 'poems_table_TMP'; CREATE TABLE "poems_table" ( "id" long NOT NULL, "title" text, "poem" text,

我使用图书馆

有必要进行更新,但用户必须保存数据。表、列的名称保持不变。只有表中的条目数增加了

我增加了数据库版本。将数据库放入存档。如创建文件-brodsky.db\u upgrade\u 1-2.sql的说明所述

ALTER TABLE "poems_table" RENAME TO 'poems_table_TMP'; CREATE TABLE
        "poems_table" ( "id" long NOT NULL, "title" text, "poem" text,
        "subject" text, "years" text, "favorite" text, PRIMARY KEY ("id") );
        INSERT INTO "poems_table"  ("id", "title", "poem", "subject",
        "years", "favorite") SELECT "id", "title", "poem", "subject",
        "years", "favorite" FROM "poems_table_TMP"; DROP TABLE
        "poems_table_TMP";
数据库助手

public class PoemsDbHelper extends SQLiteAssetHelper {

    private static String DB_NAME = "brodsky.db";
    private static final int DB_VERSION = 2;

    public PoemsDbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }
}

没有什么变化。显示代码中的旧数据,假设代码在onUpgrade方法中,并且版本从1更改为2,则代码没有任何用处。就是这样:-

  • 重命名旧数据库的poems_表
  • 创建一个新表
  • 将重命名表的内容复制到新创建的表中
  • 删除重命名后的表格
  • 它在任何地方都无法访问更新版本的brodsky.db

    您需要(我相信)做的是打开更新的brodsky.db并从该数据库复制数据

    工作示例 下面是这样一个工作示例的代码

    当数据库版本增加时(为了简单起见,任何升级),这将:-

  • 将新更新的数据库复制为单独/附加数据库,然后
  • 尝试将更新数据库中的行复制到现有数据库中
  • 仅当它们不是现有行时(基于除id列之外的所有列,因为最终用户可能添加了poems并因此使用了id)
  • 核心代码在poemdbhelper.java中,是:-

    public class PoemsDbHelper extends SQLiteAssetHelper {
    
        public static final String DBNAME = "brodsky.db";
        public static final int DBVERSION = 1;
    
        public static final String TBLNAME = "poems_table";
    
        public static final String COL_ID = "id";
        public static final String COL_TITLE = "title";
        public static final String COl_POEM = "poem";
        public static final String COL_SUBJECT = "subject";
        public static final String COL_YEARS = "years";
        public static final String COL_FAVOURITE = "favorite";
    
        Context mContext;
    
        public PoemsDbHelper(Context context) {
            super(context, DBNAME, null, DBVERSION);
            mContext = context;
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            getNewPoems(mContext, db); //<<<<<<<<<< get the new poems when upgraded
        }
    
    
        private void getNewPoems(Context context, SQLiteDatabase db) {
    
            Log.d("GETNEWPOEMS","Initiating getting new poems due to Database version increased.");
    
            // Prepare to copy the updated database from the assets folder
            InputStream is;
            OutputStream os;
            final String tempnewdbname = "tempbrodsky.db";
            int buffersize = 4096;
            byte[] buffer = new byte[buffersize];
            String newDBPath = mContext.getDatabasePath(tempnewdbname).getPath();
    
            // If a copied version of the updated database exists then delete it
            // This should not be required but better safe than sorry
            File newDBFile = new File(newDBPath);
            if (newDBFile.exists()) {
                newDBFile.delete();
            }
    
            // Just in case create the databases directory (it should exist)
            File newDBFileDirectory = newDBFile.getParentFile();
            if (!newDBFileDirectory.exists()) {
                newDBFileDirectory.mkdirs();
            }
    
            // Preapre to copy update database from the assets folder
            try {
                is = context.getAssets().open("databases/" + DBNAME);
                os = new FileOutputStream(newDBFile);
                int bytes_read;
                while ((bytes_read = is.read(buffer,0,buffersize)) > 0) {
                    os.write(buffer);
                }
                os.flush();
                os.close();
                is.close();
    
            }catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("Ouch updated database not copied - processing stopped - see stack-trace above.");
            }
    
            long id = maxid(db) + 1; // Get the next available id
            SQLiteDatabase newdb = SQLiteDatabase.openDatabase(newDBFile.getPath(),null,SQLiteDatabase.OPEN_READONLY);
            Cursor csr = newdb.query(TBLNAME,null,null,null,null,null,null);
            long insert_result;
            db.beginTransaction();
            while (csr.moveToNext()) {
                insert_result = insertCorePoem(
                        db,
                        id,
                        csr.getString(csr.getColumnIndex(COL_TITLE)),
                        csr.getString(csr.getColumnIndex(COl_POEM)),
                        csr.getString(csr.getColumnIndex(COL_SUBJECT)),
                        csr.getString(csr.getColumnIndex(COL_YEARS)),
                        csr.getString(csr.getColumnIndex(COL_FAVOURITE))
                );
                // If the row was inserted then increment the if ready for the next insert
                // If not inserted (result = -2) then leave id as it is as it was unused
                if (insert_result > 0) {
                    id++;
                }
    
            }
            db.setTransactionSuccessful();
            db.endTransaction();
            csr.close();
            newDBFile.delete(); // Delete the copied database as no longer required
        }
    
        public long insertCorePoem(SQLiteDatabase db, long id, String title, String poem, String subject, String years, String favourite) {
    
            String whereclause = COL_TITLE + "=? AND " + COl_POEM + "=? AND " + COL_SUBJECT + "=? AND " + COL_YEARS + "=?";
            String[] whereargs = new String[]{
                    title,
                    poem,
                    subject,
                    years
            };
    
            Cursor csr = db.query(TBLNAME,null,whereclause,whereargs,null,null,null);
            boolean rowexists = (csr.getCount() > 0);
            csr.close();
            if (rowexists) {
                Log.d("INSERTCOREPOEM","Skipping insert of row");
                return -2; // Don't insert if the poem already exists
            }
    
            ContentValues cv = new ContentValues();
            cv.put(COL_ID,id);
            cv.put(COL_TITLE,title);
            cv.put(COl_POEM,poem);
            cv.put(COL_SUBJECT,subject);
            cv.put(COL_YEARS,years);
            cv.put(COL_FAVOURITE,favourite);
            Log.d("INSERTCOREPOEM","Inserting new column with id " + String.valueOf(id));
            return db.insert(TBLNAME, null, cv);
        }
    
        private long maxid(SQLiteDatabase db) {
            long rv = 0;
            String extractcolumn = "maxid";
            String[] col = new String[]{"max(" + COL_ID + ") AS " + extractcolumn};
            Cursor csr = db.query(TBLNAME,col,null,null,null,null,null);
            if (csr.moveToFirst()) {
                rv = csr.getLong(csr.getColumnIndex(extractcolumn));
            }
            csr.close();
            return rv;
        }
    
        public Cursor getAllPoems() {
            SQLiteDatabase db = this.getWritableDatabase();
            return db.query(TBLNAME,null,null,null,null,null,null);
        }
    }
    
    第1阶段-验证/检查现有数据库 首次运行时,将从assets文件夹复制数据库(包含3首诗),日志包含以下内容(无论何时运行应用程序):-

    • 注意您可能需要在insertcorepoise方法中定制查询以满足您的需要

    你能帮我吗?你的代码不起作用。申请失败。Logs-java.lang.RuntimeException:无法启动活动组件信息{rodionova.lyubov.test/rodionova.lyubov.test.MainActivity}:com.readystatesoftware.sqliteasset.sqliteAssetThelper$SQLiteAssetException:资产中缺少数据库/brodsky.db文件(或.zip.gz存档),或者目标文件夹不可写错误-在rodionova.lyubov.test.poemdbhelper.getAllPoems(poemdbhelper.java:156)我自己已经找了两天的错误了。虽然我知道您的回答在逻辑上是正确的,但该消息通常是因为brodsky.db文件不在assets/databases文件夹中。如上所述,资产/数据库文件夹中的原始数据库将替换为原始数据库的修改版本。这样一来,所有的核心数据都将应用于新安装以及以前软件包的升级。你是对的。非常感谢您如此详细的解释!
    public class MainActivity extends AppCompatActivity {
        PoemsDbHelper mDBHlpr;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mDBHlpr = new PoemsDbHelper(this);
            Log.d("DBVERSION", "Database version = " + String.valueOf(PoemsDbHelper.DBVERSION));
            Cursor csr = mDBHlpr.getAllPoems();
            DatabaseUtils.dumpCursor(csr);
            csr.close();
        }
    }
    
    12-18 06:19:58.505 3574-3574/? D/DBVERSION: Database version = 1
    12-18 06:19:58.505 3574-3574/? W/SQLiteAssetHelper: copying database from assets...
    12-18 06:19:58.505 3574-3574/? W/SQLiteAssetHelper: database copy complete
    12-18 06:19:58.521 3574-3574/? I/SQLiteAssetHelper: successfully opened database brodsky.db
    12-18 06:19:58.521 3574-3574/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534758c8
    12-18 06:19:58.521 3574-3574/? I/System.out: 0 {
    12-18 06:19:58.521 3574-3574/? I/System.out:    id=1
    12-18 06:19:58.521 3574-3574/? I/System.out:    title=A Poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is a poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    subject=poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    years=2018
    12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
    12-18 06:19:58.521 3574-3574/? I/System.out: }
    12-18 06:19:58.521 3574-3574/? I/System.out: 1 {
    12-18 06:19:58.521 3574-3574/? I/System.out:    id=2
    12-18 06:19:58.521 3574-3574/? I/System.out:    title=Another Poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is another poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    subject=another poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    years=2017
    12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
    12-18 06:19:58.521 3574-3574/? I/System.out: }
    12-18 06:19:58.521 3574-3574/? I/System.out: 2 {
    12-18 06:19:58.521 3574-3574/? I/System.out:    id=3
    12-18 06:19:58.521 3574-3574/? I/System.out:    title=the Third Poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is the third poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    subject=third poem
    12-18 06:19:58.521 3574-3574/? I/System.out:    years=2018
    12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
    12-18 06:19:58.521 3574-3574/? I/System.out: }
    12-18 06:19:58.521 3574-3574/? I/System.out: <<<<<
    
    12-18 06:24:46.973 3689-3689/? D/DBVERSION: Database version = 2
    12-18 06:24:46.981 3689-3689/? I/SQLiteAssetHelper: successfully opened database brodsky.db
    12-18 06:24:46.981 3689-3689/? D/GETNEWPOEMS: Initiating getting new poems due to Database version increased.
    12-18 06:24:46.981 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 4
    12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 5
    12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 6
    12-18 06:24:46.993 3689-3689/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@53462060
    12-18 06:24:46.993 3689-3689/? I/System.out: 0 {
    12-18 06:24:46.993 3689-3689/? I/System.out:    id=1
    12-18 06:24:46.993 3689-3689/? I/System.out:    title=A Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is a poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    subject=poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    years=2018
    12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.993 3689-3689/? I/System.out: }
    12-18 06:24:46.993 3689-3689/? I/System.out: 1 {
    12-18 06:24:46.993 3689-3689/? I/System.out:    id=2
    12-18 06:24:46.993 3689-3689/? I/System.out:    title=Another Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is another poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    subject=another poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    years=2017
    12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.993 3689-3689/? I/System.out: }
    12-18 06:24:46.993 3689-3689/? I/System.out: 2 {
    12-18 06:24:46.993 3689-3689/? I/System.out:    id=3
    12-18 06:24:46.993 3689-3689/? I/System.out:    title=the Third Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is the third poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    subject=third poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    years=2018
    12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.993 3689-3689/? I/System.out: }
    12-18 06:24:46.993 3689-3689/? I/System.out: 3 {
    12-18 06:24:46.993 3689-3689/? I/System.out:    id=4
    12-18 06:24:46.993 3689-3689/? I/System.out:    title=The Update Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is a new poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    subject=4th Core Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    years=2019
    12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.993 3689-3689/? I/System.out: }
    12-18 06:24:46.993 3689-3689/? I/System.out: 4 {
    12-18 06:24:46.993 3689-3689/? I/System.out:    id=5
    12-18 06:24:46.993 3689-3689/? I/System.out:    title=Another Updated Poem
    12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is another updated poem
    12-18 06:24:46.997 3689-3689/? I/System.out:    subject=5th Core Poem
    12-18 06:24:46.997 3689-3689/? I/System.out:    years=2019
    12-18 06:24:46.997 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.997 3689-3689/? I/System.out: }
    12-18 06:24:46.997 3689-3689/? I/System.out: 5 {
    12-18 06:24:46.997 3689-3689/? I/System.out:    id=6
    12-18 06:24:46.997 3689-3689/? I/System.out:    title=The 3rd Updated Poem
    12-18 06:24:46.997 3689-3689/? I/System.out:    poem=This is the 3rd updated poem
    12-18 06:24:46.997 3689-3689/? I/System.out:    subject=6th Core Poem
    12-18 06:24:46.997 3689-3689/? I/System.out:    years=2019
    12-18 06:24:46.997 3689-3689/? I/System.out:    favorite=NO
    12-18 06:24:46.997 3689-3689/? I/System.out: }
    12-18 06:24:46.997 3689-3689/? I/System.out: <<<<<
    
    12-18 06:27:08.933 3789-3789/so53801149.so53801149poemupdatefromassets D/DBVERSION: Database version = 3
    12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets I/SQLiteAssetHelper: successfully opened database brodsky.db
    12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets D/GETNEWPOEMS: Initiating getting new poems due to Database version increased.
    12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
    12-18 06:27:08.949 3789-3789/so53801149.so53801149poemupdatefromassets I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@5347529c
    ..... results same as above (6 rows)