ORMLite - 从两个表中查找结果的并集

时间:2013-08-29 07:13:31

标签: android join ormlite

我的Android应用程序中有两个数据库持久化类使用ORMLite -

Contact

@DatabaseTable(tableName = "contacts")
public class Contact {
    @DatabaseField(id = true, columnName = "_id")
    private int id;
    @DatabaseField
    private String first_name;
    @DatabaseField
    private String last_name;
    @ForeignCollectionField(eager = false)
    ForeignCollection<Phone> phones;
}

Phone

@DatabaseTable(tableName = "phones")
public class Phone {
    @DatabaseField(id = true, columnName = "_id")
    private int id;
    @DatabaseField
    private String number;
    @DatabaseField(foreign = true)
    private Contact contact;
}

如您所见,Contact有很多Phone个。我尝试做的是在给定CharSequence约束的情况下生成查询,以查找first_namelast_namephone.number与约束匹配的任何联系人。

很容易获得与first_namelast_name匹配的联系人:

RuntimeExceptionDao<Contact, Integer> contactsDao = getHelper().getContactsDao();
QueryBuilder<Contact, Integer> contactQb = contactsDao.queryBuilder();
Where contactWhere = contactQb.where();

contactWhere.or(
    contactWhere.like("first_name", "%" + constraint + "%"),
    contactWhere.like("last_name", "%" + constraint + "%")
);

PreparedQuery<Contact> pq = contactQb.prepare();

并且很容易获得与电话号码匹配的联系人:

RuntimeExceptionDao<Contact, Integer> contactsDao = getHelper().getContactsDao();
RuntimeExceptionDao<Phone, Integer> phonesDao = getHelper().getPhonesDao();
QueryBuilder<Contact, Integer> contactQb = contactsDao.queryBuilder();
QueryBuilder<Phone, Integer> phoneQb = phonesDao.queryBuilder();

phoneQb.where().like("number", "%" + constraint + "%");
PreparedQuery<Contact> pq = contactQb.join(phoneQb).prepare();

但是当我尝试将两者结合起来时,它似乎给了我最终光标中两个数据集的交集(正如你可以想象的那样,通常是0结果)。是否有某种方法可以获得数据集的并集?

我知道ORMLite不支持RIGHT JOIN样式查询或将数据从连接表返回到结果中,但这不是我想要的 - 我只需要的是Contacts

列表

另请注意,我使用的是CursorAdapter,因此(据我所知),我不能简单地发出两个请求,然后将生成的数组连接在一起。数据注定要显示在ListView

示例

contacts

|   id   |  first_name  |  last_name  |
---------------------------------------
|   10   |  Matthew     |  Smith      |
---------------------------------------
|   21   |  John        |  Smith      |
---------------------------------------

phones

|   id   |  number      | contact_id  |
---------------------------------------
|   99   |  0444444444  |     10      |
---------------------------------------
|  123   |  0444666666  |     21      |
---------------------------------------

搜索&#34; Smith&#34;将返回两个联系人。搜索&#34; 4444&#34;将只返回马修史密斯,搜索&#34; 0666&#34;只返回约翰史密斯,并搜索&#34; 044&#34;将返回两个联系人。

编辑 - 如果解决方案仅返回唯一结果,则奖励积分 - 我目前正在执行的方式的另一个副作用是每个结果都显示在ListView中多次 - 一次为其名称,另一次为每个Phone

1 个答案:

答案 0 :(得分:1)

  

但是当我尝试将两者结合起来时,它似乎给了我最终光标中两个数据集的交集(正如你可以想象的那样,通常是0结果)。是否有某种方法可以获得数据集的并集?

如果我理解马特,你要做的是对名称和数字使用相同的constraint并显示匹配的结果 - 因此单词&#34; union&#34; 。我想有一个nameConstraint然后numberConstraint不是一个选项。

看起来这里缺少一个功能。默认情况下,当ORMLite组合来自查询构建器和联接查询构建器的WHERE语句时,它当前使用AND。我刚刚将QueryBuilder.joinOr(...)innerJoinOr(...)添加到了ORMLite主干,它将使用版本4.47,使用OR

在此版本发布之前,您将不得不使用dao.queryRaw(...)方法,并以遗憾的方式执行此操作。