在Android中使用多个表的SQLite数据库适配器?

8 浏览
0 Comments

在Android中使用多个表的SQLite数据库适配器?

在阅读Android SQLite NotePad教程时,它提到创建一个DB Adapter类来创建和访问DB表。在处理多表SQLite数据库时,是创建一个适配器类来代表整个Android应用程序,还是为每个表创建一个不同的适配器类,这是最佳实践?

我的应用程序使用多个表,希望不必创建一个庞大的适配器类。然而,问题是每个适配器中都有一个SQLiteOpenHelper的嵌套子类,这是NotePad示例中的要求。当访问第一个表时,一切正常。但是当我尝试从不同的活动访问第二个表时,我的应用程序崩溃了。

起初,我以为崩溃是由版本问题引起的,但现在两个适配器都具有相同的数据库版本,但仍然崩溃。

这是一个表的DB适配器的示例。其他适配器都按照相同的格式进行,只是实现有所不同。

当访问第一个适配器(在这个例子中是usersinfo)时,一切都按预期工作。假设我有一个用于朋友信息的另一个适配器,它遵循上述相同的结构,当它被不同的活动访问时,我认为SQLiteOpenHelper的嵌套子类会尝试重新创建数据库。显然有些问题,因为在这种情况下,我的应用程序会崩溃。

那么,在Android中标准做法是创建一个单独的庞大的数据库适配器,而不是每个表都有一个适配器吗?

0
0 Comments

在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,并且可以轻松地进行表之间的联接操作。

0
0 Comments

在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);
    }
    //...
}

希望对你有所帮助。

0