当前位置: 首页 > 面试题库 >

onUpgrade数据库-oldVersion-newVersion

幸乐湛
2023-03-14
问题内容

我正在使用此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()例程中修改版本号。仅在版本不匹配时才调用此方法,并且您在这里要做的就是进行任何必要的更改以使数据库保持最新。升级完成后,帮助程序将管理新版本号的存储。



 类似资料:
  • 附注。我对Sqlite没有太多的经验

  • 6.9.3 Database ItemWriters 虽然文本文件和XML都有自己特定的 ItemWriter, 但数据库和他们并不一样。这是因为事务提供了所需的全部功能。 对于文件来说 ItemWriters 是必要的, 因为如果需要事务特性,他们必须充当这种角色, 跟踪输出的 item,并在适当的时间 flushing/clearing。使用数据库时不需要这个功能,因为写已经包含在事务之中。

  • 表元数据 下面这些方法用于获取表信息: 列出数据库的所有表 $this->db->list_tables(); 该方法返回一个包含你当前连接的数据库的所有表名称的数组。例如: $tables = $this->db->list_tables(); foreach ($tables as $table) { echo $table; } 检测表是否存在 $this->db->table_

  • CodeIgniter 内置了速度快、功能强大的数据库类作为数据库的中间抽象层。数据库类支持传统架构以及 Active Record 架构。类中的数据库函数使用简单明了的语法。 数据库配置 入门:用法举例 连接数据库 查询 生成查询结果 查询辅助函数 Active Record 类 事务 表格元数据 字段元数据 自定义函数调用 查询缓存 数据库维护类 数据库工具类

  • 本节部分知识点来自《数据库系统概论(第 5 版)》 基本概念 数据(data):描述事物的符号记录称为数据。 数据库(DataBase,DB):是长期存储在计算机内、有组织的、可共享的大量数据的集合,具有永久存储、有组织、可共享三个基本特点。 数据库管理系统(DataBase Management System,DBMS):是位于用户与操作系统之间的一层数据管理软件。 数据库系统(DataBase

  • DB-API Python 数据库 API 为 Python 的数据库访问模块定义了一套标准化的接口。该接口被记录在 PEP 249 中。几乎所有的 Python 数据库模块,诸如 sqlite3 , psycopg 和 mysql-python 都遵循该接口。 这里 和 这里 的教程讲解了如何使用遵循 DB-API 接口的模块。 SQLAlchemy SQLAlchemy 是一套常用的数据库工具