Est-il possible de construire une requête au moment de l'exécution?
@Query("SELECT * FROM playlist " +
"WHERE playlist_title LIKE '% :playlistTitle %' " +
"GROUP BY playlist_title " +
"ORDER BY playlist_title " +
"LIMIT :limit")
List<IPlaylist> searchPlaylists(String playlistTitle, int limit);
La partie limit
est facultative. C'est-à-dire qu'il devrait pouvoir effectuer la même requête avec ou sans limite.
Dans le cas précédent, il est possible de faire deux requêtes statiques avec et sans partie limite et une requête appropriée peut être utilisée à chaque fois. Mais parfois, nous pouvons avoir à faire face à des situations plus complexes telles que la construction d'un filtre.
Dans ce cas, contrairement à l'exemple précédent, le nombre de pièces facultatives sera multiple. Pour un tableau de livres, il peut être nécessaire de filtrer en fonction de la catégorie à laquelle appartient le livre, nom de l'auteur, fourchette de prix, date de publication, etc.
D'après mon expérience (courte), utiliser ce n'est pas possible, et ce n'est pas parce qu'il s'agit d'une limitation de salle, mais, comme le dit implicitement @CommonsWare, une limitation de SQLite. Vous avez besoin de deux requêtes et donc de deux méthodes dans votre DAO.
Je voudrais avoir quelque chose comme:
@Query("SELECT * FROM playlist " +
"WHERE playlist_title LIKE '% :playlistTitle %' " +
"GROUP BY playlist_title " +
"ORDER BY playlist_title " +
"LIMIT :limit")
List<IPlaylist> searchPlaylists(String playlistTitle, int limit);
@Query("SELECT * FROM playlist " +
"WHERE playlist_title LIKE '% :playlistTitle %' " +
"GROUP BY playlist_title " +
"ORDER BY playlist_title ")
List<IPlaylist> searchPlaylists(String playlistTitle);
Ensuite, ailleurs, vous faites le contournement:
if (limit.isPresent()) {
return playlistDao.searchPlaylists(title, limit.get());
} else {
return playlistDao.searchPlaylists(title);
}
C'est la meilleure option que je puisse penser pour le moment.
Au lieu d'écrire plusieurs requêtes, je me réfère à passer la valeur négative à la clause limit. Parce que s'il y a un changement dans la requête, je dois mettre à jour la requête qui est plus sujette aux erreurs.
Document officiel -> Si l'expression LIMIT est évaluée à une valeur négative, le nombre de lignes renvoyées n'est pas supérieur. vous pouvez le trouver ici https://sqlite.org/lang_select.html et lisez la section clause limit.
Donc je ferais quelque chose comme ça,
@Query("SELECT * FROM playlist " +
"WHERE playlist_title LIKE '% :playlistTitle %' " +
"GROUP BY playlist_title " +
"ORDER BY playlist_title " +
"LIMIT :limit")
List<IPlaylist> searchPlaylists(String playlistTitle, int limit);
et passez négatif lorsque vous ne voulez pas appliquer de filtre.
return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)
Cela fonctionne dans mon cas.
Mis à jour le [21 déc 2018]
Si vous utilisez kotlin, utilisez la valeur par défaut.
@JvmOverloads
@Query("SELECT * FROM playlist " +
"WHERE playlist_title LIKE '% :playlistTitle %' " +
"GROUP BY playlist_title " +
"ORDER BY playlist_title " +
"LIMIT :limit")
fun searchPlaylists(playlistTitle: String, limit: Int = -1): List<IPlaylist>
@JvmOverloads
pour le rendre compatible avec Java. Il génère deux méthodes distinctes pour Java.
Il n'y a pas de paramètre similaire à Room dans Room, mais il existe une annotation @RawQuery dans laquelle vous pouvez transmettre une requête sous forme de chaîne afin de pouvoir générer votre requête SQL lors de l'exécution. Je pense que cela fonctionnera pour vous.
Voici l'exemple de la documentation Offical:
@Dao
interface RawDao {
@RawQuery
User getUser(String query);
}
Et voici comment vous pouvez l'utiliser:
User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");
Important: Les méthodes RawQuery doivent renvoyer un type non vide
Important: Ceci est disponible dans la salle 1.1.0-alpha3
Room prend en charge @RawQuery
annotation pour construire des requêtes au moment de l'exécution.
Marquez la méthode DAO avec l'annotation @RawQuery
au lieu de @RawQuery
normal.
@Dao
interface BooksDao{
@RawQuery
List<Book> getBooks(SupportSQLiteQuery query);
}
Room utilise des instructions préparées pour la sécurité et la vérification du temps de compilation. Par conséquent, lors de la construction des requêtes, nous devons stocker la chaîne de requête et les paramètres de liaison séparément.
Dans cet exemple, j'utilise la variable queryString
pour la chaîne de requête et args
pour les paramètres de liaison.
(Veuillez noter que j'ai utilisé un éditeur de texte pour écrire du code. Par conséquent, il peut y avoir des erreurs de frappe ou de syntaxe. Si vous trouvez quelque chose, merci de me le signaler dans les commentaires ou de modifier le message.)
// Query string
String queryString = new String();
// List of bind parameters
List<Object> args = new ArrayList();
boolean containsCondition = false;
// Beginning of query string
queryString += "SELECT * FROM BOOKS";
// Optional parts are added to query string and to args upon here
if(!authorName.isEmpty()){
queryString += " WHERE";
queryString += " author_name LIKE ?%";
args.add(authorName);
containsCondition = true;
}
if(fromDate!=null){
if (containsCondition) {
queryString += " AND";
} else {
queryString += " WHERE";
containsCondition = true;
}
queryString += " publication_date AFTER ?";
args.add(fromDate.getTime());
}
if(toDate!=null){
if (containsCondition) {
queryString += " AND";
} else {
queryString += " WHERE";
containsCondition = true;
}
queryString += " publication_date BEFORE ?";
args.add(toDate.getTime());
}
// End of query string
queryString += ";";
SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
List<Book> result = booksDao.getBooks(query);
Query
, RawQuery
prend en charge le renvoi de curseurs, entités, POJO et POJO bruts avec des champs incorporésRawQuery
prend en charge les relationsUtilisez SupportSQLiteQuery.
https://developer.Android.com/reference/Android/Arch/persistence/db/SupportSQLiteQuery
La dernière version 1.1.1 utilise maintenant SupportSQLiteQuery.
Une requête avec des liaisons typées. Il est préférable d’utiliser cette API au lieu de rawQuery (String, String []) car il autorise le type de liaison safe paramètres.
@Dao
interface RawDao {
@RawQuery(observedEntities = User.class)
LiveData<List<User>> getUsers(SupportSQLiteQuery query);
}
Usage:
LiveData<List<User>> liveUsers = rawDao.getUsers( new
SimpleSQLiteQuery("SELECT * FROM User ORDER BY name DESC"));
Mettez à jour votre note à 1.1.1
implementation 'Android.Arch.persistence.room:runtime:1.1.1'
implementation 'Android.Arch.lifecycle:extensions:1.1.1'
annotationProcessor "Android.Arch.persistence.room:compiler:1.1.1"
Remarque: si vous effectuez une mise à niveau vers la version 1.1.1 et utilisez String au lieu de SupportSQLiteQuery,
vous obtiendrez l'erreur:
RawQuery n'autorise plus le passage d'une chaîne. Veuillez utiliser Android.Arch.persistence.db.SupportSQLiteQuery.
Utiliser SupportSQLiteQuery comme ci-dessus résoudra le problème.
Remarque: Assurez-vous de bien transmettre le paramètre de requête SupportSQLiteQuery ou vous obtiendrez cette erreur:
Les méthodes RawQuery doivent avoir 1 et 1 seul paramètre de type String ou SupportSQLiteQuery
make it more simple.i will show you example using where clause using two variable.Do
like this
@Query("SELECT * FROM Student WHERE stdName1= :myname AND stdId1=:myid")
List<Student> fetchAllData(String myname,int myid);
stdName1 et stdId1 sont des noms de colonnes