SQLite
 sql >> Baza danych >  >> RDS >> SQLite

jak pobrać pierwszy lub (dowolny) element z listy LiveData w architekturze Android MVVM?

jak pobrać pierwszy lub (dowolny) element z listy LiveData w architekturze AndroidMVVM

Jeśli chcesz pobrać konkretny element z listy LiveData, musisz ograniczyć zapytanie za pomocą przesunięcia.

Domyślnie ograniczenie zapytania nie uwzględnia przesunięcia do niego; więc domyślna wartość przesunięcia to 0.

Na przykład w swoim Dao :

Poniższe zapytania z Przykładu 1 i 2 są równoważne, ponieważ domyślna wartość przesunięcia to 0.

Przykład

@Query("SELECT * FROM students LIMIT  :limit")
LiveData<List<Student>> getStudents(int limit);

// Query
getStudents(1); // returns the first row of the list

Przykład 2

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
LiveData<List<Student>> getStudents(int limit, int offset);

// Query
getStudents(1, 0); // returns the first row of the list

Uwaga: Tutaj zakładam, że twoja klasa modelu to Student

Chodzi o pierwszy rząd; ale aby zwrócić numer wiersza x następnie musisz zmienić przesunięcie tak, aby było:x-1 , ponieważ przesunięcie jest wartością od 0

Przykład 3 (to samo zapytanie Dao co w przykładzie 2)

getStudents(1, 1); // returns the second row
getStudents(1, 4); // returns the fifth row

Jeśli chcesz zwrócić więcej niż jeden wiersz, musisz manipulować LIMIT wartość, aby zwrócić x wierszy z wyników, a następnie ogranicz zapytanie za pomocą x .

getStudents(2, 1); // returns the second and third rows
getStudents(3, 4); // returns the fifth, sixth, and seventh rows

Mam nadzieję, że to rozwiąże Twoje pytanie

Edytuj zgodnie z komentarzami

Mam już listę zwróconą przez inne zapytanie @Query("SELECT * FROM students) LiveData<List<Student>> getStudents(); Zwrócona wartość to lista. Chcę uzyskać pierwszy element z listy. Ta odpowiedź zwraca naprawdę pierwszy element, ale muszę przejść wszystkie kroki (aby zdefiniować tę metodę w ViewModel i obserwuj ją w MainActivity w celu pobrania listy lub dowolnego elementu na liście). To, czego potrzebuję, to wpisać pierwszą wartość na liście, gdy bawię się funkcją w klasie repozytorium. –

Teraz używasz poniższego zapytania

@Query("SELECT * FROM students")
LiveData<List<Student>> getStudents();

I chcesz:

  1. Pobierz pierwszy lub dowolny element z listy. i zrobić to zgodnie z tym, co wspomniano powyżej
  2. Przejdź wszystkie kroki (aby zdefiniować tę metodę w ViewModel classi obserwuj to w MainActivity aby uzyskać listę lub dowolny element z listy).

Aby to zrobić:

W Dao: :Zmień zapytanie na

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
LiveData<List<Student>> getAllStudents(int limit, int offset);

W repozytorium:

public class StudentRepository {

    ...

    public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
        return mDAO.getAllStudents(limit, offset);
    }
}

W ViewModelu:

public LiveData<List<Student>> getAllStudents(final int limit, final int offset) {
    return mRepository.getAllStudents(limit, offset);
}

Aktywność:

private void getAllStudents(int limit, int offset) {
    mViewModel.getAllStudents(limit, offset).observe(this, new Observer<List<Student>>() {
        @Override
        public void onChanged(List<Student> students) {
            if (students != null) {
                // Here you can set RecyclerView list with `students` or do whatever you want

            }
        }
    });
}

Aby to przetestować:

getAllStudents(1, 0); // return first row from the table.
getAllStudents(2, 0); // return first 2 rows from the table.
getAllStudents(2, 1); // return 2nd and 3rd rows from the table.
getAllStudents(-1, 5); // remove first 5 rows from the table.

I zwrócić pierwszy element z listy mAllStudents w celu wpisania pierwszego nazwiska ucznia w Log.d

Tak więc w Twojej aktywności

mViewModel.getAllStudents(1, 0).observe(this, new Observer<List<Student>>() {
    @Override
    public void onChanged(List<Student> students) {
        if (students != null) {
            Student student = students.get(0);
            Log.d("First_Name", student.getName());
        }
    }
});

Edytuj czy można zwrócić dowolny element listy bez wykonywania wszystkich kroków, takich jak pisanie funkcji w ViewModeland zauważ, że w MainActivity? Moje pytanie nie dotyczy wszystkich kroków.

Tak, jest to możliwe, ale powyższy model jest rekomendowanym modelem przez Google. Możesz zwrócić List<Student> z Dao zapytanie zamiast LiveData<List<Student>> , ale złe wieści to:

  1. Musisz sobie z tym poradzić w osobnym wątku w tle; ponieważ LiveData zrób to za darmo.
  2. Stracisz wartość LiveData; więc musisz ręcznie odświeżyć listę, aby sprawdzić jakąkolwiek aktualizację, ponieważ nie będziesz mógł użyć wzorca obserwatora.

Możesz więc pominąć za pomocą ViewModel i Repository i wykonaj wszystkie czynności z ćwiczenia w następujący sposób:

private Executor mExecutor = Executors.newSingleThreadExecutor();

public void getAllStudents(final int limit, final int offset) {

    final StudentDAO mDAO = StudentDatabase.getInstance(getApplicationContext()).getStudentDAO();

    mExecutor.execute(new Runnable() {
        @Override
        public void run() {
            List<Student> students = mDAO.getAllStudents(limit, offset);
            Student student = students.get(0);
            Log.d("First_Name", student.getName());
        }
    });
}

// Usage: getAllStudents(1, 0);

I zapytanie o Dao:

@Query("SELECT * FROM students LIMIT  :limit OFFSET :offset")
List<Student> getAllStudents(int limit, int offset);



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak używać _COUNT w BaseColumns?

  2. Jak zmienić wiersz poleceń w SQLite?

  3. 2 sposoby na zwrócenie tylko wartości liczbowych z kolumny bazy danych SQLite

  4. 2 sposoby na wstawienie nowej linii do łańcucha w SQLite

  5. SQLite - Wybierz dane