I looked in the android documentation for an answer to my question, but I couldn't find it. To create a recyclerview using the information contained in these classes, how can I get a list of this information in Room
@Entity(
foreignKeys = [
ForeignKey(
entity = City::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("cityfk"),
onDelete = ForeignKey.NO_ACTION
)
]
)
data class Address(
@PrimaryKey
@ColumnInfo
var id: Long = 0
) : Serializable {
@ColumnInfo
var name: String = ""
@ColumnInfo(index = true)
var cityfk: Long = 0
}
@Entity(
foreignKeys = [
ForeignKey(
entity = State::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("statefk"),
onDelete = ForeignKey.NO_ACTION
)
]
)
data class City(
@PrimaryKey
@ColumnInfo
var id: Long = 0
) : Serializable {
@ColumnInfo
var name: String = ""
@ColumnInfo(index = true)
var statefk: Long = 0
}
@Entity
data class State(
@PrimaryKey
@ColumnInfo
var id: Long = 0
) : Serializable {
@ColumnInfo
var name: String = ""
}
How can I get a list of addresses listing the classes?
How to get a result like this in ANSI SQL:
select ADDRESS.NAME ADDRESS
, CITY.NAME CITY
, STATE.NAME STATE
from ADDRESS
join CITY
on CITY.ID = ADDRES.CITYFK
join STATE
on STATE.ID = CITY.STATEFK
You would typically have a POJO to represent the combined data. You can then either have a field/variable for the extracted columns noting that values are matched to the liked named variable.
You can use @Embedded to include an entity in it's entirety so in theory embed Address City and State.
You can use @Embedded along with @Relation for the child (children) BUT not for grandchildren (eg State). You would need an underlying City with State POJO where City is embedded and State is related by an @Relation.
Variable/Column name issues
Room maps columns to variable according to variable names. So there will be issues with id 's and name columns if using the simpler @Embedded for all three entities.
I would suggest always using unique names eg addressId, cityId, StateId, (at least for the column names eg @ColumnInfo(name = "addressId")) but simpler to just have var addressid.
An alternative is the use the @Embedded(prefix = "the_prefix") on some, this tells room to match the variable to column name with the prefix so you need to use AS in the SQL. Obviously the_prefix would be changed to suit.
The Dao's
if using @Embedded with @Relation then you simply need to get the parent so
@Query("SELECT * FROM address")
fun getAddressWithCityAndWithState(): List<AddressWithCityAndWithState>
You would also need the accompanying CityWithState POJO with City @Embedded and State with @Relation.
If Embedding Address, City and State with City having a prefix of "city_" and state having a prefix of "state_" then you would use something like:-
@Query("SELECT address.*, city.id AS city_id, city.name AS city_name, state.id AS state_id, state.name AS state_name FROM address JOIN city ON address.cityfk = city.it JOIN state ON city.statefk = state.id")
fun getAddressWithCityAndWithState(): List<AddressWithCityAndWithState>
Note the above is in-principle.
Working Example
The following is a working example based upon
First changes to the Address, City and State to rename the columns:-
Address :-
@Entity(
foreignKeys = [
ForeignKey(
entity = City::class,
parentColumns = arrayOf("city_id"), //<<<<<<<<<< CHANGED
childColumns = arrayOf("cityfk"),
onDelete = ForeignKey.NO_ACTION
)
]
)
data class Address(
@PrimaryKey
@ColumnInfo(name ="address_id") //<<<<<<<<<< ADDED name
var id: Long = 0
) : Serializable {
@ColumnInfo(name = "address_name") //<<<<<<<<<< ADDDED name
var name: String = ""
@ColumnInfo(index = true)
var cityfk: Long = 0
}
City :-
@Entity(
foreignKeys = [
ForeignKey(
entity = State::class,
parentColumns = arrayOf("state_id"), //<<<<<<<<<< changed
childColumns = arrayOf("statefk"),
onDelete = ForeignKey.NO_ACTION
)
]
)
data class City(
@PrimaryKey
@ColumnInfo(name = "city_id") // <<<<<<<<<< ADDED name
var id: Long = 0
) : Serializable {
@ColumnInfo(name = "city_name") //<<<<<<<<<< ADDED name
var name: String = ""
@ColumnInfo(index = true)
var statefk: Long = 0
}
State :-
@Entity
data class State(
@PrimaryKey
@ColumnInfo(name = "state_id") // ADDED name
var id: Long = 0
) : Serializable {
@ColumnInfo(name = "state_name") // ADDED name
var name: String = ""
}
Next the POJO AddressWithCityWithState :-
data class AddressWithCityWithState (
@Embedded
val address: Address,
@Embedded
val city: City,
@Embedded
val state: State
)
prefix =?
requiredA suitable DAO :-
@Query("SELECT * FROM address JOIN city on address.cityfk = city.city_id JOIN state ON city.statefk = state.state_id")
fun getAllAddressesWithCityAndWithState(): List<AddressWithCityWithState>
Using the above:-
allDao = db.getAllDao()
var state = State()
state.name = "State1"
var stateid = allDao.insert(state)
var city = City()
city.name = "City1"
city.statefk = stateid
var cityid = allDao.insert(city)
var address = Address()
address.name = "Address1"
address.cityfk = cityid
allDao.insert(address)
for(awcws: AddressWithCityWithState in allDao.getAllAddressesWithCityAndWithState()) {
Log.d("DBINFO","${awcws.address.name}, ${awcws.city.name}, ${awcws.state.name}")
}
The result in the log being:-
2021-11-22 07:43:28.574 D/DBINFO: Address1, City1, State1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.