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

2

7

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

Karyotin answered 3/4, 2019 at 5:42 Comment(2)
can you please give some more detail about your question or give exampleMisprint
I've included a link to the GitHub if you wish to see all the code I have in detail.Karyotin
S
7

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.

Shellacking answered 3/4, 2019 at 7:22 Comment(3)
deepak raj, I think your example provides a potential starting block for me but it doesn't pass the Genre parameter from the MovieActivity.Karyotin
@Karyotin I have edited the answer with the genere parameter. Check now. Just use this code only as a reference. This is not exactly as the same as your code. Understand the logic.Shellacking
@deepakraj, you don't seem to be using the genre parameter in the query. You'll need the query to be "SELECT * FROM movie_table WHERE genre = :genre"Dimmer
K
-1

To access your app's data using the Room persistence library, you work with data access objects, or DAOs. You may have to use DAO in android room.

By accessing a database using a DAO class instead of query builders or direct queries, you can separate different components of your database architecture

@Dao
public interface MyDao {
    @Query("SELECT * FROM movie_table ORDER BY genre")
    public ListMovies[] findMovieByGenre(String Genre);

}
Klina answered 3/4, 2019 at 6:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.