How to dynamically query the room database at runtime?












17















The problem



Is it possible construct a query at runtime?






Use case



@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);


The limit part is optional. That is, it should be able to perform the same query with or without limit.






A more complicated use case



In the previous case, it is possible to make two static queries with and without limit part and appropriate one can be used each time. But sometimes we may have to deal with more complex situations like building a filter.



In that case, unlike the previous example, there will be multiple number of optional parts. For a table of books, we may need to do filtering according to the category the book belongs to, author name, price range, publication date etc. It is almost impossible to make static queries with all combinations of these parts.










share|improve this question

























  • What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

    – CommonsWare
    May 31 '17 at 14:34













  • @CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

    – Anderson K
    May 31 '17 at 14:37






  • 1





    OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

    – CommonsWare
    May 31 '17 at 14:38








  • 1





    I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

    – Anderson K
    May 31 '17 at 14:45
















17















The problem



Is it possible construct a query at runtime?






Use case



@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);


The limit part is optional. That is, it should be able to perform the same query with or without limit.






A more complicated use case



In the previous case, it is possible to make two static queries with and without limit part and appropriate one can be used each time. But sometimes we may have to deal with more complex situations like building a filter.



In that case, unlike the previous example, there will be multiple number of optional parts. For a table of books, we may need to do filtering according to the category the book belongs to, author name, price range, publication date etc. It is almost impossible to make static queries with all combinations of these parts.










share|improve this question

























  • What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

    – CommonsWare
    May 31 '17 at 14:34













  • @CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

    – Anderson K
    May 31 '17 at 14:37






  • 1





    OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

    – CommonsWare
    May 31 '17 at 14:38








  • 1





    I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

    – Anderson K
    May 31 '17 at 14:45














17












17








17


4






The problem



Is it possible construct a query at runtime?






Use case



@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);


The limit part is optional. That is, it should be able to perform the same query with or without limit.






A more complicated use case



In the previous case, it is possible to make two static queries with and without limit part and appropriate one can be used each time. But sometimes we may have to deal with more complex situations like building a filter.



In that case, unlike the previous example, there will be multiple number of optional parts. For a table of books, we may need to do filtering according to the category the book belongs to, author name, price range, publication date etc. It is almost impossible to make static queries with all combinations of these parts.










share|improve this question
















The problem



Is it possible construct a query at runtime?






Use case



@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);


The limit part is optional. That is, it should be able to perform the same query with or without limit.






A more complicated use case



In the previous case, it is possible to make two static queries with and without limit part and appropriate one can be used each time. But sometimes we may have to deal with more complex situations like building a filter.



In that case, unlike the previous example, there will be multiple number of optional parts. For a table of books, we may need to do filtering according to the category the book belongs to, author name, price range, publication date etc. It is almost impossible to make static queries with all combinations of these parts.







android android-room






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 18 '18 at 16:22









Anees

4,39841045




4,39841045










asked May 31 '17 at 14:27









Anderson KAnderson K

3,69042042




3,69042042













  • What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

    – CommonsWare
    May 31 '17 at 14:34













  • @CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

    – Anderson K
    May 31 '17 at 14:37






  • 1





    OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

    – CommonsWare
    May 31 '17 at 14:38








  • 1





    I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

    – Anderson K
    May 31 '17 at 14:45



















  • What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

    – CommonsWare
    May 31 '17 at 14:34













  • @CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

    – Anderson K
    May 31 '17 at 14:37






  • 1





    OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

    – CommonsWare
    May 31 '17 at 14:38








  • 1





    I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

    – Anderson K
    May 31 '17 at 14:45

















What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

– CommonsWare
May 31 '17 at 14:34







What do you mean by "optional parameter"? Ignoring Room for the moment, how would you implement an optional parameter using traditional Android SQLite APIs?

– CommonsWare
May 31 '17 at 14:34















@CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

– Anderson K
May 31 '17 at 14:37





@CommonsWare I mean that i would like dynamically, set or not the limit parameter for the query.

– Anderson K
May 31 '17 at 14:37




1




1





OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

– CommonsWare
May 31 '17 at 14:38







