I am using my custom ContentProvider to communicate with sqlite database. I would like to display on a list (using ListFragment), data that comes from two tables (with many to many relation). The only solution I can think of for such case is to use rawQuery. And the questions is, if it is a good practice, or should I solve this in some other way?
Example of tables:
Table A: ID, COLUMN_FROM_A
Table B: ID, COLUMN_FROM_B
Joining table AB: ID, FK_ID_A, FK_ID_B
Example of overridden query method in ContentProvider:
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); Cursor cursor = null; int uriType = URIMatcher.match(uri); switch (uriType) { case TABLE_A_URI: queryBuilder.setTables("TABLE_A"); cursor = queryBuilder.query(databaseHelper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder); break; case TABLE_B_URI: queryBuilder.setTables("TABLE_B"); cursor = queryBuilder.query(databaseHelper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder); break; case TABLE_JOIN_A_B_URI: cursor = databaseHelper.getReadableDatabase().rawQuery("select a.COLUMN_FORM_A, b.COLUMN_FROM_B from TABLE_A a, TABLE_B b, TABLE_AB ab where ab.FK_ID_A=a.ID and ab.FK_ID_B=b.ID", null); break; default: throw new IllegalArgumentException("Unknown URI"); } cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; }
On the other hand, RawQuery serves as an escape hatch where you can build your own SQL query at runtime but still use Room to convert it into objects. RawQuery methods must return a non-void type. If you want to execute a raw query that does not return any value, use RoomDatabase#query methods.
RawQuery is for people who understand SQL and aren't afraid of it, query is for people who don't.
A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data. However, content providers are primarily intended to be used by other applications, which access the provider using a provider client object.
RawQuery(String, String[]) Runs the provided SQL and returns a Cursor over the result set. RawQuery(String, String[], CancellationSignal) Runs the provided SQL and returns a Cursor over the result set.
It's a good and common practice, very appropriate in this case.
I don't foresee any problems, we have used it in many apps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With