我有一些 Android 项目,其中大多数与 SQLite数据库相关联。我感兴趣的是使用一些静态类如“ DatabaseHelper.class ”这是一个很好的编程实践(或者是一个糟糕的habbit),其中我将拥有与数据库操作相关的所有静态方法。例如
public static int getId(Context context, String name) {
dbInit(context);
Cursor result = db.rawQuery("SELECT some_id FROM table WHERE some_name = '" + name + "'", null);
result.moveToFirst();
int id = result.getInt(result.getColumnIndex("some_id"));
result.close();
return id;
}
其中 dbInit(context) (在我的所有静态方法中用于数据库操作)是
private static void dbInit(Context context) {
if (db == null) {
db = context.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null);
}
}
然后,当我需要某些东西时,我可以轻松地使用例如
来调用这些方法int id = DatabaseHelper.getId(this, "Abc");
编辑:我是否必须在每个连接上使用dbClose,或者按活动保持打开并关闭每个活动?那么我是否将上层代码改为这样的东西?
...
dbClose();
return id;
}
private static void dbClose() {
if (db != null) {
db.close();
}
}
答案 0 :(得分:6)
我建议你养成每次需要时都能获得数据库连接的习惯,并在完成后将其释放回来。这种设施的通常名称是“数据库连接池”。
这会将连接逻辑移出实际代码并进入池中,并允许您在以后需要时执行许多操作。一个简单的事情,可能是池记录了连接对象的使用时间,因此您可以获得有关数据库使用情况的信息。
如果您只需要一个连接,那么您的初始池可以非常简单。
答案 1 :(得分:5)
我肯定会将您的数据库相关代码放在一个单独的类中,但是建议不要使用静态类或Singleton。它起初可能看起来很好,因为它很方便,但不幸的是它紧密地结合了你的类,隐藏了它们的依赖性,并且还使单元测试变得更加困难。
维基百科中的drawbacks部分简要概述了您可能希望探索其他技术的原因。您还可以在over here或over there处提供使用数据库访问单例的类的具体示例,以及如何使用依赖注入来解决我提到的一些问题。
作为第一步,我建议使用在构造函数中实例化的普通类,例如:
public class MyActivity extends Activity {
private DBAccess dbAccess;
public MyActivity() {
dbAccess = new DBAccess(this);
}
}
作为第二步,您可能希望研究像RoboGuice这样的框架来打破硬依赖。您的代码看起来像:
public class MyActivity extends Activity {
@Inject private DBAccess dbAccess;
public MyActivity() {
}
}
如果您想了解更多详情,请告诉我们!
答案 2 :(得分:0)
如果您打算使用单件,最低要求是使其成为无状态/线程安全。如果您使用getId方法,因为并发调用可能会导致各种奇怪的错误......
dbInit(context);
可以调用线程A,然后在命中查询语句之前停止处理。随后,线程B执行getId并同时调用dbInit在不同的上下文中传递。然后,线程A将恢复并尝试在B的上下文中执行查询。
也许这不是您应用程序中的问题,但我建议在该getId方法上粘贴一个synchronized修饰符!