我正在阅读Android SQLite记事本教程,其中提到创建一个DB适配器类来创建和访问一个DB表。当处理一个多表SQLite数据库时,最佳实践是为每个表创建一个不同的适配器类,还是为整个Android应用程序创建一个DB适配器类?
我的应用程序使用多个表,我希望不必有一个单一的大规模适配器类。然而,问题是,我有一个嵌套的SQLiteOpenHelper子类每个记事本的例子在每个适配器。当第一个表被访问,一切正常。当我试图访问第二个tble(从不同的活动)我的应用程序崩溃。
起初,我以为崩溃是由版本控制问题引起的,但现在两个适配器都有相同的数据库版本,它仍然崩溃。
下面是表的一个DB适配器的示例,其他适配器都遵循相同的格式,但实现不同。
public class InfoDBAdapter {
public static final String ROW_ID = "_id";
public static final String NAME = "name";
private static final String TAG = "InfoDbAdapter";
private static final String DATABASE_NAME = "myappdb";
private static final String DATABASE_TABLE = "usersinfo";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = "create table usersinfo (_id integer primary key autoincrement, "
+ NAME
+ " TEXT," + ");";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " //$NON-NLS-1$//$NON-NLS-2$
+ newVersion + ", which will destroy all old data"); //$NON-NLS-1$
//db.execSQL("DROP TABLE IF EXISTS usersinfo"); //$NON-NLS-1$
onCreate(db);
}
}
public InfoDBAdapter(Context ctx) {
this.mCtx = ctx;
}
public InfoDBAdapter open() throws SQLException {
this.mDbHelper = new DatabaseHelper(this.mCtx);
this.mDb = this.mDbHelper.getWritableDatabase();
return this;
}
/**
* close return type: void
*/
public void close() {
this.mDbHelper.close();
}
public long createUser(String name) {
ContentValues initialValues = new ContentValues();
initialValues.put(NAME, name);
return this.mDb.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteUser(long rowId) {
return this.mDb.delete(DATABASE_TABLE, ROW_ID + "=" + rowId, null) > 0; //$NON-NLS-1$
}
public Cursor fetchAllUsers() {
return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
NAME}, null, null, null, null, null);
}
public Cursor fetchUser(long rowId) throws SQLException {
Cursor mCursor =
this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, NAME}, ROW_ID + "=" + rowId, null, //$NON-NLS-1$
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateUser(long rowId, String name) {
ContentValues args = new ContentValues();
args.put(NAME, name);
return this.mDb
.update(DATABASE_TABLE, args, ROW_ID + "=" + rowId, null) > 0; //$NON-NLS-1$
}
}
当访问第一个适配器(在本例中为usersinfo)时,一切都按预期工作。假设我有另一个用于朋友信息的适配器,它遵循与上面相同的结构,当它被不同的Activity访问时,在我看来,SQLiteOpenHelper的嵌套子类会尝试再次创建数据库。显然,在这种情况下,我的应用崩溃了,所以一定出了什么问题。
那么,Android中的标准做法是创建单个猛犸数据库适配器,而不是为每个表创建单独的适配器吗?
2条答案
按热度按时间qoefvg9y1#
以下是我最终实现的解决方案。它是从Commonsware书籍中获得的信息和网络上的一些东西的混搭,我希望我能把这些东西标记为书签,因为我想给予信任:
对于我需要从数据库中提取的每种类型的数据,我创建了一个“适配器”类(不从任何东西派生子类)。这些适配器类包含了访问数据库以获取该信息所需的所有方法。例如,如果我的数据库中有三个表:
1.汽车
1.船只
1.摩托车
我会有三个适配器,看起来类似于下面的(我只放一个作为演示,但每个想法是相同的):
因此,如果您想象我为每个表使用一个这样的类“适配器”。
当我的应用程序启动时,我使用Android For Beginners: Creating multiple SQLite Tables for Android提供的技术
因此,我的主DBAdapter(负责在单个数据库中创建所有表)如下所示:
DBAdapter类只在应用程序第一次启动时被调用,它的唯一职责是创建/升级表。所有其他对数据的访问都是通过单独的“adapter”类完成的。我发现这样做效果很好,不会产生我前面提到的版本控制问题。
n7taea2i2#
遇到了同样的问题,尝试了很多解决方法,最后提出了一个抽象的方法,构造了数据库结构,并为表类扩展了类。
这是我的数据库构造函数类,是抽象的:
这是我的一个表类,其余的类都是一样实现的,只要你喜欢加多少就加多少:
希望我帮上忙了。