217 votes

Android Room - Obtenir l'identifiant de la nouvelle ligne insérée avec génération automatique

Voici comment j'insère des données dans une base de données en utilisant Room Persistence Library:

Entité:

 @Entity
class User {
    @PrimaryKey(autoGenerate = true)
    public int id;
    //...
}
 

Objet d'accès aux données:

 @Dao
public interface UserDao{
    @Insert(onConflict = IGNORE)
    void insertUser(User user);
    //...
}
 

Est-il possible de renvoyer l'ID d'utilisateur une fois que l'insertion est terminée dans la méthode ci-dessus sans écrire une requête de sélection séparée?

296voto

MatPag Points 12624

Basé sur la documentation ici (ci-dessous l'extrait de code)

Une méthode annotée avec l' @Insert d'annotation peut retourner:

  • long pour la seule opération d'insertion
  • long[] ou Long[] ou List<Long> pour plusieurs opérations d'insertion
  • void si vous n'avez pas de soins sur l'id inséré(s)

40voto

Quang Nguyen Points 1807

@Insert peuvent retourner void , long , long[] ou List<Long> . S'il vous plaît essayez ceci.

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  long insert(User user);

 // Insert multiple items
 @Insert(onConflict = OnConflictStrategy.REPLACE)
  long[] insert(User... user);
 

8voto

Cuong Vo Points 316

La valeur de retour de l'insertion pour un enregistrement sera 1 si votre instruction réussit.

Si vous souhaitez insérer une liste d'objets, vous pouvez utiliser:

 @Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] addAll(List<Object> list);
 

Et exécutez-le avec Rx2:

 Observable.fromCallable(new Callable<Object>() {
        @Override
        public Object call() throws Exception {
            return yourDao.addAll(list<Object>);
        }
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
        @Override
        public void accept(@NonNull Object o) throws Exception {
           // the o will be Long[].size => numbers of inserted records.

        }
    });
 

8voto

Hardian Points 1122

Obtenez l'ID de ligne par le sniplet suivant. Il utilise callable sur un ExecutorService avec Future.

  private UserDao userDao;
 private ExecutorService executorService;

 public long insertUploadStatus(User user) {
    Callable<Long> insertCallable = () -> userDao.insert(user);
    long rowId = 0;

    Future<Long> future = executorService.submit(insertCallable);
     try {
         rowId = future.get();
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return rowId;
 }
 

Réf: Tutoriel du service d'exécution Java pour plus d'informations sur Callable.

7voto

Supriya Naveen Points 16

Dans vous Dao, la requête insérée retourne Long c'est-à-dire le rowId inséré.

  @Insert(onConflict = OnConflictStrategy.REPLACE)
 fun insert(recipes: CookingRecipes): Long
 

Dans votre classe Model (Repository): (MVVM)

 fun addRecipesData(cookingRecipes: CookingRecipes): Single<Long>? {
        return Single.fromCallable<Long> { recipesDao.insertManual(cookingRecipes) }
}
 

Dans votre classe ModelView: (MVVM) Gérez LiveData avec DisposableSingleObserver.
Référence de fournisseur active: https://github.com/SupriyaNaveen/CookingRecipes

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X