OK. Ignoring Room for the moment, how would you implement this using SQLiteDatabase? If the answer is "I would have two different query strings", then why not use two different @Query annotations? Since an annotation can refer to a static field (AFAIK), in principle, you can even reduce redundancy by defining the core part of the query string once and referring to it from each annotation.

– CommonsWare
May 31 '17 at 14:38






1




1





I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

– Anderson K
May 31 '17 at 14:45





I understand you, I'm doing a refactoring and as the room is very new, I'm trying to see if there is a better way to do this, but otherwise I'll create two methods.

– Anderson K
May 31 '17 at 14:45












7 Answers
7






active

oldest

votes


















15














In my experience (short) using Room that's not possible, and not because of being a Room limitation but, as implicitly commented by @CommonsWare , a limitation on SQLite. You need two queries, and therefore two methods in your DAO.



I would do have something like:



@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);


Then somewhere else you do the bypass:



if (limit.isPresent()) {
return playlistDao.searchPlaylists(title, limit.get());
} else {
return playlistDao.searchPlaylists(title);
}


That 's the best option I can think at the moment.






share|improve this answer
























  • Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

    – Bipin Bharti
    Jun 18 '18 at 10:06











  • When i using this method then "playlistTitle" not used error accured

    – Bipin Bharti
    Jun 18 '18 at 10:07








  • 1





    This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

    – Anees
    Jan 31 at 13:14



















10














Instead of writing multiple query i refer pass negative value to limit clause. Because if there is change in query i have to update the both query which is more error prone.



Official doc -> If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. you can find it here https://sqlite.org/lang_select.html and read the limit clause section.



So I would do somthing like this,



@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);


and pass negative when you don't want to apply filter.



return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)


It's working in my case.



Updated [21 Dec 2018]



In case If you are using kotlin use default value.



@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 to make it compatiable with Java. It generate two separate methods for Java.






share|improve this answer


























  • Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

    – Eugen Pechanec
    Jun 6 '18 at 6:54



















5














There is no something like optional parameter in Room, but there is a @RawQuery annotation where you can pass query as a String so you can build your SQL query in the runtime. I think this will work for you.



Here is the example from the Offical documentation:



@Dao
interface RawDao {
@RawQuery
User getUser(String query);
}


And here is how you can use it:



User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");


Important: RawQuery methods must return a non-void type



Important: This is available in Room 1.1.0-alpha3






share|improve this answer


























  • Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

    – Claude Hangui
    Jun 8 '18 at 9:42











  • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

    – AJW
    Feb 2 at 3:16



















4














Use SupportSQLiteQuery.



https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteQuery



Latest release 1.1.1 now uses SupportSQLiteQuery.




A query with typed bindings. It is better to use this API instead of
rawQuery(String, String) because it allows binding type safe
parameters.




@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"));


Update your gradle to 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"


Note: if you upgrade to 1.1.1, and are using String instead of SupportSQLiteQuery,



you will get the error:




RawQuery does not allow passing a string anymore. Please use
android.arch.persistence.db.SupportSQLiteQuery.




Using SupportSQLiteQuery as above will solve the problem.






share|improve this answer
























  • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

    – AJW
    Feb 2 at 3:16



















4














Room supports @RawQuery annotation to construct queries at run-time.






Step 1 : Make DAO method



Mark the DAO method with @RawQuery annotation instead of normal @RawQuery.



@Dao
interface BooksDao{
@RawQuery
List<Book> getBooks(SupportSQLiteQuery query);
}





Step 2 : Construct the query



Room uses prepared statements for security and compile time verification. Therefore, while constructing queries, we need to store query string and bind parameters separately.



In this example, I use the variable queryString for query string and args for bind parameters.



(Please note that I used text editor to write code. Therefore there may be typo or simple syntax errors. If you find anything please let me know in the comments or edit the post.)



// 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 += ";";





Step 3 : Perform query



SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
List<Book> result = booksDao.getBooks(query);










Notes




  • Like normal Query, RawQuery supports returning raw cursors, entities, POJOs and POJOs with embedded fields


  • RawQuery supports relations






share|improve this answer


























  • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

    – AJW
    Feb 2 at 3:18






  • 1





    No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

    – Anees
    Feb 3 at 19:35



















1














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 and stdId1 are column names






