web-dev-qa-db-fra.com

Comment obtenir le nombre de lignes de la base de données de salle dans Android?

Je suis la pratique d'avoir un référentiel et un Dao et ainsi de suite. J'essayais d'obtenir le nombre de lignes dans mon référentiel de base de données en ayant une fonction

int getNumFiles() {
    List<AFile> lst = files.getValue();  // files is of type LiveData<List<AFile>> files;
    if (lst == null) {
        return 0;
    } else {
        return lst.size();
    }
}

Mais lst est toujours évalué à null. Je suppose que cela a quelque chose à voir avec le fait que je ne suis pas autorisé à interroger la base de données à partir du thread d'interface utilisateur ou quelque chose? Dois-je l'implémenter comme on implémente l'ajout ou la suppression d'un élément? En d'autres termes, avez une fonction dans le Dao qui est appelée via une AsyncTask dans le référentiel de base de données? Je ne sais pas comment faire cette chose très simple.

Il y a this réponse qui montre ce que l'on écrirait dans le Dao pour connaître le nombre de lignes, mais cela n'explique pas comment le référentiel devrait appeler cela.

8
Nimitz14

J'ai fini par le faire comme ça (en utilisant un nouveau thread pour la requête).

Dans le Dao

@Query("SELECT COUNT(id) FROM table WHERE is_checked = 1")
int getCount();

Dans le référentiel

int getNumFiles() {
    return afileDao.getCount();
}

Où j'en ai besoin

    final AtomicInteger fcount = new AtomicInteger();
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            int num = f_repo.getNumFiles();
            fcount.set(num);
        }
    });
    t.setPriority(10);
    t.start();
    t.join();
    // use as fcount.get()
9
Nimitz14

Ligne de comptage de la base de données des pièces

@Query("SELECT COUNT(column_name) FROM tableName")
LiveData<Integer> getRowCount();
14
Shomu

Voyons si cela fonctionne. Je suis peut-être hors de la base, mais j'ai eu du mal avec ce même problème en essayant d'apprendre les bases de données de salle et plus récemment en essayant d'obtenir le nombre de lignes de la table avec laquelle je travaillais.

(Ceci est mon premier message, je m'excuse pour sa brièveté et j'accueille favorablement une pensée constructive pour l'améliorer.)

En commençant par le Dao, j'ai déclaré la méthode avec l'annotation @Query (). C'est le point où nous définirons la requête que nous utiliserons pour récupérer les informations souhaitées.

@Query("SELECT COUNT(*) FROM Word_table")
LiveData<Integer> getCount();

Deuxièmement, effectuez cette opération dans le référentiel. Le référentiel appellera notre classe Dao pour récupérer des informations et essentiellement passer la requête.

public LiveData<Integer> getCount() {
    return mWordDao.getCount();
}

Troisièmement, introduisez-le dans le ViewModel. Le ViewModel sera appelé par la (dans ce cas) MainActivity et à son tour appellera la méthode getCount () à partir du référentiel et redescendra la chaîne.

// count
public LiveData<Integer> getCount() { return mRepository.getCount(); }

Enfin, créez l'observable dans MainActivity, car j'ai encapsulé la valeur avec un wrapper LiveData <>.

    mWordViewModel.getCount().observe(this, new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer integer) {
            Word_count.setText(String.valueOf(integer));
        }
    });

Je sais que c'est simpliste, court et laisse de côté beaucoup de détails, mais après avoir parcouru le code de la base de données de salle un grand nombre de fois, cela a fonctionné pour moi pour pouvoir afficher le nombre de lignes dans la table de base de données à laquelle je faisais référence . Et il semble que ce soit la façon dont les bases de données de Room sont censées fonctionner.

(Le code que j'utilisais comme base de branchement pour récupérer le nombre de lignes a été récupéré dans les laboratoires de base de code fournis par Google pour les bases de données de salle, partie I.)

Vous pouvez les atteindre avec le lien suivant et cliquer sur celui des bases de données de pièces - Partie 1: Codelabs for Android Developers

Scott

4
M S Martens

Je pense qu'une meilleure façon de faire des choses miniatures dans le thread d'arrière-plan est de créer un Handler & HandlerThread et de les utiliser pour effectuer une tâche de ligne.

//The handlers to perform tasks on the background threads
override lateinit var mHandler: Handler
override lateinit var mHandlerThread: HandlerThread

override fun start() {
    //Instantiate the handlerThread
    mHandlerThread = HandlerThread(MainPresenter::class.Java.simpleName)

    //A call to the start method has to be executed manually
    mHandlerThread.start()
    mHandler = Handler(mHandlerThread.looper)
}

Et partout où vous voulez appeler quelque chose dans le fil d'arrière-plan, simplement:

mHandler.post { getTableCountInBg() }

J'étais en train de taper ce à quoi @ Sameer Donga lié, mais référez-le à la place. Appelez-le comme ci-dessus.

P.S. Ignorez les annotations de remplacement. Ils sont là parce que je l'applique à un présentateur.

1
Clinkz