我应该为我的数据库中的每个表创建一个继承SQLiteOpenHelper的类吗?

时间:2019-03-05 20:59:10

标签: android sqlite android-sqlite android-database

我需要创建一个Android应用程序数据库,但是我想知道是否应该为我数据库中存在的每个表创建一个继承SQLiteOpenHelper的类吗?还是我应该创建一个类:例如从SQLiteOpenHelper继承并在onCreate方法中创建所有表以及更新和删除函数的MyAppDatabase?

有没有建议?

1 个答案:

答案 0 :(得分:0)

对于数据库中的所有表,您只需要一个数据库助手,因此您可以使用一个 onCreate 方法来创建表。请注意,如果您有多个数据库助手,则只有打开数据库的第一个助手会调用一次 onCreate (和 onUpdate 方法),因此除了拥有多个帮助程序效率低下,拥有多个数据库帮助程序可能会更加复杂。

更具体地说,只有在数据库不存在时才自动调用 onCreate 。到 onCreate 调用时,数据库本身已经创建。

onUpdate 仅在打开数据库时被调用(通过超级调用)传递给调用的版本号大于存储在数据库文件中的版本号时被调用。然后,此时将更新文件中存储的版本号,以反映较新的版本。因此,随后的调用将不会再调用 onUpgrade 方法。

您是否可以选择是否拆分方法和标识符,例如各个表的列/表名称。有些人可能认为拆分很尴尬,其他人可能认为这更清楚。

示例

以下代码是3个排列(以及数据库)的示例,它们全部利用2个表,即 table001 (列 _id mydata >)和 table001 (列名 _id myotherdata )。

  1. 使用单个数据库助手(DBHelper001),并将所有内容嵌入在助手中。该数据库为 mydb001

  2. 使用单个databasehelper(DBHelper002)以及针对表的特定类(面向Table001的类和面向Table002的类)的特定于Table的方法和常量。

  3. 使用两个单独的数据库帮助器(DBHelperTable001和DBHelperTable002),为了简化代码,使用Table001和Table002类。

    • 请注意,要克服仅在 onOpen 方法一旦被调用时调用 onCreate 的情况,该方法还会尝试创建相应的表(CREATE TABLE IF NOT EXISTS ......在避免这种情况下很重要表确实存在时失败)。
    • 请注意,这仅仅是拥有多个助手的一种低效率。

首先是表特定的类(第一个排列未使用)

Table001.java

public class Table001 {

    public static final String TBL_TABLE001 = "table001";
    public static final String COL_TABLE001_ID = BaseColumns._ID;
    public static final String COL_TABLE001_MYDATA = "mydata";

    public static String getCrtSQL() {
        return "CREATE TABLE IF NOT EXISTS " + TBL_TABLE001 + "(" +
                COL_TABLE001_ID + " INTEGER PRIMARY KEY, " +
                COL_TABLE001_MYDATA + " TEXT" +
                ")";
    }

    public static long insert(SQLiteDatabase db, String mydata) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE001_MYDATA,mydata);
        return db.insert(TBL_TABLE001,null,cv);
    }

    public static Cursor getAll(SQLiteDatabase db) {
        return db.query(TBL_TABLE001,null,null,null,null,null,null);
    }
}

Table002.java

public class Table002 {

    public static final String TBL_TABLE002 = "table002";
    public static final String COL_TABLE002_ID = BaseColumns._ID;
    public static final String COL_TABLE002_MYOTHERDATA = "myotherdata";

    public static String getCrtSQL() {
        return "CREATE TABLE IF NOT EXISTS " + TBL_TABLE002 + "(" +
                COL_TABLE002_ID + " INTEGER PRIMARY KEY, " +
                COL_TABLE002_MYOTHERDATA + " TEXT" +
                ")";
    }

    public static long insert(SQLiteDatabase db, String mydata) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE002_MYOTHERDATA,mydata);
        return db.insert(TBL_TABLE002,null,cv);
    }

    public static Cursor getAll(SQLiteDatabase db) {
        return db.query(TBL_TABLE002,null,null,null,null,null,null);
    }
}

四个数据库帮助程序类

DBHelper001.java-(自包含)

