【问题标题】:Handling a "complex" database in Android SQLite在 Android SQLite 中处理“复杂”数据库
【发布时间】:2013-03-12 08:53:41
【问题描述】:

1 - 多次扩展 SQLiteOpenHelper 是错误的并且无法正常工作。 2 - 拥有一个扩展 SQLiteOpenHelper 以处理 (CRUD) 7 个不同类的大类很奇怪。

有没有例子可以做到这一点?在没有大量依赖类的情况下将许多实体 CRUD 到我的数据库中?

我似乎在 Google 上找不到大于 2 或 3 个表的示例。 拥有一个非常大的 SQLiteOpenHelper 并为我的所有实体提供保存方法是可怕的。 此项目也不允许使用 ORM。

任何帮助/指导?

【问题讨论】:

  • 我有包含 20 多个实体的应用程序,它们运行良好。我为 db 支持的对象创建了一个基类,以及一个通用的 List 类,其中包含从这些对象下降的对象。后代类通常唯一需要实现的是loadFromCursor()getContentValues()
  • 好的...你能告诉我你是怎么做的吗?您有在线示例吗?
  • 抱歉,我现在没有时间清理代码。但是为了给你指明正确的方向,我的DBObject 有三个抽象方法:void loadFromCursor( Cursor c )ContentValues getContentValues()String getWhereClause()。我还有 boolean isEqual( DBObject obj )void clone( DBObject obj ) 的空实现用于变更管理。基于以上,我可以轻松实现 CRUD(我称之为store()load()delete())。只有后代对象知道它们的列名,所以我不会用契约类之类的东西弄乱我的代码。
  • 我很想看到这个“净化代码”。我真的无法在互联网上找到很好的答案。当你找到时间,建立一个主题并在 StackOverflow 中提出它,我很确定它会对社区有很大帮助。谢谢。
  • 我正在进行重构,考虑使用注释和注入...一旦完成,这可能会公开。我以与您相同的方式接近它......广告模式适用于一两张桌子,但除此之外的任何东西都变得非常笨拙。我也不想为每个项目从头开始创建一些东西,所以我的解决方案就是这样产生的。

标签: java android sqlite


【解决方案1】:

拥有一个非常大的 SQLiteOpenHelper,并为我所有的人提供保存方法 实体太可怕了。

你认为好的指定应用程序只有几行代码吗?

在Android 中,从SQLiteOpenHelper 扩展是最好的选择。它包含了所有必需的逻辑,并且在我看来使用它非常舒服。但一切都需要正确实施。

多次扩展 SQLiteOpenHelper 是错误的,无法正常工作

SQLiteOpenHleper 很可能没有问题,但我认为错误的实现和使用。

你的意思是,ORM 框架,例如 ORMLite 是不允许的,所以我的建议是使用 SQLiteOpenHelper 并进行正确和干净的实现。

更新:

7 种保存方法。 7种更新方法。 7 删除方法。 7 选择方法。 从数据库中获取其他数据的许多其他方法。是不是最好的 选择?

我在 cmets 中的意思是,这是实施问题。您真的不需要 7 个表以上的 7 个保存方法。这是我的第一个想法。如何创建一种通用方法?

public class DataSourceTools {

   private SQLiteOpenHelper handler;
   private SQLiteDatabase db;

   public DataSourceTools(SQLiteOpenHelper handler) {
      this.handler = handler;
   }

   public void saveObject(String table, ContentValues data) {
      try {
         db = openWrite(this.handler);
         if (db != null) {
            db.insert(table, nullColumnHackName, data);
         }
      }
      finally {
         close(db);
      }
   }

   public void updateObject(String table, ContentValues dataToUpdate) {
      try {
         db = openWrite(this.handler);
         if (db != null) {
            String whereClause = "...";
            String[] whereArgs = {...};
            db.update(table, dataToUpdate, whereClause, whereArgs);
         }
      }
      finally {
         close(db);
      }
   }

   public void deleteObject(String table, ContentValues data) {
      try {
         db = openWrite(this.handler);
         if (db != null) {
            String whereClause = "...";
            String[] whereArgs = {...};
            db.delete(table, whereClause, whereArgs);
         }
      }
      finally {
         close(db);
      }
   }

   public Object findObject(String table, ContentValues data) {
      Object myObject = null; 
      Cursor c = null;
      try {
         String[] columns = {"id", "name", "lastname", ...};
         String selection = "id = ?";
         String[] selectionArgs = {data.getAsString("key_id")};
         c = db.query(table, columns, selection, selectionArgs, null, null, null);
         if (c.moveToFirst()) {
            myObject = new Object();
            myObject.setId(c.getInt(c.getColumnIndex("id")));
            myObject.setName(c.getString(c.getColumnIndex("name")));
            myObject.setLastName(c.getString(c.getColumnIndex("lastname")));
         }
         return myObject;
      }
      finally {
         if (c != null) {
            c.close()
         }
         close(db);
      }
   }

   public List<Object> findAll(String table) {
      List<Object> objects = new ArrayList<Object>(); 
      Object myObject = null; 
      Cursor c = null;
      try {
         String[] columns = {"id", "name", "lastname", ...};
         c = db.query(table, columns, null, null, null, null, null);
         if (c.moveToFirst()) {
            myObject = new Object();
            myObject.setId(c.getInt(c.getColumnIndex("id")));
            myObject.setName(c.getString(c.getColumnIndex("name")));
            myObject.setLastName(c.getString(c.getColumnIndex("lastname")));
            objects.add(myObject);
         }
         return objects;
      }
      finally {
         if (c != null) {
            c.close()
         }
         close(db);
      }
   }

   private final synchronized SQLiteDatabase openWrite(SQLiteOpenHelper handler) {
      if (handler != null) {
         return handler.getWritableDatabase();
      }
      return null;
   }

   private final synchronized SQLiteDatabase openRead(SQLiteOpenHelper handler) {
      if (handler != null) {
         return handler.getReadableDatabase();
      }
      return null;
   }

   private final synchronized void close(SQLiteDatabase db) {
      if (db != null && db.isOpen()) {
         db.close();
      }
   }
}

注意:这是第一个概念,刚刚专门为您编写,因此需要更新:考虑方法的参数 --> 如何做出更好的选择,事务的使用,作为单例的数据源,对插入、更新进行一些性能测试。一切都取决于应用程序的特性。

【讨论】:

  • 7 种保存方法。 7种更新方法。 7 删除方法。 7 选择方法。从数据库中获取其他数据的许多其他方法。是不是最好的选择?
  • 现在你在谈论实现,所以一个类中有 28 个方法不好,但这是实现未使用技术的问题:-
  • 我将此 aswer 设置为正确的...是一个很好的方法,但在许多方面却相当不灵活。但是谢谢你写它。
  • @MBarni - 告诉我这些方法,我会更新吗?这只是概念,需要根据应用程序要求进行更新。
  • “存储”预制查询以检索/更改数据库数据。
【解决方案2】:

使用参数化方法优于对每个表的每个操作使用一种方法。 MBarni,您能否举例说明为什么这对您的需求不够灵活?

【讨论】:

  • @sajmon_d 已经提供了非常灵活的代码设计,我根据自己的需要进行了调整...
猜你喜欢
  • 1970-01-01
  • 2021-10-20
  • 2016-11-10
  • 1970-01-01
  • 2015-06-02
  • 2012-12-04
  • 1970-01-01
  • 2020-05-31
  • 2015-04-29
相关资源
最近更新 更多