0

I've got a list of primary keys and I need these elements from my greendao database.

The most trivial method would be to query each object idividually and inserting it into a list:

public List<MyObject> getMyObjectByIds(List<String> ids) {
    List<MyObject> result = new ArrayList<MyObject>();

    for (String id : ids) {
        QueryBuilder<MyObject> queryBuilder = myObjectDao.queryBuilder();
        MyObject myObject = queryBuilder.where(MyObjectDao.Properties.Id.eq(id)).unique();
        result.add(myObject);
    }

    return result;
}

However this seem quite ineffective since it would have to do ids.size() queries. A single query with multiple OR statements would be better. However, since the whereOr() and or() methods only except 2 or more parameters you'd have to make quite a few IF ELSE statements to catch lists with 0, 1 or 2 ids:

public List<MyObject> getMyObjectByIds(List<String> ids) {
    QueryBuilder<MyObject> queryBuilder = myObjectDao.queryBuilder();

    if (ids.size() == 0) {
        List<MyObject> result = new ArrayList<MyObject>();
        return result;
    } else if (ids.size() == 1) {
        return queryBuilder.where(MyObjectDao.Properties.Id.eq(ids.get(0))).list();
    } else if (ids.size() == 2) {
        queryBuilder.whereOr(MyObjectDao.Properties.Id.eq(ids.get(0)), MyObjectDao.Properties.Id.eq(ids.get(1)));
        return queryBuilder.list();
    } else if (ids.size() >= 3) {
        queryBuilder.whereOr(MyObjectDao.Properties.Id.eq(ids.get(0)), MyObjectDao.Properties.Id.eq(ids.get(1)), getWhereConditionsEqIdRefFromThirdElementOn(ids));
        return queryBuilder.list();
    }
}

private WhereCondition[] getWhereConditionsEqIdFromThirdElementOn(List<String> ids) {
    WhereCondition[] whereConditions = new WhereCondition[ids.size() - 1];
    for (int i = 2; i < ids.size(); ++i) {
        whereConditions[i] = MyObjectDao.Properties.Id.eq(ids.get(i));
    }
    return whereConditions;
}

Honestly, this might be faster but it still seems quite ugly to me. Is there another way? Or do I have to make a raw query?

Oliver Metz
  • 2,712
  • 2
  • 20
  • 32

3 Answers3

5

As pointed out by Dragon Bozanovic. GreenDAO does have IN operator for this purpose.

public List<MyObject> getMyObjectByIds(List<String> ids) {
    return myObjectDao.queryBuilder()
             .where(MyObjectDao.Properties.Id.in(ids)).list();
}
Asif Mujteba
  • 4,596
  • 2
  • 22
  • 38
  • Thats exactly what I was looking for. For some reason I was only looking at the functions of the `QueryBuilder` when the `Property` itself had the solution. [link] (http://greendao-orm.com/javadoc/greendao/de/greenrobot/dao/Property.html#in%28java.util.Collection%29) – Oliver Metz Jul 02 '15 at 18:45
2

I may be missing something, but this looks like a by the book example for using in operator.

Community
  • 1
  • 1
Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
0

You could try doing something like this:

public List<MyObject> getMyObjectByIds(List<String> ids) {

    List<MyObject> result = new ArrayList<MyObject>();
    QueryBuilder<MyObject> queryBuilder = myObjectDao.queryBuilder();
    for (String id : ids) {
        queryBuilder.whereOr(MyObjectDao.Properties.Id.eq(id));
    }

    return queryBuilder.list();
}

According to the documentation here, it seems that each whereOr function adds the given conditions to the previous where clause using an logical OR. It might be necessary to add a initial where clause before the for.

Jofre Mateu
  • 2,390
  • 15
  • 26
  • 1
    This won't do the trick since the `whereOr` function requires at least two parameters. Thats exactly the problem I needed to solve... – Oliver Metz Jul 02 '15 at 18:39