11

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

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 数据库的?我没有将任何数据库传递给该方法。我的 SQLiteDatabase db 变量如何从外部类设置为创建的数据库?有人能像白痴一样告诉我吗?

4

7 回答 7

8

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

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

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

于 2012-09-03T20:33:16.050 回答
4

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

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

他们还调用了更多的回调方法,例如onConfigure(db),onOpen(db)等。(阅读有关这些方法的更多信息。)如果有帮助,您可以自己阅读源代码以了解所有这些发生的方式和时间的结构。

于 2012-09-03T20:33:39.740 回答
1

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

这里 PeopleDB 扩展了 SQLiteOpenHelper。此代码来自不同的类,并且在 getWritableDatabase() 或 getReadableDatabase() 或任何此类调用时调用 onCreate

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

希望有帮助。

于 2012-09-03T20:40:08.170 回答
1

看到我们的数据库是在 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();
        }
于 2012-09-03T20:48:07.660 回答
0

可能,在他们第一次被召唤时getReadableDatabase()getWriteableDatabase()当他们第一次被召唤时


于 2012-09-03T20:33:35.247 回答
0

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

于 2013-05-02T19:40:43.687 回答
0

这门课SQLiteOpenHelper被称为“助手”是有充分理由的。它为我们的应用程序编写者节省了大量的精力。

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

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

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

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

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

于 2017-09-25T03:48:45.063 回答