share|improve this answer































    -1














    @Anderson K & @Juanky Soriano,
    I'm agree with @CommonsWare,



    There some Limitation in Room Library, then also We can write fully dynamic query on Room Database by using the @query() of Support SQLite Database



    String mQuery = "SELECT * FROM foobar WHERE columnName1 IN ('value_1','value_2') and columnName2 In('value_3','value_4')";

    AppDatabase appDatabase = Room.databaseBuilder(getApplicationContext(),
    AppDatabase.class, "database-name").build();

    Cursor mCursor = AppDatabase.getAppDatabase(context).getOpenHelper().getReadableDatabase().query(myQuery);


    Now you can convert cursor row wise data to your POJO class.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44287465%2fhow-to-dynamically-query-the-room-database-at-runtime%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      15














      In my experience (short) using Room that's not possible, and not because of being a Room limitation but, as implicitly commented by @CommonsWare , a limitation on SQLite. You need two queries, and therefore two methods in your DAO.



      I would do have something like:



      @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);


      Then somewhere else you do the bypass:



      if (limit.isPresent()) {
      return playlistDao.searchPlaylists(title, limit.get());
      } else {
      return playlistDao.searchPlaylists(title);
      }


      That 's the best option I can think at the moment.






      share|improve this answer
























      • Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

        – Bipin Bharti
        Jun 18 '18 at 10:06











      • When i using this method then "playlistTitle" not used error accured

        – Bipin Bharti
        Jun 18 '18 at 10:07








      • 1





        This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

        – Anees
        Jan 31 at 13:14
















      15














      In my experience (short) using Room that's not possible, and not because of being a Room limitation but, as implicitly commented by @CommonsWare , a limitation on SQLite. You need two queries, and therefore two methods in your DAO.



      I would do have something like:



      @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);


      Then somewhere else you do the bypass:



      if (limit.isPresent()) {
      return playlistDao.searchPlaylists(title, limit.get());
      } else {
      return playlistDao.searchPlaylists(title);
      }


      That 's the best option I can think at the moment.






      share|improve this answer
























      • Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

        – Bipin Bharti
        Jun 18 '18 at 10:06











      • When i using this method then "playlistTitle" not used error accured

        – Bipin Bharti
        Jun 18 '18 at 10:07








      • 1





        This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

        – Anees
        Jan 31 at 13:14














      15












      15








      15







      In my experience (short) using Room that's not possible, and not because of being a Room limitation but, as implicitly commented by @CommonsWare , a limitation on SQLite. You need two queries, and therefore two methods in your DAO.



      I would do have something like:



      @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);


      Then somewhere else you do the bypass:



      if (limit.isPresent()) {
      return playlistDao.searchPlaylists(title, limit.get());
      } else {
      return playlistDao.searchPlaylists(title);
      }


      That 's the best option I can think at the moment.






      share|improve this answer













      In my experience (short) using Room that's not possible, and not because of being a Room limitation but, as implicitly commented by @CommonsWare , a limitation on SQLite. You need two queries, and therefore two methods in your DAO.



      I would do have something like:



      @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);


      Then somewhere else you do the bypass:



      if (limit.isPresent()) {
      return playlistDao.searchPlaylists(title, limit.get());
      } else {
      return playlistDao.searchPlaylists(title);
      }


      That 's the best option I can think at the moment.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered May 31 '17 at 15:04









      Juanky SorianoJuanky Soriano

      18213




      18213













      • Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

        – Bipin Bharti
        Jun 18 '18 at 10:06











      • When i using this method then "playlistTitle" not used error accured

        – Bipin Bharti
        Jun 18 '18 at 10:07








      • 1





        This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

        – Anees
        Jan 31 at 13:14



















      • Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

        – Bipin Bharti
        Jun 18 '18 at 10:06











      • When i using this method then "playlistTitle" not used error accured

        – Bipin Bharti
        Jun 18 '18 at 10:07








      • 1





        This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

        – Anees
        Jan 31 at 13:14

















      Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

      – Bipin Bharti
      Jun 18 '18 at 10:06





      Hello, it's not working in my case. Particular this line "WHERE playlist_title LIKE '% :playlistTitle %' "

      – Bipin Bharti
      Jun 18 '18 at 10:06













      When i using this method then "playlistTitle" not used error accured

      – Bipin Bharti
      Jun 18 '18 at 10:07







      When i using this method then "playlistTitle" not used error accured

      – Bipin Bharti
      Jun 18 '18 at 10:07






      1




      1





      This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

      – Anees
      Jan 31 at 13:14





      This was a great answer. But it is outdated since Room introduced @RawQuery annotation.

      – Anees
      Jan 31 at 13:14













      10














      Instead of writing multiple query i refer pass negative value to limit clause. Because if there is change in query i have to update the both query which is more error prone.



      Official doc -> If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. you can find it here https://sqlite.org/lang_select.html and read the limit clause section.



      So I would do somthing like this,



      @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);


      and pass negative when you don't want to apply filter.



      return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)


      It's working in my case.



      Updated [21 Dec 2018]



      In case If you are using kotlin use default value.



      @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 to make it compatiable with Java. It generate two separate methods for Java.






      share|improve this answer


























      • Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

        – Eugen Pechanec
        Jun 6 '18 at 6:54
















      10














      Instead of writing multiple query i refer pass negative value to limit clause. Because if there is change in query i have to update the both query which is more error prone.



      Official doc -> If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. you can find it here https://sqlite.org/lang_select.html and read the limit clause section.



      So I would do somthing like this,



      @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);


      and pass negative when you don't want to apply filter.



      return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)


      It's working in my case.



      Updated [21 Dec 2018]



      In case If you are using kotlin use default value.



      @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 to make it compatiable with Java. It generate two separate methods for Java.






      share|improve this answer


























      • Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

        – Eugen Pechanec
        Jun 6 '18 at 6:54














      10












      10








      10







      Instead of writing multiple query i refer pass negative value to limit clause. Because if there is change in query i have to update the both query which is more error prone.



      Official doc -> If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. you can find it here https://sqlite.org/lang_select.html and read the limit clause section.



      So I would do somthing like this,



      @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);


      and pass negative when you don't want to apply filter.



      return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)


      It's working in my case.



      Updated [21 Dec 2018]



      In case If you are using kotlin use default value.



      @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 to make it compatiable with Java. It generate two separate methods for Java.






      share|improve this answer















      Instead of writing multiple query i refer pass negative value to limit clause. Because if there is change in query i have to update the both query which is more error prone.



      Official doc -> If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. you can find it here https://sqlite.org/lang_select.html and read the limit clause section.



      So I would do somthing like this,



      @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);


      and pass negative when you don't want to apply filter.



      return playlistDao.searchPlaylists(title, limit.isPresent() ? limit.get() : -1)


      It's working in my case.



      Updated [21 Dec 2018]



      In case If you are using kotlin use default value.



      @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 to make it compatiable with Java. It generate two separate methods for Java.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 21 '18 at 5:52

























      answered Jun 1 '17 at 5:07









      MoinkhanMoinkhan

      9,52232955




      9,52232955













      • Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

        – Eugen Pechanec
        Jun 6 '18 at 6:54



















      • Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

        – Eugen Pechanec
        Jun 6 '18 at 6:54

















      Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

      – Eugen Pechanec
      Jun 6 '18 at 6:54





      Or make the Dao an abstract class and delegate the second method to the first with limit parameter set to -1.

      – Eugen Pechanec
      Jun 6 '18 at 6:54











      5














      There is no something like optional parameter in Room, but there is a @RawQuery annotation where you can pass query as a String so you can build your SQL query in the runtime. I think this will work for you.



      Here is the example from the Offical documentation:



      @Dao
      interface RawDao {
      @RawQuery
      User getUser(String query);
      }


      And here is how you can use it:



      User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");


      Important: RawQuery methods must return a non-void type



      Important: This is available in Room 1.1.0-alpha3






      share|improve this answer


























      • Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

        – Claude Hangui
        Jun 8 '18 at 9:42











      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16
















      5














      There is no something like optional parameter in Room, but there is a @RawQuery annotation where you can pass query as a String so you can build your SQL query in the runtime. I think this will work for you.



      Here is the example from the Offical documentation:



      @Dao
      interface RawDao {
      @RawQuery
      User getUser(String query);
      }


      And here is how you can use it:



      User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");


      Important: RawQuery methods must return a non-void type



      Important: This is available in Room 1.1.0-alpha3






      share|improve this answer


























      • Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

        – Claude Hangui
        Jun 8 '18 at 9:42











      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16














      5












      5








      5







      There is no something like optional parameter in Room, but there is a @RawQuery annotation where you can pass query as a String so you can build your SQL query in the runtime. I think this will work for you.



      Here is the example from the Offical documentation:



      @Dao
      interface RawDao {
      @RawQuery
      User getUser(String query);
      }


      And here is how you can use it:



      User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");


      Important: RawQuery methods must return a non-void type



      Important: This is available in Room 1.1.0-alpha3






      share|improve this answer















      There is no something like optional parameter in Room, but there is a @RawQuery annotation where you can pass query as a String so you can build your SQL query in the runtime. I think this will work for you.



      Here is the example from the Offical documentation:



      @Dao
      interface RawDao {
      @RawQuery
      User getUser(String query);
      }


      And here is how you can use it:



      User user = rawDao.getUser("SELECT * FROM User WHERE id = 3 LIMIT 1");


      Important: RawQuery methods must return a non-void type



      Important: This is available in Room 1.1.0-alpha3







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 18 '18 at 21:29

























      answered Mar 18 '18 at 20:45









      Mladen RakonjacMladen Rakonjac

      4,61342135




      4,61342135













      • Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

        – Claude Hangui
        Jun 8 '18 at 9:42











      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16



















      • Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

        – Claude Hangui
        Jun 8 '18 at 9:42











      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16

















      Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

      – Claude Hangui
      Jun 8 '18 at 9:42





      Yeah..but the thing is it's only valid for read queries. How do you go about with write queries ?

      – Claude Hangui
      Jun 8 '18 at 9:42













      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:16





      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:16











      4














      Use SupportSQLiteQuery.



      https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteQuery



      Latest release 1.1.1 now uses SupportSQLiteQuery.




      A query with typed bindings. It is better to use this API instead of
      rawQuery(String, String) because it allows binding type safe
      parameters.




      @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"));


      Update your gradle to 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"


      Note: if you upgrade to 1.1.1, and are using String instead of SupportSQLiteQuery,



      you will get the error:




      RawQuery does not allow passing a string anymore. Please use
      android.arch.persistence.db.SupportSQLiteQuery.




      Using SupportSQLiteQuery as above will solve the problem.






      share|improve this answer
























      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16
















      4














      Use SupportSQLiteQuery.



      https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteQuery



      Latest release 1.1.1 now uses SupportSQLiteQuery.




      A query with typed bindings. It is better to use this API instead of
      rawQuery(String, String) because it allows binding type safe
      parameters.




      @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"));


      Update your gradle to 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"


      Note: if you upgrade to 1.1.1, and are using String instead of SupportSQLiteQuery,



      you will get the error:




      RawQuery does not allow passing a string anymore. Please use
      android.arch.persistence.db.SupportSQLiteQuery.




      Using SupportSQLiteQuery as above will solve the problem.






      share|improve this answer
























      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16














      4












      4








      4







      Use SupportSQLiteQuery.



      https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteQuery



      Latest release 1.1.1 now uses SupportSQLiteQuery.




      A query with typed bindings. It is better to use this API instead of
      rawQuery(String, String) because it allows binding type safe
      parameters.




      @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"));


      Update your gradle to 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"


      Note: if you upgrade to 1.1.1, and are using String instead of SupportSQLiteQuery,



      you will get the error:




      RawQuery does not allow passing a string anymore. Please use
      android.arch.persistence.db.SupportSQLiteQuery.




      Using SupportSQLiteQuery as above will solve the problem.






      share|improve this answer













      Use SupportSQLiteQuery.



      https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteQuery



      Latest release 1.1.1 now uses SupportSQLiteQuery.




      A query with typed bindings. It is better to use this API instead of
      rawQuery(String, String) because it allows binding type safe
      parameters.




      @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"));


      Update your gradle to 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"


      Note: if you upgrade to 1.1.1, and are using String instead of SupportSQLiteQuery,



      you will get the error:




      RawQuery does not allow passing a string anymore. Please use
      android.arch.persistence.db.SupportSQLiteQuery.




      Using SupportSQLiteQuery as above will solve the problem.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 2 '18 at 2:48









      live-lovelive-love

      16.8k108575




      16.8k108575













      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16



















      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:16

















      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:16





      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:16











      4














      Room supports @RawQuery annotation to construct queries at run-time.






      Step 1 : Make DAO method



      Mark the DAO method with @RawQuery annotation instead of normal @RawQuery.



      @Dao
      interface BooksDao{
      @RawQuery
      List<Book> getBooks(SupportSQLiteQuery query);
      }





      Step 2 : Construct the query



      Room uses prepared statements for security and compile time verification. Therefore, while constructing queries, we need to store query string and bind parameters separately.



      In this example, I use the variable queryString for query string and args for bind parameters.



      (Please note that I used text editor to write code. Therefore there may be typo or simple syntax errors. If you find anything please let me know in the comments or edit the post.)



      // 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 += ";";





      Step 3 : Perform query



      SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
      List<Book> result = booksDao.getBooks(query);










      Notes




      • Like normal Query, RawQuery supports returning raw cursors, entities, POJOs and POJOs with embedded fields


      • RawQuery supports relations






      share|improve this answer


























      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:18






      • 1





        No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

        – Anees
        Feb 3 at 19:35
















      4














      Room supports @RawQuery annotation to construct queries at run-time.






      Step 1 : Make DAO method



      Mark the DAO method with @RawQuery annotation instead of normal @RawQuery.



      @Dao
      interface BooksDao{
      @RawQuery
      List<Book> getBooks(SupportSQLiteQuery query);
      }





      Step 2 : Construct the query



      Room uses prepared statements for security and compile time verification. Therefore, while constructing queries, we need to store query string and bind parameters separately.



      In this example, I use the variable queryString for query string and args for bind parameters.



      (Please note that I used text editor to write code. Therefore there may be typo or simple syntax errors. If you find anything please let me know in the comments or edit the post.)



      // 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 += ";";





      Step 3 : Perform query



      SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
      List<Book> result = booksDao.getBooks(query);










      Notes




      • Like normal Query, RawQuery supports returning raw cursors, entities, POJOs and POJOs with embedded fields


      • RawQuery supports relations






      share|improve this answer


























      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:18






      • 1





        No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

        – Anees
        Feb 3 at 19:35














      4












      4








      4







      Room supports @RawQuery annotation to construct queries at run-time.






      Step 1 : Make DAO method



      Mark the DAO method with @RawQuery annotation instead of normal @RawQuery.



      @Dao
      interface BooksDao{
      @RawQuery
      List<Book> getBooks(SupportSQLiteQuery query);
      }





      Step 2 : Construct the query



      Room uses prepared statements for security and compile time verification. Therefore, while constructing queries, we need to store query string and bind parameters separately.



      In this example, I use the variable queryString for query string and args for bind parameters.



      (Please note that I used text editor to write code. Therefore there may be typo or simple syntax errors. If you find anything please let me know in the comments or edit the post.)



      // 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 += ";";





      Step 3 : Perform query



      SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
      List<Book> result = booksDao.getBooks(query);










      Notes




      • Like normal Query, RawQuery supports returning raw cursors, entities, POJOs and POJOs with embedded fields


      • RawQuery supports relations






      share|improve this answer















      Room supports @RawQuery annotation to construct queries at run-time.






      Step 1 : Make DAO method



      Mark the DAO method with @RawQuery annotation instead of normal @RawQuery.



      @Dao
      interface BooksDao{
      @RawQuery
      List<Book> getBooks(SupportSQLiteQuery query);
      }





      Step 2 : Construct the query



      Room uses prepared statements for security and compile time verification. Therefore, while constructing queries, we need to store query string and bind parameters separately.



      In this example, I use the variable queryString for query string and args for bind parameters.



      (Please note that I used text editor to write code. Therefore there may be typo or simple syntax errors. If you find anything please let me know in the comments or edit the post.)



      // 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 += ";";





      Step 3 : Perform query



      SimpleSQLiteQuery query = new SimpleSQLiteQuery(queryString, args.toArray());
      List<Book> result = booksDao.getBooks(query);










      Notes




      • Like normal Query, RawQuery supports returning raw cursors, entities, POJOs and POJOs with embedded fields


      • RawQuery supports relations







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 31 at 14:23

























      answered Aug 18 '18 at 17:47









      AneesAnees

      4,39841045




      4,39841045













      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:18






      • 1





        No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

        – Anees
        Feb 3 at 19:35



















      • Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

        – AJW
        Feb 2 at 3:18






      • 1





        No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

        – Anees
        Feb 3 at 19:35

















      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:18





      Is @RawQuery subject to risk of SQL injection attack and therefore a security risk?

      – AJW
      Feb 2 at 3:18




      1




      1





      No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

      – Anees
      Feb 3 at 19:35





      No. It is not plain text query as the name make us think. It uses bind variables internally. SimpleSQLiteQuery, to be more precise.

      – Anees
      Feb 3 at 19:35











      1














      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 and stdId1 are column names






      share|improve this answer




























        1














        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 and stdId1 are column names






        share|improve this answer


























          1












          1








          1







          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 and stdId1 are column names






          share|improve this answer













          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 and stdId1 are column names







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 31 '18 at 14:42









          Syed Danish HaiderSyed Danish Haider

          449311




          449311























              -1














              @Anderson K & @Juanky Soriano,
              I'm agree with @CommonsWare,



              There some Limitation in Room Library, then also We can write fully dynamic query on Room Database by using the @query() of Support SQLite Database



              String mQuery = "SELECT * FROM foobar WHERE columnName1 IN ('value_1','value_2') and columnName2 In('value_3','value_4')";

              AppDatabase appDatabase = Room.databaseBuilder(getApplicationContext(),
              AppDatabase.class, "database-name").build();

              Cursor mCursor = AppDatabase.getAppDatabase(context).getOpenHelper().getReadableDatabase().query(myQuery);


              Now you can convert cursor row wise data to your POJO class.






              share|improve this answer




























                -1














                @Anderson K & @Juanky Soriano,
                I'm agree with @CommonsWare,



                There some Limitation in Room Library, then also We can write fully dynamic query on Room Database by using the @query() of Support SQLite Database



                String mQuery = "SELECT * FROM foobar WHERE columnName1 IN ('value_1','value_2') and columnName2 In('value_3','value_4')";

                AppDatabase appDatabase = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "database-name").build();

                Cursor mCursor = AppDatabase.getAppDatabase(context).getOpenHelper().getReadableDatabase().query(myQuery);


                Now you can convert cursor row wise data to your POJO class.






                share|improve this answer


























                  -1












                  -1








                  -1







                  @Anderson K & @Juanky Soriano,
                  I'm agree with @CommonsWare,



                  There some Limitation in Room Library, then also We can write fully dynamic query on Room Database by using the @query() of Support SQLite Database



                  String mQuery = "SELECT * FROM foobar WHERE columnName1 IN ('value_1','value_2') and columnName2 In('value_3','value_4')";

                  AppDatabase appDatabase = Room.databaseBuilder(getApplicationContext(),
                  AppDatabase.class, "database-name").build();

                  Cursor mCursor = AppDatabase.getAppDatabase(context).getOpenHelper().getReadableDatabase().query(myQuery);


                  Now you can convert cursor row wise data to your POJO class.






                  share|improve this answer













                  @Anderson K & @Juanky Soriano,
                  I'm agree with @CommonsWare,



                  There some Limitation in Room Library, then also We can write fully dynamic query on Room Database by using the @query() of Support SQLite Database



                  String mQuery = "SELECT * FROM foobar WHERE columnName1 IN ('value_1','value_2') and columnName2 In('value_3','value_4')";

                  AppDatabase appDatabase = Room.databaseBuilder(getApplicationContext(),
                  AppDatabase.class, "database-name").build();

                  Cursor mCursor = AppDatabase.getAppDatabase(context).getOpenHelper().getReadableDatabase().query(myQuery);


                  Now you can convert cursor row wise data to your POJO class.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 1 '18 at 9:57









                  TejaDroidTejaDroid

                  3,79421928




                  3,79421928






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44287465%2fhow-to-dynamically-query-the-room-database-at-runtime%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas