En este tutorial aprenderás a eliminar datos con Room con la anotación @Delete
.
Al igual que @Insert
y @Update
es posible eliminar uno o varios registros de la base de datos y usar POJOs arbitrarios para especificar columnas particulares.
La Anotación @Delete
Para especificar que un método de un DAO será para eliminación márcalo con @Delete
.
Sus parámetros deben ser objetos anotados con @Entity
. Similar a las demás operaciones, Room flexibiliza la cantidad de filas que deseamos eliminar.
Ejemplo: Eliminar una, tres listas o una lista dinámica de listas de compras:
@Delete
void deleteShoppingList(ShoppingList shoppingList);
@Delete
void deleteShoppingLists(ShoppingList... shoppingLists);
@Delete
void deleteShoppingLists(List<ShoppingList> shoppingLists);
Si deseamos eliminar dependiendo de los valores de unas cuantas columnas, entonces podemos pasar un POJO que represente esta necesidad y lo asociamos con la propiedad entity
.
Ejemplo: Crea una entidad llamada ShoppingListId
para eliminar una lista de compras por su ID.
public class ShoppingListId {
public String id;
public ShoppingListId(String id) {
this.id = id;
}
}
Luego creamos un método en el DAO que reciba el objeto para que Room lo interprete como una entidad parcial:
@Delete(entity = ShoppingList.class)
void deleteShoppingList(ShoppingListId shoppingList);
Por otro lado, si quieres borrar todos los elementos de la tabla, debes acudir a la anotación @Query
para ordenar la operación DELETE
:
@Query("DELETE FROM shopping_list");
void deleteAllShoppingLists();
O si quieres eliminar por Id a través de parámetros bindeables, entonces:
@Query("DELETE FROM shopping_list WHERE id=:id")
void deleteShoppingList(String id);
Ejemplo Para Eliminar Datos Con Room
Para demostrar la eliminación añadiremos dos pequeños casos de uso a nuestra App de listas de compras como se ve en el siguiente prototipo:
El primero es la eliminación individual desde el ítem de la lista y el segundo es la eliminación de todas las listas desde el overflow de la Toolbar.
A continuación vamos a ver los pasos principales para el desarrollo. Si deseas descargar el código para guiarte, usa el siguiente enlace:
Eliminar Lista De Compras Por Id
Esta característica nace del clic del usuario en un botón que existe en el ítem. Sabiendo esto, agreguémoslo al layout, procesemos el evento y propaguemos el evento hacia el ViewModel y el Repositorio.
1. Agregar Botón De Eliminar
Abre shopping_list_item.xml y posiciona al lado del botón de favorito, un ImageView
que represente el ítem de acción para eliminar. Usa como como icono el vector asset llamado delete.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:padding="@dimen/normal_padding"
android:layout_height="?listPreferredItemHeight">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/favorite_button"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Lista de ejemplo" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/favorite_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:button="@drawable/sl_favorite_24"
android:minWidth="0dp"
android:minHeight="0dp"
app:buttonTint="@color/favorite_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/delete_button"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_delete_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. Procesar Clic En El Adaptador
De la misma forma que hicimos con el botón de favoritos, agrega un método para la eliminación:
interface ItemListener {
void onClick(ShoppingListForList shoppingList);
void onFavoriteIconClicked(ShoppingListForList shoppingList);
void onDeleteIconClicked(ShoppingListForList shoppingList);
}
Luego asigna una escucha OnClickListener
para que onDeleteIconClicked()
sea disparado en la actividad principal:
public class ShoppingListViewHolder extends RecyclerView.ViewHolder {
private final TextView mNameText;
private final CheckBox mFavoriteButton;
private final ImageView mDeleteButton;
public ShoppingListViewHolder(@NonNull View itemView) {
super(itemView);
mNameText = itemView.findViewById(R.id.name);
mFavoriteButton = itemView.findViewById(R.id.favorite_button);
mDeleteButton = itemView.findViewById(R.id.delete_button);
// Setear eventos
mFavoriteButton.setOnClickListener(this::manageEvents);
mDeleteButton.setOnClickListener(this::manageEvents);
itemView.setOnClickListener(this::manageEvents);
}
private void manageEvents(View view) {
if (mItemListener != null) {
ShoppingListForList clickedItem = mShoppingLists.get(getAdapterPosition());
// Manejar evento de click en Favorito
if (view.getId() == R.id.favorite_button) {
mItemListener.onFavoriteIconClicked(clickedItem);
return;
} else if (view.getId() == R.id.delete_button) {
mItemListener.onDeleteIconClicked(clickedItem);
return;
}
mItemListener.onClick(clickedItem);
}
}
public void bind(ShoppingListForList item) {
mNameText.setText(item.name);
mFavoriteButton.setChecked(item.favorite);
}
}
3. Propagar Acción Al ViewModel Y Repositorio
Ve a MainActivity
y sobrescribe el método anteriormente creado. Este debe ejecutar un nuevo método de ShoppinListViewModel
llamado deleteShoppingList(),
el cuál recibe como parámetro la lista de compras:
// Asignar escucha de ítems
mAdapter.setItemListener(new ShoppingListAdapter.ItemListener() {
@Override
public void onClick(ShoppingListForList shoppingList) {
editShoppingList(shoppingList);
}
@Override
public void onFavoriteIconClicked(ShoppingListForList shoppingList) {
mViewModel.markFavorite(shoppingList);
}
@Override
public void onDeleteIconClicked(ShoppingListForList shoppingList) {
mViewModel.deleteShoppingList(shoppingList);
}
});
2. El método deleteShoppingList()
mapeará el objeto entrante al POJO parcial que construimos. Asignando el id correspondiente:
public void deleteShoppingList(ShoppingListForList shoppingList) {
ShoppingListId id = new ShoppingListId(shoppingList.id);
mRepository.deleteShoppingList(id);
}
3. Ahora en el método equivalente del repositorio creamos un nuevo hilo y ejecutamos la eliminación desde el DAO.
public void deleteShoppingList(ShoppingListId id) {
ShoppingListDatabase.dbExecutor.execute(
() -> mShoppingListDao.deleteShoppingList(id)
);
}
Al ejecutar el proyecto debes ver los ítems con su icono de eliminación. Y si pruebas clickear desaparecerán de la lista.
Eliminar Todas Las Listas De Compras
Esta acción es ejecutada desde un ítem de acción que se encuentra en el overflow de la Toolbar. Al igual que el caso anterior, agreguemos este botón, procesemos su clic y propaguemos las acciones hacia la capa de datos.
1. Añadir Action Button Para Eliminar
Crea un recurso de menú llamado main_menu.xml y agrega el ítem de eliminación:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/delete_all"
android:title="@string/delete_all"
app:showAsAction="never" />
</menu>
2. Procesar Evento De Action Button
Luego, ve a la actividad principal y añade los métodos onCreateOptionsMenu()
para inflar el recurso anterior y onOptionsItemSelected()
para detectar el evento de clic:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
if (R.id.delete_all == itemId) {
mViewModel.deleteAll();
return true;
}
return super.onOptionsItemSelected(item);
}
3. Actualizar ViewModel Y Repositorio
Repetimos las tareas anteriores. Propagamos la acción de eliminación total desde el ViewModel con un nuevo método llamado deleteAll()
.
public void deleteAll() {
mRepository.deleteAll();
}
El repositorio abrirá el hilo de trabajo y ejecutará el método de eliminación del DAO:
public void deleteAll() {
ShoppingListDatabase.dbExecutor.execute(
mShoppingListDao::deleteAllShoppingLists
);
}
Y finalmente tendremos ambas características implementadas. Ejecuta y al presionar el ítem de eliminación de todas las listas verás:
Siguiente tutorial: Relaciones Uno A Uno Con Room
Únete Al Discord De Develou
Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!