public class DBHelper001 extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb001";
    public static final int DBVERSION = 1;

    public static final String TBL_TABLE001 = "table001";
    public static final String TBL_TABLE002 = "table002";
    public static final String COL_TABLE001_ID = BaseColumns._ID;
    public static final String COL_TABLE001_MYDATA = "mydata";
    public static final String COL_TABLE002_ID = BaseColumns._ID;
    public static final String COL_TABLE002_MYOTHERDATA = "myotherdata";

    public DBHelper001(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crt_table001_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE001 + "(" +
                COL_TABLE001_ID + " INTEGER PRIMARY KEY," +
                COL_TABLE001_MYDATA + " TEXT" +
                ")";
        String crt_table002_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TABLE002 + "(" +
                COL_TABLE002_ID + " INTEGER PRIMARY KEY," +
                COL_TABLE002_MYOTHERDATA + " TEXT" +
                ")";
        db.execSQL(crt_table001_sql);
        db.execSQL(crt_table002_sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insertIntoTable001(String mydata) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE001_MYDATA,mydata);
        return db.insert(TBL_TABLE001,null,cv);
    }

    public long insertIntoTable002(String myotherdata) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE002_MYOTHERDATA,myotherdata);
        return db.insert(TBL_TABLE002,null,cv);
    }

    public Cursor getAllFromTable001() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TBL_TABLE001,null,null,null,null,null,null);
    }

    public Cursor getAllFromTable002() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TBL_TABLE002,null,null,null,null,null,null);
    }
}

DBHelper002.java (其他地方的表特定代码)

public class DBHelper002 extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb002";
    public static final int DBVERSION = 1;

    public DBHelper002(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(Table001.getCrtSQL());
        db.execSQL(Table002.getCrtSQL());
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

DBHelperTable001.java(特定于table001的帮助器)

public class DBHelperTable001 extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb003";
    public static final int DBVERSION = 1;

    public DBHelperTable001(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(Table001.getCrtSQL());
        //NOTE Table002 won't get created as onCreate is only called once
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        db.execSQL(Table001.getCrtSQL());
    }
}
  • 注意 onOpen 方法用于规避onCreate,在数据库的整个生命周期中仅调用一次。
    • 调用execSQL是这种方法效率低下的一个例子。

DBHelperTable002.java(特定于table002的帮助器)

public class DBHelperTable002 extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb003";
    public static final int DBVERSION = 1;

    public DBHelperTable002(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(Table002.getCrtSQL());
        //NOTE Table001 won't get created as onCreate is only called once
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        db.execSQL(Table002.getCrtSQL());
    }
}

把他们都绑在一起

以下活动利用( MainActivity.java )利用所有3个排列。对于每个表,每行都添加一行,然后将每个表中的所有数据提取到游标中,然后将其转储(输出到日志)。

请注意,对于特定于表的助手,每个助手都用于提取行(显示冗余方面)。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    DBHelper001 mDBHlpr1;
    DBHelper002 mDBHlpr2;
    DBHelperTable001 mTblDBHlpr1;
    DBHelperTable002 mTblDBHlpr2;
    Cursor mCsr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDBHlpr1 = new DBHelper001(this);
        mDBHlpr1.insertIntoTable001("my data for table001 in mydb001");
        mDBHlpr1.insertIntoTable002("my other data for table002 in mydb001");
        mCsr = mDBHlpr1.getAllFromTable001();
        DatabaseUtils.dumpCursor(mCsr);
        mCsr = mDBHlpr1.getAllFromTable002();
        DatabaseUtils.dumpCursor(mCsr);


        mDBHlpr2 = new DBHelper002(this);
        Table001.insert(mDBHlpr2.getWritableDatabase(),"my data for table001 in mydb002");
        Table002.insert(mDBHlpr2.getWritableDatabase(),"my other data for table002 in mydb002");
        mCsr = Table001.getAll(mDBHlpr2.getWritableDatabase());
        DatabaseUtils.dumpCursor(mCsr);
        mCsr = Table002.getAll(mDBHlpr2.getWritableDatabase());
        DatabaseUtils.dumpCursor(mCsr);

        //Oooops???? wouldn't normally do this
        mCsr = Table001.getAll(mDBHlpr1.getWritableDatabase()); //?????????? from other database!!!
        DatabaseUtils.dumpCursor(mCsr);

        mTblDBHlpr1 = new DBHelperTable001(this);
        Table001.insert(mTblDBHlpr1.getWritableDatabase(),"my data for table001 in mydb003");
        mTblDBHlpr2 = new DBHelperTable002(this);
        Table002.insert(mTblDBHlpr2.getWritableDatabase(),"my data for table002 in mydb003");
        mCsr = Table001.getAll(mTblDBHlpr1.getWritableDatabase());
        DatabaseUtils.dumpCursor(mCsr);
        mCsr = Table002.getAll(mTblDBHlpr1.getWritableDatabase()); //???????????? but OK
        DatabaseUtils.dumpCursor(mCsr);
        mCsr = Table001.getAll(mTblDBHlpr2.getWritableDatabase());
        DatabaseUtils.dumpCursor(mCsr);
        mCsr = Table002.getAll(mTblDBHlpr2.getWritableDatabase()); //??????????? but OK
        DatabaseUtils.dumpCursor(mCsr);
    }
}

