Android 是否通过内容提供程序或直接访问DBHelper创建表?其他的?
我正在构建一个Android应用程序,它使用一个DB助手类和内容提供者,仅用于访问DB。我注意到,当我的应用程序启动时,它从来没有碰到我的DBHelper类的onCreate(),该类包含表创建的所有DDL(如果它们不存在的话)Android 是否通过内容提供程序或直接访问DBHelper创建表?其他的?,android,sqlite,android-contentprovider,Android,Sqlite,Android Contentprovider,我正在构建一个Android应用程序,它使用一个DB助手类和内容提供者,仅用于访问DB。我注意到,当我的应用程序启动时,它从来没有碰到我的DBHelper类的onCreate(),该类包含表创建的所有DDL(如果它们不存在的话) 我已经手动创建了其中一个表,并且已经确认我可以通过我的提供商执行CRUD操作。我的目标是让内容提供者只访问DBhelper类,并让UI使用内容提供者进行CRUD操作 我觉得我缺少了这张椅子的一部分,需要一些帮助来理解这个过程应该如何工作,这样当我的应用程序启动时,系统将
我已经手动创建了其中一个表,并且已经确认我可以通过我的提供商执行CRUD操作。我的目标是让内容提供者只访问DBhelper类,并让UI使用内容提供者进行CRUD操作 我觉得我缺少了这张椅子的一部分,需要一些帮助来理解这个过程应该如何工作,这样当我的应用程序启动时,系统将检查表是否存在,并在不存在时创建 我已经将DBhelper类作为一个单例实现,对此似乎有很多争论 我明白,在创建操作继续之前,我确实需要获得一个可读或可写的db,至少我认为这是正确的。我遇到的问题是,如果我应该在应用程序启动时从我的MainActivity的onCreate中获取我的db类的实例,那么我无法将其拼凑起来?或者,如果我应该在我的内容提供商中做一些事情,在应用程序启动时处理这个问题?仅供参考-我确实在清单中注册了我的内容提供程序,如前所述,在我的MainActivity onCreate()中,我已成功地将我的内容提供程序用于手动生成的表上的CRUD操作 如果您有任何指示,我们将不胜感激 这是我的AppDB类
class AppDatabase extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "wgutrack.db";
public static final int DATABASE_VERSION = 1;
public static final String CTINE = "CREATE TABLE IF NOT EXISTS ";
public static final String PKA = " INTEGER PRIMARY KEY AUTOINCREMENT, ";
private static final String TEXT_TYPE = " TEXT";
public static final String INTEGER_TYPE = " INTEGER";
private static final String COMMA_SEP = ", ";
private static final String NN = " NOT NULL ";
// Implement AppDatabase as a singleton
private static AppDatabase instance = null;
private AppDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* Get an instance of the app's singleton db helper object
* @param context The content provider's context
* @return A SQLite DB helper object
*/
static AppDatabase getInstance(Context context) {
if (instance == null) {
instance = new AppDatabase(context);
}
return instance;
}
@Override
public void onCreate(SQLiteDatabase db) {
// Create script for Terms table
String sqlTerms;
sqlTerms = CTINE + TermsContract.TABLE_NAME + " ("
+ TermsContract.Columns._ID + PKA
+ TermsContract.Columns.COL_TITLE + TEXT_TYPE + NN + COMMA_SEP
+ TermsContract.Columns.COL_START + INTEGER_TYPE + NN + COMMA_SEP
+ TermsContract.Columns.COL_END + INTEGER_TYPE + NN + ")";
Log.d("SQLQRY", sqlTerms);
db.execSQL(sqlTerms);
// Create script for Courses table
String sqlCourses;
sqlCourses = CTINE + CoursesContract.TABLE_NAME + " ("
+ CoursesContract.Columns._ID + PKA
+ CoursesContract.Columns.COL_TITLE + TEXT_TYPE + NN + COMMA_SEP
+ CoursesContract.Columns.COL_STATUS + TEXT_TYPE + NN + COMMA_SEP
+ CoursesContract.Columns.COL_MENTOR_ID + INTEGER_TYPE + NN + COMMA_SEP
+ CoursesContract.Columns.COL_START + INTEGER_TYPE + COMMA_SEP
+ CoursesContract.Columns.COL_END + INTEGER_TYPE + COMMA_SEP
+ CoursesContract.Columns.COL_START_NOTIFY + INTEGER_TYPE + COMMA_SEP
+ CoursesContract.Columns.COL_END_NOTIFY + INTEGER_TYPE + ")";
Log.d("SQLQRY", sqlCourses);
db.execSQL(sqlCourses);
// Create script for term / course map table
String sqlMap;
sqlMap = CTINE + TermsCourseMapContract.TABLE_NAME + " ("
+ TermsCourseMapContract.Columns._ID + PKA
+ TermsCourseMapContract.Columns.COL_TERM_ID + INTEGER_TYPE + COMMA_SEP
+ TermsCourseMapContract.Columns.COL_COURSE_ID + INTEGER_TYPE + ")";
// Create script for Mentors table
String sqlMentors;
sqlMentors = CTINE + MentorsContract.TABLE_NAME + " ("
+ MentorsContract.Columns._ID + PKA
+ MentorsContract.Columns.COL_FIRST_NAME + TEXT_TYPE + NN + COMMA_SEP
+ MentorsContract.Columns.COL_LAST_NAME + TEXT_TYPE + NN + COMMA_SEP
+ MentorsContract.Columns.COL_PHONE + TEXT_TYPE + COMMA_SEP
+ MentorsContract.Columns.COL_EMAIL + TEXT_TYPE + ")";
Log.d("SQLQRY", sqlMentors);
db.execSQL(sqlMentors);
// Create script for Assessments table
String sqlAssessments;
sqlAssessments = CTINE + AssessmentsContract.TABLE_NAME + " ("
+ AssessmentsContract.Columns._ID + PKA
+ AssessmentsContract.Columns.COL_TITLE + TEXT_TYPE + NN + COMMA_SEP
+ AssessmentsContract.Columns.COL_DESC + TEXT_TYPE + COMMA_SEP
+ AssessmentsContract.Columns.COL_TYPE + TEXT_TYPE + COMMA_SEP
+ AssessmentsContract.Columns.COL_COURSE_ID + INTEGER_TYPE + NN + ")";
Log.d("SQLQRY", sqlAssessments);
db.execSQL(sqlAssessments);
// Create script for the Notes table
String sqlNotes;
sqlNotes = CTINE + NotesContract.TABLE_NAME + " ("
+ NotesContract.Columns._ID + PKA
+ NotesContract.Columns.COL_TITLE + TEXT_TYPE + NN + COMMA_SEP
+ NotesContract.Columns.COL_TEXT + TEXT_TYPE + NN + COMMA_SEP
+ NotesContract.Columns.COL_COURSE_ID + INTEGER_TYPE + NN + ")";
Log.d("SQLQRY", sqlNotes);
db.execSQL(sqlNotes);
// Create script for the Goals table
String sqlGoals;
sqlGoals = CTINE + GoalsContract.TABLE_NAME + " ("
+ GoalsContract.Columns._ID + PKA
+ GoalsContract.Columns.COL_TITLE + TEXT_TYPE + NN + COMMA_SEP
+ GoalsContract.Columns.COL_DESC + TEXT_TYPE + NN + COMMA_SEP
+ GoalsContract.Columns.COL_DUE_DATE + INTEGER_TYPE + NN + COMMA_SEP
+ GoalsContract.Columns.COL_ASS_ID + INTEGER_TYPE + NN + ")";
Log.d("SQLQRY", sqlGoals);
db.execSQL(sqlGoals);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
// upgrade from version 1
break;
default:
throw new IllegalStateException("onUpgrade() with unknown new version: " + newVersion);
}
}
}
我注意到,当我的应用程序启动时,它从来没有击中目标
DBHelper类的onCreate(),该类具有表的所有DDL
创造物,如果它们不存在的话
创建数据库时,SQLIteOpenHelper
类的onCreate
方法运行一次。它并不是每次实例化子类的实例时都运行
开发应用程序时,更改数据库结构的最简单方法是执行以下操作之一(假设数据可能丢失):-
- 从设备上的设置中删除/清除应用程序的数据,然后重新运行应用程序
- 卸载然后重新安装应用程序,然后重新运行应用程序
- 在删除表的
方法中使用合适的代码,然后调用已更改的onUpgrade
方法onCreate
onUpgrade
方法在的限制范围内更改表
您可以通过查询sqlite\u master表来检查表是否存在。这将返回一个包含5列的游标,即:-
- 类型
- 表格表格
- 名称实体的名称
- tbl_name实体相关的表的名称
- rootpage
- sql用于创建实体的sql
- (实体与类型相关,例如表、索引、视图、触发器)
SELECT tbl_name FROM sqlite_master WHERE tbl_name = 'tablex' AND type = 'table';
所以你可以有一个方法,大致如下:-
public boolean doesTableExist(String table_name) {
boolean rv = false;
String[] columns = new String[]{"sqlite_master"};
String whereclause = "tbl_name=? AND type=?";
String[] whereargs = new String[]{table_name,"table"};
Cursor csr = yoursqlitedatabase.query("sqlite_master",columns,whereclause,wwhereargs,null,null,null);
rv = csr.getCount() > 0;
csr.close();
return rv;
}
- 如果在DBhelper中包含上述内容,则
可以是Cursor csr=yoursqlitedatabase.query(“sqlite_master”,columns,whereclause,wwhereargs,null,null)
Cursor csr=this.getWritableDatabase().query(“sqlite\u master”,columns,where子句,wwhereargs,null,null)代码>
- 通常您会看到
,然后看到SQliteDatabase db=this.getWritabledatabase()
db.query……。
- 然后,您可以使用类似于
作为类变量,然后在要检查的类(活动)中AppDatabase myDBHlper
后跟myDBHelper=Appdatabase.getInstance(this)
if(myDBHelper.doestableExist(“您的表”){……}
- 通常您会看到
创建表(如果不存在)…
就足够了
您可以通过重写类的
onOpen
方法来实现检查等,该类是SQLiteOpenHelper(又称DBHelper)的子类,或者是onConfigure
方法。“我的目标是让内容提供者只访问DBHelper类,让UI使用内容提供者进行CRUD操作”——为什么?您是否计划使用其他应用程序通过您的提供商访问此内容?如果不是,那么为什么不放弃提供程序,直接使用SQLite(或者通过Room或ORM层)?纯粹出于内部目的使用ContentProvider
不是一种流行的方法。