Query dynamically with greenDao

2019-07-01 18:05发布

I need to verify some conditions to create a complete query:

QueryBuilder qb = getMyObjDao().queryBuilder();

if ( someCondition )

 qb.where(MyObjDao.Properties.Prop1.eq(someValue)); 

else
qb.whereOr(MyObjDao.Properties.Prop2.eq(someValue),MyObjDao.Properties.Prop2.eq(someValue));

if ( someOtherCondition )

 qb.where(MyObjDao.Properties.Prop3.eq(someValue)); 

else

 qb.whereOr(MyObjDao.Properties.Prop4.eq(someValue));

So is it possible to concatenate query builder conditions and create query builder dynamically? or anything so:

(a = '%'+condition1 or a = '%'+condition1+'%' or a = condition1 + '%') and
|(b = '%'+condition2 or b = '%'+condition2+'%' or b = condition2 + '%') and ....

How make that in greenDao?

1条回答
冷血范
2楼-- · 2019-07-01 18:23

QueryBuilder.and() and QueryBuilder.or() are used to combine WhereConditions. The resulting WhereConditions have to be used inside QueryBuilder.where() (which will combine the conditions using AND) or QueryBuilder.whereOr().


Please notice, that all your queries don't make much sense. As consequence the code I give you may not work as you expected, as I am just guessing what you expect. as example you can take qb.whereOr(MyObjDao.Properties.Prop2.eq(someValue),MyObjDao.Properties.Prop2.eq(someValue))

This translates to where (Prop2 = someValue OR Prop2 = someValue) or maybe to where (Prop2 = 'someValue' OR Prop2 = 'someValue'). In each of them the OR and the second statement are obsolete.

Another example is (a = '%'+condition1 or a = '%'+condition1+'%' or a = condition1 + '%') and (b = '%'+condition2 or b = '%'+condition2+'%' or b = condition2 + '%') and .... If you are not searching for strings with % in it, the query with a where-clause like this is going to return none or false results.


For:

(a = '%'+condition1 or a = '%'+condition1+'%' or a = condition1 + '%') and
(b = '%'+condition2 or b = '%'+condition2+'%' or b = condition2 + '%') and ....

You can use something like this:

ArrayList<WhereCondition> and = new ArrayList<WhereCondition>();

if (condition1 != null) {
    and.add(queryBuilder.or(
            YourDao.Properties.a.eq("%"+condition1),
            YourDao.Properties.a.eq("%"+condition1+"%"),
            YourDao.Properties.a.eq(condition1+"%")));
}

if (condition2 != null) {
    and.add(queryBuilder.or(
            YourDao.Properties.a.eq("%"+condition2),
            YourDao.Properties.a.eq("%"+condition2+"%"),
            YourDao.Properties.a.eq(condition2+"%")));
}

...

if (and.size() == 1) {
    queryBuilder.where(and.get(0));
} else if (and.size() > 1) {
    WhereCondition first = and.remove(0);
    queryBuilder.where(first, and.toArray(new WhereCondition[and.size()]));
}

UPDATE

Of course you can use another approach without dynamic list as well:

For:

QueryBuilder qb = getMyObjDao().queryBuilder();

if ( someCondition )

 qb.where(MyObjDao.Properties.Prop1.eq(someValue)); 

else
qb.whereOr(MyObjDao.Properties.Prop2.eq(someValue),MyObjDao.Properties.Prop2.eq(someValue));

if ( someOtherCondition )

 qb.where(MyObjDao.Properties.Prop3.eq(someValue)); 

else

 qb.whereOr(MyObjDao.Properties.Prop4.eq(someValue));

You can use this:

QueryBuilder<MyObj> queryBuilder = getMyObjDao().queryBuilder();
WhereCondition where = null;

if (someCondition1) {
    WhereCondition cond = MyObjDao.Properties.Prop1.eq(someValue);
    if (where == null) {
        where = cond;
    } else {
        where = queryBuilder.and(where, cond);
    }
} else {
    WhereCondition cond = queryBuilder.or(
            MyObjDao.Properties.Prop2.eq(someValue),
            MyObjDao.Properties.Prop2.eq(someOtherValue));
    if (where == null) {
        where = cond;
    } else {
        where = queryBuilder.and(where, cond);
    }
}

if (someOtherCondition) {
    WhereCondition cond = MyObjDao.Properties.Prop3.eq(someValue);
    if (where == null) {
        where = cond;
    } else {
        where = queryBuilder.and(where, cond);
    }
} else {
    WhereCondition cond = MyObjDao.Properties.Prop4.eq(someValue);
    if (where == null) {
        where = cond;
    } else {
        where = queryBuilder.or(where, cond2);
    }
}

List<YourObj> result = queryBuilder.where(where).list();

As you see there are a lot of possiblities how you can combine WhereConditions at runtime using greendao. But as long as you don't give a detailed example and description of what you really want to do, nobody can help you.

By the way:

  • Using where() or whereOr() doesn't make any difference, if you are only using one WhereCondition.
  • you probably wanted to query: (a like '%'+condition1 or a like '%'+condition1+'%' or a like condition1 + '%') instead of (a = '%'+condition1 or a = '%'+condition1+'%' or a = condition1 + '%').
  • notice, that (a like '%'+condition1 or a like '%'+condition1+'%' or a like condition1 + '%') is equal to (a like '%'+condition1+'%') since every result that matches a like '%'+condition1 or a like condition1+'%' will also match a like '%'+condition1+'%'.
查看更多
登录 后发表回答