【问题标题】:SQLiteOpenHelper - how is the database created?SQLiteOpenHelper - 数据库是如何创建的?
【发布时间】:2012-08-28 12:45:51
【问题描述】:

我正在制作一个数据库应用程序,我的程序可以运行,并且我已经理解了我一直在学习的大部分教程。但是,我还不清楚一个方面。

MyDBHelper 有一个内部类扩展 SQLiteOpenHelper。 外部 变量包括名为 d 的 SQLiteDatabase。 MyDBHelper 的代码是:

private static class MyDBHelper extends SQLiteOpenHelper {
        MyDBHelper(Context c) {
            super(c, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            try {
                db.execSQL(DATABASE_CREATE);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVers, int newVers) {
            Log.w(TAG, "Upgrading database from version " + oldVers + " to " + newVers + ", which will destroy all old data.");
            db.execSQL("DROP TABLE IF EXISTS GM");
            onCreate(db);
        }
    }

我的问题是这实际上是如何创建初始数据库的。它发生在 onCreate() 方法中,但据我所知,这是 从不 调用的。我知道第一次创建数据库时会调用它,但是在哪里呢?此外,它是如何传递一个 SQLiteDatabase 数据库的?我没有将任何数据库传递给该方法。 outer 类中的 SQLiteDatabase db 变量如何设置为创建的数据库?有人能像白痴一样告诉我吗?

【问题讨论】:

    标签: java android database sqlite sqliteopenhelper


    【解决方案1】:

    onCreate()onUpgrade() 方法在创建 Db 时真正被调用。 事实上,它是在SQLiteOpenHelpergetReadableDatabase() or getWritebleDatabase() 方法中签入的。它将检查数据库是否已经存在于数据目录中以及它的版本是什么。据此,它将调用onCreate(), or onUpgrade()。或者什么都没有,如果 db 文件存在并且版本正确。

    您可以搜索您的代码以执行myDBHelper.getReadable(Writable)Database()。这就是执行此检查的时间。

    如果需要更多详细信息,请告诉我。祝你好运

    【讨论】:

      【解决方案2】:

      请记住,您正在扩展 SQLiteOpenHelper,所有的魔法都发生在这个超类中,特别是当您调用 getReadableDatabase()getWritableDatabase() 时,最初创建(或只是重新打开)数据库。这两种方法:

      • 定义SQLiteDatabase db 变量(并控制将db 传递给您的回调方法)
      • 通过调用onCreate(db) 方法或打开现有数据库来初始化db
      • 检查版本号,如有必要,请致电您的onUpgrade(db)onDowngrade(db)

      他们还调用了更多的回调方法,如onConfigure(db)onOpen(db) 等。(Read more 关于这些方法。)如果有帮助,您可以自己阅读the source code 以了解其结构当这一切发生时。

      【讨论】:

        【解决方案3】:

        onCreate() 方法不是此类的构造函数。创建数据库时调用 onCreate。

        这里 PeopleDB 扩展了 SQLiteOpenHelper。这段代码来自不同的类,当 getWritableDatabase() 或 getReadableDatabase() 或任何类似的东西被调用时,onCreate 被调用

          PeopleDB db = null; //onCreate NOT called here
          db=new PeopleDB(getContext());
          db.getWritableDatabase();  //onCreate is called here!
        

        希望对您有所帮助。

        【讨论】:

          【解决方案4】:

          看到我们的数据库是在 openhelper 的构造函数本身中创建的,而不是在覆盖的 onCreate 方法中。在 onCreate 方法中,我们正在触发一个查询以在数据库中创建一个表,该表是在 open helper 的构造函数中创建的,用于插入数据而不是创建数据库。

          还有一件事是 SQLiteDatabase 对象没有在 SQLiteOpenHelper 类中实例化。它在您要使用数据库执行数据库操作的类中实例化,您需要编写这样的函数来初始化或打开数据库以准备插入。

          SQLiteDatabase database;
          
          YourOpenHelper yourOpenHelper=new YourOpenHelper(); //to creating database using openhelper and automatically call onCreate to make a table in that
          
              public void open() throws SQLException {
                      database = profiloHelper.getWritableDatabase();
                  }
          

          这是您必须为数据库中的任何操作(如插入删除)编写的代码,您只需更改 QUERY

          SQLiteStatement insert_stmt = null;
          
                  try {
                      insert_stmt = database.compileStatement(YOUR_QUERY);
          
                      insert_stmt.bindString(1,   field1);
                      insert_stmt.bindString(2,   field2);
                      insert_stmt.executeInsert();
                  }
                  finally {
                      if (insert_stmt != null) insert_stmt.close();
                  }
          

          【讨论】:

            【解决方案5】:

            可能在getReadableDatabase()getWriteableDatabase() 第一次被调用时


            【讨论】:

              【解决方案6】:

              您创建一个实现 onCreate(SQLiteDatabase)、onUpgrade(SQLiteDatabase, int, int) 和可选的 onOpen(SQLiteDatabase) 的子类,该类负责打开数据库(如果存在),如果不存在则创建它并升级它是必要的。 (Android 开发者网站)

              【讨论】:

                【解决方案7】:

                SQLiteOpenHelper 被称为“Helper”是有充分理由的。它为我们的应用编写者节省了大量的精力。

                第一次调用getWritableDatabase(或getReadableDatabase)以实现SQLiteOpenHelper,构造函数中的super 语句传递当前Context 和数据库NAME,您更喜欢 SQLiteOpenHelper 的超类构造函数。

                然后超类构造函数为您的SQLiteDatabase 设置初始空间,并为其分配您通过super 传递的名称。

                完成后,超类构造函数调用onCreate 并通过onCreate 的唯一参数传递它创建的命名SQLiteDatabase。因为onCreate 只被调用一次,所以调用execSQL 来定义数据库的结构是一个非常好的地方。

                getReadableDatabase(或getWritableDatabase)的后续执行只会为您打开数据库,而不再调用onCreate。 (当超类构造函数注意到super 发送了不同的版本号时,onUpgrade 被调用。)

                了解SQLiteOpenHelper 创建一个没有明显代码的数据库的方式以及onCreate 如何“出乎意料”地传递一个参数对我来说是一件真正的苦差事。现在我不敢相信这会很难。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-07-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-09
                  相关资源
                  最近更新 更多