在Android中使用多个表的SQLite数据库适配器?
在Android中使用多个表的SQLite数据库适配器?
在阅读Android SQLite NotePad教程时,它提到创建一个DB Adapter类来创建和访问DB表。在处理多表SQLite数据库时,是创建一个适配器类来代表整个Android应用程序,还是为每个表创建一个不同的适配器类,这是最佳实践?
我的应用程序使用多个表,希望不必创建一个庞大的适配器类。然而,问题是每个适配器中都有一个SQLiteOpenHelper的嵌套子类,这是NotePad示例中的要求。当访问第一个表时,一切正常。但是当我尝试从不同的活动访问第二个表时,我的应用程序崩溃了。
起初,我以为崩溃是由版本问题引起的,但现在两个适配器都具有相同的数据库版本,但仍然崩溃。
这是一个表的DB适配器的示例。其他适配器都按照相同的格式进行,只是实现有所不同。
当访问第一个适配器(在这个例子中是usersinfo)时,一切都按预期工作。假设我有一个用于朋友信息的另一个适配器,它遵循上述相同的结构,当它被不同的活动访问时,我认为SQLiteOpenHelper的嵌套子类会尝试重新创建数据库。显然有些问题,因为在这种情况下,我的应用程序会崩溃。
那么,在Android中标准做法是创建一个单独的庞大的数据库适配器,而不是每个表都有一个适配器吗?
在Android中使用多个表的SQLite DB Adapter的原因是为了更好地组织和管理数据库操作。每个表都有一个对应的adapter类,该类包含了访问该表的所有方法。这样可以将数据库操作分散到各个adapter类中,使代码结构更清晰,易于维护。
解决方法是创建一个主DBAdapter类,负责创建和升级所有表,并在每个表的adapter类中扩展这个主类。这样,当打开任何一个表的adapter时,数据库会检查是否需要升级。这种方法还可以避免在应用程序启动时实例化DBAdapter。
下面是一个示例的DBAdapter类,用于创建和升级数据库和表:
public class DBAdapter { public static final String DATABASE_NAME = "stuffIOwn"; public static final int DATABASE_VERSION = 1; // 定义创建表的SQL语句 private static final String CREATE_TABLE_CARS = "create table cars (_id integer primary key autoincrement, " + CarsDBAdapter.NAME+ " TEXT," + CarsDBAdapter.MODEL+ " TEXT," + CarsDBAdapter.YEAR+ " TEXT" + ");"; private static final String CREATE_TABLE_BOATS = "create table boats (_id integer primary key autoincrement, " + BoatsDBAdapter.NAME+" TEXT," + BoatsDBAdapter.MODEL+" TEXT," + BoatsDBAdapter.YEAR+" TEXT"+ ");"; private static final String CREATE_TABLE_CYCLES = "create table cycles (_id integer primary key autoincrement, " + CyclesDBAdapter.NAME+" TEXT," + CyclesDBAdapter.MODEL+" TEXT," + CyclesDBAdapter.YEAR+" TEXT"+ ");"; private final Context context; private DatabaseHelper DBHelper; private SQLiteDatabase db; /** * Constructor * @param ctx the Context */ public DBAdapter(Context ctx) { this.context = ctx; this.DBHelper = new DatabaseHelper(this.context); } // 省略其他方法 /** * 内部类DatabaseHelper,用于创建和升级数据库和表 */ private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE_CARS); db.execSQL(CREATE_TABLE_BOATS); db.execSQL(CREATE_TABLE_CYCLES); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 升级数据库 } } }
每个表对应的adapter类可以类似地实现,例如CarsDBAdapter类:
public class CarsDBAdapter extends DBAdapter { // 定义表名和列名 public CarsDBAdapter(Context ctx) { super(ctx); } // 实现具体的数据库操作方法 }
通过这种方式,可以实现多个表的SQLite DB Adapter,并且可以轻松地进行表之间的联接操作。
在Android中,有时候需要在应用程序中使用多个表格的SQLite数据库适配器。下面的代码展示了一个抽象的数据库适配器和一个表格类的实现。这段代码中有一些问题需要解决。
问题1:为什么在构造函数中传递Activity实例而不是Context实例?
问题2:如果ourConstructorBool没有声明为静态的,那么它如何能被设置为true?
解决方法:
1. 将构造函数中的Activity实例更改为Context实例,因为Context是Activity的父类,更通用。
2. 将ourConstructorBool声明为静态的,这样它才能在构造函数中被设置为true。
下面是修改后的代码:
public abstract class dbAdapter { //... public dbAdapter(Context context){ if(!ourConstructorBool){ ourContext = context; DATABASE_NAME = context.getString(Asaf.com.contactsEX.R.string.DB_NAME); ourConstructorBool = true; } } //... static boolean ourConstructorBool = false; //... } public class PhoneNumberAdapter extends dbAdapter{ //... public PhoneNumberAdapter(Context context){ super(context); } //... }
希望对你有所帮助。