结果

以下是第一次运行的结果(请注意,多次运行而不卸载应用程序将导致添加2个新行):-

03-06 11:27:18.453 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@12c4306e
03-06 11:27:18.453 11093-11093/? I/System.out: 0 {
03-06 11:27:18.453 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.453 11093-11093/? I/System.out:    mydata=my data for table001 in mydb001
03-06 11:27:18.453 11093-11093/? I/System.out: }
03-06 11:27:18.453 11093-11093/? I/System.out: <<<<<
03-06 11:27:18.453 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@275e530f
03-06 11:27:18.453 11093-11093/? I/System.out: 0 {
03-06 11:27:18.453 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.453 11093-11093/? I/System.out:    myotherdata=my other data for table002 in mydb001
03-06 11:27:18.453 11093-11093/? I/System.out: }
03-06 11:27:18.453 11093-11093/? I/System.out: <<<<<


03-06 11:27:18.472 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@1006e57a
03-06 11:27:18.472 11093-11093/? I/System.out: 0 {
03-06 11:27:18.472 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.472 11093-11093/? I/System.out:    mydata=my data for table001 in mydb002
03-06 11:27:18.472 11093-11093/? I/System.out: }
03-06 11:27:18.472 11093-11093/? I/System.out: <<<<<
03-06 11:27:18.472 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@2337112b
03-06 11:27:18.473 11093-11093/? I/System.out: 0 {
03-06 11:27:18.473 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.473 11093-11093/? I/System.out:    myotherdata=my other data for table002 in mydb002
03-06 11:27:18.473 11093-11093/? I/System.out: }
03-06 11:27:18.473 11093-11093/? I/System.out: <<<<<


03-06 11:27:18.473 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@37ef9988
03-06 11:27:18.473 11093-11093/? I/System.out: 0 {
03-06 11:27:18.473 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.473 11093-11093/? I/System.out:    mydata=my data for table001 in mydb001
03-06 11:27:18.473 11093-11093/? I/System.out: }
03-06 11:27:18.473 11093-11093/? I/System.out: <<<<<


03-06 11:27:18.499 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@2b786c5d
03-06 11:27:18.500 11093-11093/? I/System.out: 0 {
03-06 11:27:18.500 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.500 11093-11093/? I/System.out:    mydata=my data for table001 in mydb003
03-06 11:27:18.500 11093-11093/? I/System.out: }
03-06 11:27:18.500 11093-11093/? I/System.out: <<<<<
03-06 11:27:18.500 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@2038a9d2
03-06 11:27:18.500 11093-11093/? I/System.out: 0 {
03-06 11:27:18.501 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.501 11093-11093/? I/System.out:    myotherdata=my data for table002 in mydb003
03-06 11:27:18.501 11093-11093/? I/System.out: }
03-06 11:27:18.501 11093-11093/? I/System.out: <<<<<
03-06 11:27:18.501 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@264a7aa3
03-06 11:27:18.501 11093-11093/? I/System.out: 0 {
03-06 11:27:18.501 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.501 11093-11093/? I/System.out:    mydata=my data for table001 in mydb003
03-06 11:27:18.501 11093-11093/? I/System.out: }
03-06 11:27:18.502 11093-11093/? I/System.out: <<<<<
03-06 11:27:18.502 11093-11093/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@3c2611a0
03-06 11:27:18.502 11093-11093/? I/System.out: 0 {
03-06 11:27:18.502 11093-11093/? I/System.out:    _id=1
03-06 11:27:18.502 11093-11093/? I/System.out:    myotherdata=my data for table002 in mydb003
03-06 11:27:18.503 11093-11093/? I/System.out: }
03-06 11:27:18.503 11093-11093/? I/System.out: <<<<<