下面是我最终实现的解决方案。这有点像是从公共软件书籍中获得的信息和一些我希望我在网络上做书签的东西混合而成的,因为我想给这些东西加上学分:
对于我需要从数据库中提取的每种类型的数据,我创建了一个“适配器”类(不从任何子类化)。这些适配器类包含访问该信息段的数据库所需的所有方法。例如,如果数据库中有三个表:
-
汽车
-
小船
-
摩托车
我将有三个类似于以下内容的适配器(我只将其中一个作为演示,但每个适配器的想法都是相同的):
public class CarsDBAdapter {
public static final String ROW_ID = "_id";
public static final String NAME = "name";
public static final String MODEL = "model";
public static final String YEAR = "year";
private static final String DATABASE_TABLE = "cars";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DBAdapter.DATABASE_NAME, null, DBAdapter.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
/**
* Constructor - takes the context to allow the database to be
* opened/created
*
* @param ctx
* the Context within which to work
*/
public CarsDBAdapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the cars database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException
* if the database could be neither opened or created
*/
public CarsDBAdapter 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();
}
/**
* Create a new car. If the car is successfully created return the new
* rowId for that car, otherwise return a -1 to indicate failure.
*
* @param name
* @param model
* @param year
* @return rowId or -1 if failed
*/
public long createCar(String name, String model, String year){
ContentValues initialValues = new ContentValues();
initialValues.put(NAME, name);
initialValues.put(MODEL, model);
initialValues.put(YEAR, year);
return this.mDb.insert(DATABASE_TABLE, null, initialValues);
}
/**
* Delete the car with the given rowId
*
* @param rowId
* @return true if deleted, false otherwise
*/
public boolean deleteCar(long rowId) {
return this.mDb.delete(DATABASE_TABLE, ROW_ID + "=" + rowId, null) > 0; //$NON-NLS-1$
}
/**
* Return a Cursor over the list of all cars in the database
*
* @return Cursor over all cars
*/
public Cursor getAllCars() {
return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
NAME, MODEL, YEAR }, null, null, null, null, null);
}
/**
* Return a Cursor positioned at the car that matches the given rowId
* @param rowId
* @return Cursor positioned to matching car, if found
* @throws SQLException if car could not be found/retrieved
*/
public Cursor getCar(long rowId) throws SQLException {
Cursor mCursor =
this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, NAME,
MODEL, YEAR}, ROW_ID + "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Update the car.
*
* @param rowId
* @param name
* @param model
* @param year
* @return true if the note was successfully updated, false otherwise
*/
public boolean updateCar(long rowId, String name, String model,
String year){
ContentValues args = new ContentValues();
args.put(NAME, name);
args.put(MODEL, model);
args.put(YEAR, year);
return this.mDb.update(DATABASE_TABLE, args, ROW_ID + "=" + rowId, null) >0;
}
}
所以,如果您想象我为每个表都有一个这样的类“适配器”。
当我的应用程序启动屏幕时,我会使用显示的技术
Android For Beginners: Creating multiple SQLite Tables for Android
因此,我的主数据库适配器(负责在单个数据库中创建所有表)如下所示:
public class DBAdapter {
public static final String DATABASE_NAME = "stuffIOwn"; //$NON-NLS-1$
public static final int DATABASE_VERSION = 1;
private static final String CREATE_TABLE_CARS =
"create table cars (_id integer primary key autoincrement, " //$NON-NLS-1$
+ CarsDBAdapter.NAME+ " TEXT," //$NON-NLS-1$
+ CarsDBAdapter.MODEL+ " TEXT," //$NON-NLS-1$
+ CarsDBAdapter.YEAR+ " TEXT" + ");"; //$NON-NLS-1$ //$NON-NLS-2$
private static final String CREATE_TABLE_BOATS = "create table boats (_id integer primary key autoincrement, " //$NON-NLS-1$
+BoatsDBAdapter.NAME+" TEXT," //$NON-NLS-1$
+BoatsDBAdapter.MODEL+" TEXT," //$NON-NLS-1$
+BoatsDBAdapter.YEAR+" TEXT"+ ");"; //$NON-NLS-1$ //$NON-NLS-2$
private static final String CREATE_TABLE_CYCLES = "create table cycles (_id integer primary key autoincrement, " //$NON-NLS-1$
+CyclesDBAdapter.NAME+" TEXT," //$NON-NLS-1$
+CyclesDBAdapter.MODEL+" TEXT," //$NON-NLS-1$
+CyclesDBAdapter.YEAR+" TEXT"+ ");"; //$NON-NLS-1$ //$NON-NLS-2$
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
/**
* Constructor
* @param ctx
*/
public DBAdapter(Context ctx)
{
this.context = ctx;
this.DBHelper = new DatabaseHelper(this.context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_CARS);
db.execSQL(CREATE_TABLE_BOATS);
db.execSQL(CREATE_TABLE_CYCLES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
// Adding any table mods to this guy here
}
}
/**
* open the db
* @return this
* @throws SQLException
* return type: DBAdapter
*/
public DBAdapter open() throws SQLException
{
this.db = this.DBHelper.getWritableDatabase();
return this;
}
/**
* close the db
* return type: void
*/
public void close()
{
this.DBHelper.close();
}
}
只有在应用程序首次启动时才会调用DBadapter类,它的唯一职责是创建/升级表。对数据的所有其他访问都是通过单独的“适配器”类完成的。我发现这非常有效,并且不会产生我前面提到的版本控制问题。
希望这有帮助。