我有一个简单的 Notes 应用程序,其功能与 Android NotePad 示例类似。一个补充是每个笔记都可以有标签。一个 Note
可以有多个 Tag
,一个 Tag
可以属于多个 Note
- 从而使其成为多个一对多关系。
我已经使用外键和映射表完成了数据库设计。现在,我希望我的应用程序能够插入 Android 搜索框架,这需要使用 ContentProvider
来公开我的数据。
对于这种情况,是否有可以遵循的最佳实践?我确实找到了一些相关的问题,但大多数都涉及一对多关系(这个例子)。我确实从这些问题中得出结论,最好每个数据库都有一个 ContentProvider
,然后使用 Matcher 概念来解析数据库中的多个表。这仍然留下了其他问题。
-
给定一个Note ID
,我想返回与该Note关联的所有标签。对于这种情况,我该如何设置 ContentUri
? "content://myexample/note/#"
和 "content://myexample/tag/#"
都无法达到此目的。
-
我重写的 6 个 ContentProvider
方法都不适合这样的目的,不是吗?我当然可以引入一种新方法,但这不会被我的 ContentProvider
的使用者理解。
预先感谢您的建议。
I have a simple Notes app which is similar in functionality to the Android NotePad sample. One addition is that every note can have Tags. A Note
can have several Tag
s and a Tag
can belong to several Note
s - thus making this a many-to-many relationship.
I have completed the DB Design using Foreign Keys and a Mapping Table. Now, I wish my app to plug into the Android Search Framework, which necessitates the use of a ContentProvider
to expose my data.
Are there any best practices to be followed for this scenario? I did find a few related questions on SO, but most of them dealt with one-to-many relationships (this one for example). I did conclude from these questions that it is best to have a single ContentProvider
per DB, and then use the Matcher concept to resolve multiple tables within the DB. That still leaves other questions open.
-
Given a Note ID
, I would like to return all the tags associated with that Note. How do I go about setting up the ContentUri
for such a case? Neither of "content://myexample/note/#"
and "content://myexample/tag/#"
would serve the purpose.
-
None of the 6 ContentProvider
methods which I override would suit such a purpose, would they? I can of course, introduce a new method, but that would not be understood by the consumers of my ContentProvider
.
Thanks in advance for your suggestions.
发布评论
评论(2)
现在我发现了一些关于 Android ContentProvider 中多对多条目关系的很酷的东西。答案来自Google I/O 2011官方Android客户端源代码。例如,在Google I/O应用程序中,有一个条目名为
Session
,另一个条目为Speaker.一个
Session
可能有多个Speaker
,并且一个Speaker
将参加多个Session
。那么,让我们看看谷歌的解决方案:
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleProvider.java
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleContract.java
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleDatabase.java
也许这个答案会有所帮助你们。
Now I find some cool stuff about the many-to-many entry relationship in Android ContentProvider. The answer comes from the Google I/O 2011 Offcial Android Client source code.For example, in the Google I/O app, there is a entry called
Session
and another entry isSpeaker
. OneSession
maybe have severalSpeaker
and oneSpeaker
will attend severalSession
.So,let's have a look about the google's solution:
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleProvider.java
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleContract.java
https://github.com/google/iosched/blob/2011/android/src/com/google/android/apps/iosched/provider/ScheduleDatabase.java
Maybe this answer will help you guys.
是的,当你想实现搜索时,你需要使用 ContentProvider 来实现它。
您可以使用现有的内容提供程序来检索与注释关联的标签。
您可以定义另一个 URL,例如“content://myexample/note/tag/#”形式,以获取与特定节点关联的所有标签。
您需要添加另一个必须在 URI 匹配器中匹配的 URI。
说类似 GET_NOTE_TAGS = 3;
在 ContentProvider 的 getType 方法中,返回适当的 mime 类型。我猜这将与标签的 mime 类型相同,因为您返回相同的标签。
然后在您的查询/更新/删除/插入方法中解析传入的 URI 以将其与“content://myexample/note/tag/#”进行匹配。然后在您的数据库或内容上适当地实现您的查询并返回您需要返回的标签。
“content://myexample/note/tag/#”架构只是一个示例,您可以在同一 ContentProvider 中使用多个 URI。
您还声明必须连接表。这可以使用 db.query 来完成,如果它变得复杂,您可以使用原始查询,从数据库中获取您需要的数据。
Yes you need to implement it using ContentProvider when you want to implement search.
You can use your existing content provider to retrieve the tags associated with a note.
you can define another URL say in the form "content://myexample/note/tag/#" to get all the tags associated with a particular node.
You will need to add another URI that has to be matched in your URI matcher.
say something like GET_NOTE_TAGS = 3;
In the getType method of your ContentProvider, return the appropriate mime type. I would guess that this wil be the same as the mime type for tags, since you are returning the same tags.
Then in your query/update/delete/insert methods parse the incoming URI to match it with "content://myexample/note/tag/#". Then implement your query appropriately on your database or your content and return the tags that you need to return.
The "content://myexample/note/tag/#" schema is just an example and you can use multiple URIs within the same ContentProvider.
You also stated that you have to join tables. that can be done using db.query and if it becomes complicated you may use rawqueries, to get the data as you need from the database.