Query
public
abstract
@interface
Query
implements
Annotation
androidx.room.Query |
Marks a method in a Dao
annotated class as a query method.
The value of the annotation includes the query that will be run when this method is called. This query is verified at compile time by Room to ensure that it compiles fine against the database.
The arguments of the method will be bound to the bind arguments in the SQL statement. See
Room only supports named bind parameter
Room will automatically bind the parameters of the method into the bind arguments. This is done
by matching the name of the parameters to the name of the bind arguments.
As an extension over SQLite bind arguments, Room supports binding a list of parameters to the
query. At runtime, Room will build the correct query to have matching number of bind arguments
depending on the number of items in the method parameter.
There are 4 type of statements supported in
For SELECT queries, Room will infer the result contents from the method's return type and
generate the code that will automatically convert the query result into the method's return
type. For single result queries, the return type can be any data object (also known as POJOs).
For queries that return multiple values, you can use
INSERT queries can return
UPDATE or DELETE queries can return
Flow
If you are using Kotlin, you can also return
Note that querying a table with a return type of
Keep nullability in mind when choosing a return type, as it affects how the query method handles
empty tables:
When the return type is When the return type is When the return type is
RxJava2
If you are using RxJava2, you can also return
Both
Additionally if the statement is an INSERT, UPDATE or DELETE then the return types,
You can return arbitrary POJOs from your query methods as long as the fields of the POJO match
the column names in the query result.
For example, if you have class:
:name
to avoid any confusion between the
method parameters and the query bind parameters.
@Query("SELECT * FROM song WHERE release_year = :year")
public abstract List<Song> findSongsByReleaseYear(int year);
@Query("SELECT * FROM song WHERE id IN(:songIds)")
public abstract List<Song> findByIds(long[] songIds);
For the example above, if the songIds
is an array of 3 elements, Room will run the
query as: SELECT * FROM song WHERE id IN(?, ?, ?)
and bind each item in the
songIds
array into the statement. One caveat of this type of binding is that only 999
items can be bound to the query, this is a limitation of SQLite (
Query
methods: SELECT, INSERT, UPDATE, and
DELETE.
List
or Array
.
In addition to these, any query may return Cursor
or any query
result can be wrapped in a LiveData
.
void
or long
. If it is a long
, the value is the
SQLite rowid of the row inserted by this query. Note that queries which insert multiple rows
cannot return more than one rowid, so avoid such statements if returning long
.
void
or int
. If it is an int
,
the value is the number of rows affected by this query.
Flow<T>
from query methods. This creates a
Flow<T>
object that emits the results of the query and re-dispatches the query every
time the data in the queried table changes.
Flow<T>
always returns the first row
in the result set, rather than emitting all of the rows in sequence. To observe changes over
multiple rows in a table, use a return type of Flow<List<T>>
instead.
Flow<T>
, querying an empty table throws a null pointer
exception.
Flow<T?>
, querying an empty table emits a null value.
Flow<List<T>>
, querying an empty table emits an empty
list. Flowable<T>
or
Publisher<T>
from query methods. Since Reactive Streams does not allow null
, if
the query returns a nullable type, it will not dispatch anything if the value is null
(like fetching an Entity
row that does not exist).
You can return Flowable<T[]>
or Flowable<List<T>>
to workaround this limitation.
Flowable<T>
and Publisher<T>
will observe the database for changes and
re-dispatch if data changes. If you want to query the database without observing changes, you can
use Maybe<T>
or Single<T>
. If a Single<T>
query returns null
,
Room will throw EmptyResultSetException
.
Single<T>
, Maybe<T>
and Completable
are supported.
class SongDuration {
String name;
@ColumnInfo(name = "duration")
String length;
}
You can write a query like this:
@Query("SELECT name, duration FROM song WHERE id = :songId LIMIT 1")
public abstract SongDuration findSongDuration(int songId);
And Room will create the correct implementation to convert the query result into a
SongDuration
object. If there is a mismatch between the query result and the fields of
the POJO, and as long as there is at least 1 field match, Room prints a
RoomWarnings.CURSOR_MISMATCH
warning and sets as many fields as it can.
Summary
Public methods | |
---|---|
String
|
value()
The SQLite query to be run. |
Inherited methods | |
---|---|
Public methods
value
public String value ()
The SQLite query to be run.
Returns | |
---|---|
String |
The query to be run. |