Search code examples
androidmany-to-manyandroid-contentprovider

Android Content Provider and Many-to-Many DB relationship


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 Tags and a Tag can belong to several Notes - 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.

  1. 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.

  2. 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.


Solution

  • 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.