Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Android Room how can I create and call a custom query

I've set up a room database with 3 columns (title, descriptions, genre). I want to query the genre column with a user-specified genre(comedy, horror, etc) and return the results.

DAO Interface

I want the Query to only retrieve the entries where the genre matches the genre selected by the user.

@Dao
public interface MovieDAO {
    @Query SELECT * FROM movie_table WHERE genre")
    pubic LiveData<List<Movie>> getAllMovies();
}

Repository Class

In the Repository.class, can I pass the genre String selected by the user to the Query this way?

public class MovieRepository {
    private MovieDao movieDao;
    private LiveData<List<Movie>> allMovies;

    public MovieRepository(Application application) {
        MovieDatabase database = MovieDatabase.getInstance(application);
        movieDao = database.MovieDao();
        allMovies = movieDao.getAllMovies
    }

    public void findMoviesByGenre(String genre) {
        movieDao.findMoviesByGenre(genre);
    }
}

ViewModel class

I'm not sure if I'm missing something in the findMovieByGenre() method

public class MovieViewModel exteneds AndroidViewModel {
    private MovieRepository repository;
    private LiveData<List<Movie>> allMovies

    // Constructor, 
    public MovieViewModel(@NonNull Application application) {
        super(application);
        repository = new MovieRepository(Application)
        allMovies = repository.getAllMovies();
    }

    **public void findMovieByGenre(String genre) {
        repository.findMoviesByGenre(genre);
    }**
}

Activity

This is the part I'm really struggling with, how does the activity call the ViewModel and pass in the genre string parameter? I've tried the approach below but the observe returns the following error.

Cannot resolve method 'observe(com.example.roomexample.MainActivity, anonymous android.arch.lifecycle.Observer>)'

If I remove the genre string in from of the observe, I get the error below.

findMovieByGenre(String)in MovieViewModel cannot be applied to () 


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    movieViewModel = ViewModelProviders.of(this). get(MovieViewModel.class);
    movieViewModel.findMovieByGenre("comedy").observe(this, new Observer<List<Movie>>() {
        @Override
        public void onChanged(@Nullable final List<Movie> movies) {

            Log.d("Movie", movies.get(num).getTitle());
            Log.d("Movie", movies.get(num).getDescription());
            Log.d("Movie", movies.get(num).getGenre());                
        }
    });
}

In short I want to match the genre selected by the user and match it to the genre entry in the database and return the matching results.

My code is based on the following tutorials. If you have any additional material that code help me in my quest please pass it along.

  • Google coding Labs
  • Coding in Flow

Here is a link to my code as it currently stands. https://github.com/Shawn-Nichol/RoomExample

like image 851
Shawn Avatar asked Apr 03 '19 05:04

Shawn


People also ask

How do I query the userids array in room?

@Query ("SELECT * FROM user WHERE uid IN (:userIds)") public abstract List findByIds (int [] userIds); For the example above, if the userIds is an array of 3 elements, Room will run the query as: SELECT * FROM user WHERE uid IN (?, ?, ?) and bind each item in the userIds array into the statement.

How does room generate the return type of a query result?

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 java object.

How to implement room database in Android Studio?

Now, let’s move towards the implementation of Room Database in Android. To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language. Navigate to the app > Gradle Scripts > build.gradle file and add the below dependencies in the dependencies section.

What are the one-shot queries in room?

The Room library includes integrations with several different frameworks to provide asynchronous query execution. One-shot write queries that insert, update, or delete data in the database. One-shot read queries that read data from your database only once and return a result with the snapshot of the database at that time.


1 Answers

If you are using MVVM architecture with LiveData follow this method.

1. Observe the LiveData List in MoviesActivity.java

final LiveData<List<MoviesData>> viewModelData = moviesViewModel.getMoviesByGenre("comedy");
    viewModelData.observe(this, new Observer<List<MoviesData>>() {
        @Override
        public void onChanged(List<MoviesData> moviesData) {
            //Handle the Movies List here.
        }
    });

2. In MoviesViewModel.java

public LiveData<List<NotificationData>> getMoviesByGenre(String genere) {
    MoviesRepository mRepository = new MoviesRepository(application);
    LiveData<List<MoviesData>> mMoviesData = mRepository.getMoviesByGenre(genere);
    return mMoviesData;
}

3. MoviesRepository.java

private MoviesDao mMoviesDao;

//Initialize.
AppDatabase db = AppDatabase.getAppDatabase(application);
mMoviesDao = db.moviesDao();



public LiveData<List<MoviesData>> getMoviesByGenre(String genere) {
    mMovies = mMoviesDao.findMovieByGenre(genere);
    return mMovies;
}

3. In MoviesDao

@Query("SELECT * FROM movie_table ORDER BY genre")
public LiveData<List<Movies> findMovieByGenre(String genre);

So you can Observe query result in your Activity class' Observe method.

like image 115
deepak raj Avatar answered Oct 15 '22 11:10

deepak raj