我有3个表格,USER
,ENTRY
(对于输入的产品,不是创建PRODUCT表所必需的)和USER_COLLECTION
,这是USER
之间的表格和ENTRY
,因为一个条目可以有多个用户。
基本上:
用户= USERID | USER_NAME
条目= ENTRYID | ENTRY_NAME | ENTRYPRICE | ENTRY_DATE
Collection = COLLECTIONID | ENTRYID | USERID
我有一个用户表,在整个项目中都存在。他们可以创建条目(通常是某种价格的产品),并且可以将多个用户链接到某个条目(可以从列表中选择,因此用户可以在整个项目中保留)。
例如,我的表格如下:
User
--------------------------
user_id | user_name
--------------------------
1 | 'FOO'
2 | 'BAR'
3 | 'FOOBAR'
ENTRY
-----------------------------------------------------------------------
entryid | entry_name | entry_price | entry_date
-----------------------------------------------------------------------
0 | 'Banana' | 2.50 | 12/12/2012
COLLECTION
---------------------------------------
collectionid | entryid | userid
----------------------------------------
0 | 1 | 1
1 | 1 | 2
2 | 1 | 3
我有一个Banana,价格为2.50,有3个用户链接到它,Foo,Bar和Foobar。
现在,我想在我的应用程序中使用它并获取数据;除了我不知道从哪里开始。我尝试选择条目数据,使用该id循环收集数据,但这意味着我有两个游标打开,它将无法正常工作。尝试创建一个连接,但我真的不能做一个好的,主要是因为:
JOIN
---------------------------------------
collectionid | entryname | username
----------------------------------------
0 | Banana | FOO
1 | Banana | BAR
2 | Banana | FOOBAR
我无法迭代这一点,因为我会在Android代码中创建多个相同的条目对象...
希望我明白这一点。
if (cursor2.moveToFirst()) {
do {
Item i = new Item(<GET STUFF FROM CURSOR>);
i.addUser(new Person(<GET STUFF FROM CURSOR>)));
Log.d("TAG", i.getUsersPaying().size() + "");
} while (cursor2.moveToNext());
}
如果我使用它,我会创建Item i的多个实例。他们都是香蕉,而我只有1个项目香蕉,并添加了多个用户。
答案 0 :(得分:2)
首先,您可能需要考虑在连接查询中返回表中的ID。如果您返回entryid
列,事情就会容易一些。
只需制作一个Map<Integer, Item>
来存储您已经在循环中看到的项目。在检查每个光标时,请检查地图以查看是否已有实例。如果不这样做,只需制作一个新的并插入即可。
假设您的查询结果为:
JOIN
----------------------------------------------------
collectionid | entryname | entryname | username
----------------------------------------------------
0 | 1 | Banana | FOO
1 | 1 | Banana | BAR
2 | 1 | Banana | FOOBAR
2 | 2 | Apple | FOOBAR
您可以按如下方式修改代码:
Map<Integer, Item> items = new HashMap<Integer, Item>();
if (cursor2.moveToFirst()) {
do {
int itemId = cursor2.getInt(1);
Item i;
if (items.containsKey(itemId))
i = items.get(itemId);
else
{
i = new Item(<GET STUFF FROM CURSOR>);
items.put(itemId, i);
}
i.addUser(new Person(<GET STUFF FROM CURSOR>)));
Log.d("TAG", i.getUsersPaying().size() + "");
} while (cursor2.moveToNext());
}
答案 1 :(得分:1)
您需要维护已加载到内存中的实体的字典。例如,在一个可以保留的背景片段中。
基本上你会这样做:
Item i = cacheFragment.createOrGetEntry( cursor.getLong( ENTRY_ID_COLUMN_INDEX ) );
Person p = cacheFragment.createOrGetPerson( cursor.getLong( PERSON_ID_COLUMN_INDEX ) );
当然,您的查询还必须返回您需要的所有行的ID(entryId和personId)。但是连接查询是有效地执行此操作的方法,因此请保留您对此所做的操作,并添加两个缺少的ID列。
createOrGetPerson方法如下所示:
public Person createOrGetPerson(long id) {
Entry<Long, Person> p = personDictionnary.get( id ); // can be a HashMap or even better, a SparseArray
if (p==null) {
p = new Person(id);
personDictionnary.put(p); // Remember it for next time
}
return p;
}
你还应该看一下处理这类问题的数据持久性框架或ORM框架(例如Hibernate,即使我不知道这是否适用于Android)。