So I have two tables City and Street I wrote query to return City and its streets with one query response looks like this
1 City1
1 Street1
2 Street2
3 Street3
and I have POJO class for this response:
data class CityResponse(var city: City, var streets: List<Street>)
But I can't compile because it throws error:
error: Cannot figure out how to read this field from cursor private java.util.List<Street> streets
How can I write this response data class that room would understand what do I mean with variable streets: List<Street>
In this case used joins query and make one common pojo class that give both details. then make query like below ..
#Query("SELECT * FROM Student s LEFT JOIN BookIssue b ON s.StudentId =b.StudentId")
List<JoinData> getJoinData();
you can also implement inner join and others joins but make one single pojo that give both table record.
and also one more way first find city and make for loop and find based on city name into street and getting street data.
Related
Is it possible to store objects from a generated Protobuf Java class in a Room database? Do I need to serialize the objects and store the serialized versions inside of an Entity class?
You basically have two options. Serialise and save as a Blob (byte[]) or to have Entities that reflect the objects properties and if those are themselves are objects then like wise break them down. This latter approach is potentially more complicated but it does open the data to being more useful database wise.
In short serialise or not to serialise is a choice that would depend upon what is required. Do you just want to use the database for storage or do you want to take advantage of the searchability aspect offered by SQLite (Room).
As an example lets say you have a contract for an address that has the following properties:-
postbox (int)
street (string)
city (string)
country (string or probably more correctly a reference to a country object)
then if you serialise the object you have a string of bytes (byte[]) and all the data will be stored in a single column.
If you wanted to search for all addresses in a city that would be a) inefficient and also relatively difficult.
If each property were saved in a table with a column per property then that search for the city is straightforward e.g. SELECT your_columns FROM the_table WHERE city = 'MyCity';
If the address object were serialised and saved the you might be fortunate and be able to use SELECT serialised_address FROM the_table WHERE instr(serialised_address,hex('MyCity') > 0;
It depends upon how serialisation generates the underlying data
Underneath Room is SQLite and here's a quick SQLite example that demonstrates the difference assuming that the property markers are the property name (e.g. city) followed by = e.g. city MyCity is stored as city=MyCity converted to hex (bytes).
DROP TABLE IF EXISTS test1;
CREATE TABLE IF NOT EXISTS test1 (serialised_address BLOB);
CREATE TABLE IF NOT EXISTS test2 (postbox INTEGER, street TEXT, city TEXT, country TEXT);
INSERT INTO test1
VALUES(hex('postbox=1,street="The Street",city="MyCity",country="England"')),
(hex('postbox=1,street="The Street",city="NotMyCity",country="England"'))
;
INSERT INTO test2 VALUES(1,'The Street','MyCity','England'),(1,'The Street','NotMyCity','England');
SELECT *,null,null,null FROM test1 UNION SELECT * FROM test2;
SELECT 'S1',serialised_address,null,null,null FROM test1 WHERE instr(serialised_address,hex('MyCity')) > 0
UNION SELECT 'S2',serialised_address,null,null,null FROM test1 WHERE instr(serialised_address,hex('myCity')) > 0
UNION SELECT 'S3',* FROM test2 WHERE city = 'MyCity'
UNION SELECT 'S4',* FROM test2 WHERE city = 'mycity'
;
This creates 2 tables (Entities in Room speak).
Table test1 is for the serialised object address.
Table test2 stores the properties in individual columns.
Both tables are loaded with the equivalent data.
The first query gets the data from both tables using nulls for the 3 columns that don't exist in the test1 table
i.e. all the data is stored in the single column
The second query looks for the city called MyCity expecting to just extract that 1 city.
When run the results are :-
(i.e. 2 rows from each table)
and :-
As you can see 3 rows have been extracted not the expected 2 rows. This is because the search through the byte array for MyCity has also found NotMyCity.
I'm newbie to android and am learning the basics of kotlin/Room. As I head down the rabbit hole of data classes, DAOs joining tables, I am trying to understand why so many table/interfaces are used where multiple queries could achieve the same outcome?
Example: an application contains an address book of business contacts. A user can select one or more contacts for their address book from a large list. The aim is to only populate the users address book with the information of the contacts they have selected.
This would require:
A User table: containing unique user information for many users (userId, name, address...etc.)
A Contacts table: containing unique contact information for many contacts (contactId, name, address...etc.)
A joining table: containing the contact selections of each user (userId and contactId)
A UserWithContacts table: containing embedded user objects with a relation to the contact object in the joinging table.
The purpose of the UserWithContacts table as I understand it is to query directly and get a list of contact objects that have been selected by a specific user.
This structure, with adjoining DAOs, makes for a number of classes/interfaces/etc to keep track of.
Why is it better to take this approach and not simply query the joining table for a list of contactIDs based on a given userId, followed by a second query that returns the contact objects from the contact table with contact information? This would not required the additional UserWithContacts table or DAO interface.
For Example:
//Get a list of contactId's that have a common UserId
#Query("SELECT contactId FROM joiningTable WHERE userId =:userId")
fun getAllUserContactIds(userId: String): List<String>
//Get a list of Contacts objects from are contained within a list of Contact Ids
#Query("SELECT * FROM contactTable WHERE contactId IN (:contactIds)")
fun getAllUserContacts(contactIds: List<String>): List<Contact>
This pair of queries provides an equivalent list of Contact objects that can be used to populate the address book.
Can anyone describe why it is preferred to use multiple classes/interfaces instead of multiple queries?
Thanks in advance for your thoughts.
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.
Table -article-
id |nam|image|id_categor(FK)|
table category
id |categorieName|
I have two tables in the database. The first table has a foreign key to the second table. Can I get name from the second table by the foreign key ?
need a JSON like
"categories":[
{"categorieName":"test1",
"data":[
{
"name":"wallpaper1",
"image":"tv_101.jpg"
},
{
"name":"wallpaper2",
"image":"tv_102.jpg"
}
]
Welcome, You need to provide a better description with a better code so everyone can understand easily.
If I understand your problem properly then you need a join. You can use SQLite rawQuery to get the desired output.
For Example:
private final String JOIN_QUERY = "SELECT * FROM article a INNER JOIN categories b ON a.id=b.other_id WHERE b.property_id=?";
db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)});
EDIT: I still don't get your question but I think you are using PHP
First of all you cannot directly get the JSON from the database. What you need to do is:
Query your required data using PHP
SELECT * FROM categories then loop it in php and get all articles in each category by querying SELECT * FROM articles WHERE cate_id=loopCategoy_Id
And save it in a key value array
Then convert the array into JSON
Send JSON response
Did you try join ?
Joining two tables by common columns will definitely help here
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 :)