Android 和 SQLite:"nested" getReadableDatabase
Android and SQLite: "nested" getReadableDatabase
在我的 Android 应用程序中,我使用以下代码访问数据库:
public class DbHelper extends SQLiteOpenHelper {
/* ... */
}
public class DbManager {
private DbHelper helper = null;
public DbManager(Context context) {
helper = new DbHelper(context);
}
public void method1(bool cond) {
SQLiteDatabase db = helper.getReadableDatabase();
/* operate on db... */
if (cond) method2();
/* operate on db... */
db.close();
}
public void method2() {
/* see below */
}
}
method1
和 method2
可以从 class 外部独立调用。另外还有method1
必须调用method2
.
的情况
在method2
中我需要一个数据库实例,所以我应该调用SQLiteDatabase db = helper.getReadableDatabase();
。
如果 method2
没有被 method1
调用,这是可以的。另一方面,如果我从 method1
调用它,我会创建一个数据库句柄两次。
这样可以吗?
我想我可以这样避免这种情况:
public void method2(SQLiteDatabase db) {
SQLiteDatabase locDb;
if (db == null) {
locDb = helper.getReadableDatabase();
} else {
locDb = db;
}
/* ... */
if (db == null) locDb.close();
}
然后在 method1
我将使用 method2(db);
而从外面我将使用 method2(null);
这一切都有意义吗?或者我应该简单地忽略我正在创建“嵌套”数据库实例这一事实?这对具有更高“嵌套”级别的性能有何影响?
最大的问题可能是关闭数据库,不必要地关闭和打开数据库是低效的。
您需要做的就是获取数据库(getReadableDatabase 或 getWritableDatabase (在大多数情况下,两者都是 return 可写数据库))。它将 returns 相同的对象,除非数据库已关闭,然后它会通过打开数据库的过程。
- 这将是同一个对象 return 由 getWritableDatabase() 编辑,除非某些问题(例如磁盘已满)需要打开数据库 read-only。在这种情况下,read-only 数据库对象将被 returned。 https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#getReadableDatabase().
不过,也许可以考虑:-
public class DbManager {
private DbHelper helper = null;
private SQLiteDatabase db = null; //<<<<< ADDED
public DbManager(Context context) {
helper = new DbHelper(context);
db = helper.getWritableDatabase(); //<<<<< ADDED
}
public void method1(boolean cond) {
/* operate on db... */
if (cond) method2();
/* operate on db... */
}
public void method2() {
/* operate on db... */
}
}
当然你也可以考虑对 DbHelper 使用单例方法,那么多个 DbManager 实例将只有一个 DbHelper 实例
例如你可以有类似的东西:-
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "whatever";
private static final int DATABASE_VERSION = 1;
/* ... */
/* don't allow construction of a DbHelper by making the constructor private */
private DbHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
volatile static private DbHelper instance = null;
public static DbHelper getInstance(Context context) {
if (instance == null) {
instance = new DbHelper(context);
}
return instance;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
}
}
以及
public class DbManager {
private DbHelper helper = null;
private SQLiteDatabase db = null;
public DbManager(Context context) {
helper = DbHelper.getInstance(context);
db = helper.getWritableDatabase();
}
public void method1(boolean cond) {
/* operate on db... */
if (cond) method2();
/* operate on db... */
}
public void method2() {
/* see below */
}
}
在我的 Android 应用程序中,我使用以下代码访问数据库:
public class DbHelper extends SQLiteOpenHelper {
/* ... */
}
public class DbManager {
private DbHelper helper = null;
public DbManager(Context context) {
helper = new DbHelper(context);
}
public void method1(bool cond) {
SQLiteDatabase db = helper.getReadableDatabase();
/* operate on db... */
if (cond) method2();
/* operate on db... */
db.close();
}
public void method2() {
/* see below */
}
}
method1
和 method2
可以从 class 外部独立调用。另外还有method1
必须调用method2
.
在method2
中我需要一个数据库实例,所以我应该调用SQLiteDatabase db = helper.getReadableDatabase();
。
如果 method2
没有被 method1
调用,这是可以的。另一方面,如果我从 method1
调用它,我会创建一个数据库句柄两次。
这样可以吗?
我想我可以这样避免这种情况:
public void method2(SQLiteDatabase db) {
SQLiteDatabase locDb;
if (db == null) {
locDb = helper.getReadableDatabase();
} else {
locDb = db;
}
/* ... */
if (db == null) locDb.close();
}
然后在 method1
我将使用 method2(db);
而从外面我将使用 method2(null);
这一切都有意义吗?或者我应该简单地忽略我正在创建“嵌套”数据库实例这一事实?这对具有更高“嵌套”级别的性能有何影响?
最大的问题可能是关闭数据库,不必要地关闭和打开数据库是低效的。
您需要做的就是获取数据库(getReadableDatabase 或 getWritableDatabase (在大多数情况下,两者都是 return 可写数据库))。它将 returns 相同的对象,除非数据库已关闭,然后它会通过打开数据库的过程。
- 这将是同一个对象 return 由 getWritableDatabase() 编辑,除非某些问题(例如磁盘已满)需要打开数据库 read-only。在这种情况下,read-only 数据库对象将被 returned。 https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#getReadableDatabase().
不过,也许可以考虑:-
public class DbManager {
private DbHelper helper = null;
private SQLiteDatabase db = null; //<<<<< ADDED
public DbManager(Context context) {
helper = new DbHelper(context);
db = helper.getWritableDatabase(); //<<<<< ADDED
}
public void method1(boolean cond) {
/* operate on db... */
if (cond) method2();
/* operate on db... */
}
public void method2() {
/* operate on db... */
}
}
当然你也可以考虑对 DbHelper 使用单例方法,那么多个 DbManager 实例将只有一个 DbHelper 实例
例如你可以有类似的东西:-
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "whatever";
private static final int DATABASE_VERSION = 1;
/* ... */
/* don't allow construction of a DbHelper by making the constructor private */
private DbHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
volatile static private DbHelper instance = null;
public static DbHelper getInstance(Context context) {
if (instance == null) {
instance = new DbHelper(context);
}
return instance;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
}
}
以及
public class DbManager {
private DbHelper helper = null;
private SQLiteDatabase db = null;
public DbManager(Context context) {
helper = DbHelper.getInstance(context);
db = helper.getWritableDatabase();
}
public void method1(boolean cond) {
/* operate on db... */
if (cond) method2();
/* operate on db... */
}
public void method2() {
/* see below */
}
}