Query dynamically with greenDao

邮差的信 提交于 2020-01-03 19:43:06

问题


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:


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+'%'.


来源:https://stackoverflow.com/questions/19623523/query-dynamically-with-greendao

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!