问题 SQLiteOpenHelper - 数据库是如何创建的?


我正在制作一个数据库应用程序,我的程序正常工作,我已经理解了我一直关注的大部分教程。但是,有一方面我不清楚。

有一个内部类的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变量是如何从  class设置为创建的数据库?有人能像白痴一样跟我说话吗?


12458
2017-09-03 20:23


起源



答案:


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

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

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


8
2017-09-03 20:33





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

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

他们还调用了一些更多的回调方法 onConfigure(db)onOpen(db)等(阅读更多 关于这些方法。)如果它会有所帮助,你可以通读 源代码 你要了解所有这些发生的方式和时间的结构。


3
2017-09-03 20:33





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

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

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

希望有所帮助。


1
2017-09-03 20:40





请参阅我们的数据库是在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();
        }

1
2017-09-03 20:48





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



0
2017-09-03 20:33





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


0
2018-05-02 19:40





班上 SQLiteOpenHelper 有充分理由被称为“助手”。它为我们的app作者节省了相当大的努力。

第一次 你打电话 getWritableDatabase (要么 getReadableDatabase)为您的实施 SQLiteOpenHelper, 你的 super 构造函数中的语句传递当前 Context 和数据库 NAME 您更喜欢超类构造函数 SQLiteOpenHelper

然后,超类构造函数为您的设置初始空间 SQLiteDatabase 并为其指定您通过的名称 super

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

后续执行 getReadableDatabase (要么 getWritableDatabase)只是为你打开数据库,再也不打电话 onCreate。 (当超类构造函数注意到这一点时 super 发送了不同的版本号, onUpgrade 是calle。)

了解方式 SQLiteOpenHelper 创建一个没有明显代码的数据库以及如何实现 onCreate 得到一个“突然出现”的论点对我来说是一件真正的苦差事。现在我无法相信它可能会变得艰难。


0
2017-09-25 03:48