Search code examples
androidsqlmvvmviewmodelandroid-room

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.

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


Solution

  • 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.