POJO与Android中的游标

时间:2010-03-30 12:34:50

标签: android cursor pojo

我通常倾向于使用POJO来定义我的应用的模型层,例如文章,评论等。

我准备在我的一个ListViews的适配器中实现AlphabetIndexer。现在这个适配器接受一个文章集合,我通常从我的包装器中获取SQLiteDatabase。

AlphabetIndexer构造函数的签名如下:

public AlphabetIndexer (Cursor cursor, int sortedColumnIndex, CharSequence alphabet)

由于这不接受Collection或类似的东西,只是一个Cursor,它让我想知道:也许我不应该为我的模型创建对象,只使用从数据库返回的Cursors?

所以问题是,我猜:我应该怎么做,用POJO的集合表示数据,或者只是在我的应用程序中使用游标?

任何输入?

4 个答案:

答案 0 :(得分:13)

我遇到过类似的问题。现在,我正在逐渐远离POJO。但请注意,如果您愿意,可以为POJO集合创建自己的Cursor界面。

答案 1 :(得分:12)

我喜欢创建支持Cursor的POJO类。支持Cursor的POJO类有一个构造函数,它接受一个Cursor并提供以下好处:

  • 易于使用的getter返回适当的内容类型,更好 而不是获取索引和必须记住的数据类型 数据库
  • 从其他getter计算结果的getter方法,就像OO编程应该是
  • 一样
  • Getter返回值可以是枚举!

这些好处非常值得一些样板代码,由于用户工程师本身并不访问光标列,因此避免了许多错误。我们仍然使用CursorAdapter类,但bindView方法的第一行是从Cursor创建Cursor支持的POJO,然后在代码上很漂亮。

下面是一个示例实现,用户工程师可以快速将不透明光标转换为明确定义的用户对象,从那时起,它就可以像普通POJO一样传递和访问,只要后备光标未关闭。 SmartUserCursor是我编写的一个特殊类,用于确保在访问游标之前记住并恢复游标位置,并且它还存储游标列索引,因此查找速度很快。

实施例

public class User {

    private final SmartUserCursor mCursor;

    public User(SmartUserCursor cursor, int position) {
        mCursor = new SmartUserCursor(cursor, position);
    }

    public long getUserId() {
        return mCursor.getLong(SmartUserCursor.Columns.userId);
    }

    public UserType getType() {
        return UserType.valueOf(mCursor.getString(SmartUserCursor.Columns.type));
    }

    public String getFirstName() {
        return mCursor.getString(SmartUserCursor.Columns.firstName);
    }

    public String getLastName() {
        return mCursor.getString(SmartUserCursor.Columns.lastName);
    }

    public final String getFullName() {
        return getFirstName() + " " + getLastName();
    }

    public static User newUserFromAdapter(BaseAdapter adapter, int position) {
        return new User((SmartUserCursor)adapter.getItem(position), position);
    }

    public static User newUserBlocking(Context context, long UserId) {
        Cursor cursor = context.getContentResolver().query(
                Users.CONTENT_URI_CLIENT,
                Users.DEFAULT_USER_PROJECTION,
                Users.Columns.USER_ID+"=?",
                new String[] {String.valueOf(UserId)},
                null
        );

        if (cursor == null || !cursor.moveToFirst()) {
            throw new RuntimeException("No User with id " + UserId + " exists");
        }

        return new User(new SmartUserCursor(cursor, Users.DEFAULT_USER_PROJECTION), -1);
    }

    public final void closeBackingCursor() {
        mCursor.close();
    }

}

答案 2 :(得分:9)

对实体对象(PO​​JO)投一票。传递游标,特别是UI层,对我来说感觉很不对劲(无论Android sdk是否意味着这样做)。通常有几种方法来填充UI,我倾向于避免那些直接使用游标的方法。例如,要填充我的自定义列表视图,我使用SimpleAdapter并使我的集合对象能够将自己的表示形式返回给SimpleAdapter构造函数的List<? extends Map<String, ?>>

我使用一种模式,其中每个表都由实体对象包装,并且有一个提供程序类,用于处理与该实体关联的CRUD操作。 (可选)如果我需要集合的扩展功能,我也将它们包装起来(即。EntityItems extends ArrayList<EntityItem>)提供程序有一个基类,我将引用传递给DbAdapter类,该类在数据库周围进行繁重的工作。

除了个人偏好之外,最大的原因是我希望尽可能远离我的UI隐藏这种代码:

String something = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_CONSTANT));

如果我在UI层中看到这种内联代码,我通常会看到更糟糕的潜伏在拐角处。也许我只是花了太多时间在大型团队的企业界工作,但我赞成可读性,除非有一个合理的性能问题或者它是一个足够小的任务,表达性只是企业上的过度杀伤。

答案 3 :(得分:2)

答案是4岁。 我认为现在我们已经拥有了CPU能力来逃避更多的东西。我的想法是只与POJO和ArrayLists一起工作;并扩展CursorLoader以将光标映射到后台的POJO并将arraylist传递给activity;

除非你查询数百行,但是,你经常这样做与使用POJO,getter和setter的好处