I need to migrate from Sqlite database to room in my application, but before migrating i have some doubts regrading room database i have searched through many sites but i have not satisfied with the solution.
My table schema will be changing frequently through API calls, is it possible in room ?
We need entities to map Column Name with entity properties, Since my table schema changes frequently how do i create the entity ?
Is it possible to map the multiple columns to single field property in entity, like say
Table A has three columns COL_A,COL_B,COL_C
#Entity
class TableA{
#ColumnInfo("COL_A")
val columnA : String
#ColumnInfo("COL_B,COL_C")
val columns : Map<String,String>
}
Is it possible to create entity like above in room?
Can anyone clear the above doubts ?
Related
I am trying to implement a Room database using a one-to-many relation, following the Android Room training (https://developer.android.com/training/data-storage/room/relationships#one-to-many).
However, I can't find a way to add a condition on the second table.
For example, to fetch all UserWithPlaylists, for users above 25 and having playlists names starting with "play" this does not work because Room does not automatically group the results (and a GROUP BY clause prevents creating the List of Playlist):
#Transaction
#Query("SELECT User.* FROM User, Playlist WHERE User.age > 25 AND Playlist.playlistName LIKE play%")
public List<UserWithPlaylists> getUsersWithPlaylistsSpecific();
I already tried solutions such as embedding one entity in another and using
#Embedded(prefix = "PETS_")
as suggested here: https://stackoverflow.com/a/50698610 but without success.
I also want to avoid this method using a Java Map.
How can I achieve this?
Hi I am developing an android app and I am using room DB and I have created one table and now I want to add another table I need to write a migration for that and in-migration I need to write full SQL queries for the new table assume I have more than 20 fields how complex will be the query.
In SQLite, we need to write such complex queries which sometimes becomes complicated to write and find errors So, room DB came to resue but now we need to do the same in the room DB migration. How does it useful then?
If we use SQLite, then if we already added one table and now We want to add another table then we can just uninstall the application and new tables will be generated, but in-room DB this is not a case I tried the same thing but it is still showing me that you need to write a migration for the new table. So, in this case, while developing there will a lot of migration scripts that will be hard to maintain at some point in the future.
How does it useful then I have to write a multiple create queries while developing the app this is a very basic flow in any application.
Once we go to prodution then it makes sense to write migration for every table but not in the developing mode.
How does room DB make developr job eaiser?
I have more than 20 fields how complex will be the query.
It can be very simple as an Entity defines an Object e.g. your 20 columns and to get the 20 columns can be as simple as
#Query(SELECT * FROM thetable)
List<Thetable> getAll();
The above being in an Interface that is annotated with #Dao and all you do in the code is retrieve an instance from the built room database and then use the getAll method which returns a List of Thetable objects. Each with all the member variables populated from the database.
e.g. you could have :-
mMyTheTableDaoObject = mMyBuiltRoomDatabase.getAll();
List<TheTable> myTheTableList = mMyTheTableDaoObject.getAll();
for(TheTable t: myTheTableList) {
int current???? = t.get????();
}
While using standard/non-room then you would have to do something along the lines of :-
SQLitedatabase db = whatever_you_need_to_do_to_get_an_SQLiteDatabase_instance;
Cursor c = db.query("theTable",null,null,null,null,null,null);
ArrayList<TheTable> myTheTableList = new ArrayList();
while(c.moveToNext()) {
currentTheTable = new TheTable();
current.TheTable.setId = c.getLong(c.getColumnIndex("id");
current.TheTable.setNextColumn1 = c.getString("next_column1");
current.TheTable.setNextColumn2 = c.getString("next_column2");
........ another 17 similar lines of code
currentTheTable.setNextColumn20 = c.getString("next_column20");
myTheTableList.add(currentTheTable);
}
for(TheTable t: myTheTableList) {
int current???? = t.get????();
}
If we use SQLite, then if we already added one table and now We want to add another table then we can just uninstall the application and new tables will be generated, but in-room DB this is not a case I tried the same thing but it is still showing me that you need to write a migration for the new table.
Once we go to production then it makes sense to write migration for every table but not in the developing mode.
Rather then migrating simply delete the database (delete the App's data or uninstall the App, the database is stored in the default location (data/data/package_name/databases)) and rerun without changing the version. The database will be created as per the new schema. Perhaps utilising temporary code to load data accordingly.
How does room DB make developr job eaiser?
In Short ROOM generates what is termed as the boilerplate code from relatively simple code e.g the #Query above writes the underlying code to extract the data and build the objects (e.g. the code as above).
Please check the official document:
https://developer.android.com/training/data-storage/room/migrating-db-versions
Actually Room using SQLITE behind the scene. It provide you plethora of other facilities. In case of Migration you have to write full code to create table.
Harsh your question is valid in some way but as you know android is maintaining SQLite database and libraries like room, greendao or even native SQLiteOpenHelper
is handling the transaction with sqllite behind the scene for the developers.
In all the earlier libraries too you have to maintain versions of your database and which fields or tables have been added to your database and write migrations for the version upgrades of the database.
The beauty of room comes in play in how easy they have made the CRUD operations on the SQLite database and getting data wrapped in LiveData or Observable, not that you don't need to write migrations.
I am using Room Database for storing chat, I have one group table and I want to fetch three parameters like this query
My Group Entity class is GroupUserEntity.kt
#Query("SELECT DISTINCT group_id, group_name, group_image FROM group_user_table")
fun getAllGroups() : List<ENTITY_CLASS>
I am not able to use my Group Entity class(GroupUserEntity.kt) over ENTITY_CLASS, forcefully I have to make new Entity class(Pojo Class) to fetch those three values.
So my questions is, there is any way to utilize my old Entity class(GroupUserEntity.kt) to fetch all groups? or I need to make a new POJO class for that?
It depends on number of variables in your GroupUserEntity.kt.
If for example you have group_id, group_name, group_image and group_category (total 4) in GroupUserEntity.kt and you are fetching data for only 3 variables then it will show you an error. (Cursor mismatch).
To avoid this either call ALL the columns values from database to match GroupUserEntity.kt, or create a new POJO.
Not sure if sqlite actually supports this, if it's a room db bug, or if I'm doing something wrong, but insertion of rows using predefined data during a migration doesn't actually work:
Using the Persistence Migration Sample as an example:
In the UsersDatabase for the MIGRATION_2_3 I add in this line to the migration:
database.execSQL("INSERT INTO Users (userid, username, last_update) VALUES (456, 'asdf', 123), (999, '3524', 4567);");
In the MigrationTest I add more assertions:
List<User> allUsers = usersDatabase.userDao().getAllUsers();
Assert.assertEquals(4, allUsers.size());
Result:
The test fails and the rows were not created, but the migration was run until completion! I need this working, does anybody have a way to do this or are there any good alternatives?
I have three tables Notes, Tags and join table with foreign keys of Note and Tag called NoteTagJoin, but how can I return Note with all Tags as one response?
Here is query to get Note and Tags:
SELECT n.*,t.* FROM notes n INNER JOIN note_tag_join nt ON n.entryId = nt.noteId INNER JOIN tags t ON t.tagId = nt.tagId WHERE n.entryId =:noteId
And here is response class which has to hold note and list of tags:
data class NoteResponse(
#Embedded
var note: Note? = null,
#Relation(parentColumn = "entryId", entityColumn = "tagId", entity = Tag::class)
var tags: List<Tag>? = null
)
But tags list is empty on response just note is there, I know for sure that Tags and Note exists in db and Join table has right foreign keys because all other queries works so my guess is that Query is wrong or NoteResponse class is wrong because I use annotation #Relation which I don't need, but if I don't add #Relation annotation on tags it throws error that room doesn't know what is this list so how to do it? I can't find any references for this, documentation only mentions embedding one class in POJO but no examples for Lists and all similar posts talks only about inserting list.
please see my realization of many-to-many relationship CinemaActorJoinDao
You can instead my code , replace with your , if you have any question , i will try ask to you :)