Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query nested Embeded objects using Room Persistance Library in android?

Consider I have 3 classes User, Address, Location

class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;

    @Embedded(prefix = "home_")
    public Location homeLocation;

    @Embedded(prefix = "office_")
    public Location officeLocation;
}

class Location{
     public long lat;
     public long lng;
}

@Entity
class User {
    @PrimaryKey
    public int id;

    public String firstName;

    @Embedded(prefix = "addr_")
    public Address address;
}

How should i write the query to get the users whose home location is between certain latitude and longitude boundary ?

Ex: If i want to find all users whose home location is between these two points Location1(13.135795,77.360348) & Location2(12.743639, 77.901424). My query would look something like this -

select * from User where address.homelocation.lat < :l1_latitude && address.homelocation.lat > l2_latitude && address.homelocation.lng > :l1_longitude && address.homelocation.lng < :l2_longitude

If i have to use prefix in the embedded location from my understanding, correct me if am wrong, all the fields inside address will get appended with prefix. So i can query city as addr_city and if i have to query lat inside the homeLocation then will it become addr_home_lat ?

Is nested embedded objects permitted in room database? If yes then how do i query the nested embedded objects?

Need some help here. Thank you.

like image 408
SkyTreasure Avatar asked Jan 17 '18 07:01

SkyTreasure


People also ask

Is Room database relational?

Because SQLite is a relational database, you can define relationships between entities. Even though most object-relational mapping libraries allow entity objects to reference each other, Room explicitly forbids this.

Is room in Android an ORM?

Is Android Room an ORM? Room isn't an ORM; instead, it is a whole library that allows us to create and manipulate SQLite databases more easily. By using annotations, we can define our databases, tables, and operations.

What is Android room database?

What is a Room database? Room is a database layer on top of an SQLite database. Room takes care of mundane tasks that you used to handle with an SQLiteOpenHelper . Room uses the DAO to issue queries to its database. By default, to avoid poor UI performance, Room doesn't allow you to issue queries on the main thread.


1 Answers

Yes "nested embedded objects" are permitted inside ROOM. You can write a User class which has an embedded Address class as which contains a embedded Location class.

Each time when an embedded object is added, room flattens out the table. In your case room generates a table called "User" with the following columns:

id, firstName, addr_street, addr_state, addr_city, addr_post_code, addr_home_lat, addr_home_lng, addr_office_lat, addr_office_lng

So your query should be like :

@Query("SELECT * FROM User WHERE " +
        "addr_home_lat BETWEEN :lat1 AND :lat2" +
        " AND addr_home_lng BETWEEN :lng1 AND :lng2")
List<User> findInRange(long lat1, long lat2, long lng1, long lng2);

Notice that "lat" has been flattened to "addr_home_lat" and "lng" to "addr_home_lng". So you can use these column names for applying the filter logic.

In case you misspelled a column name for example "home_lng" instead of "addr_home_lng", then room will find that out and give you an error :

There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: home_lng)

For more information on room database, check out the Google I/O talk.

like image 60
Sonu Sanjeev Avatar answered Oct 20 '22 00:10

Sonu Sanjeev