Introducción A SQLite En Android

El uso de bases de datos en Android se basa en el motor libre SQLite.

Google nos provee de un framework para administrar las bases de datos de nuestras aplicaciones con gran facilidad. Y mi objetivo es mostrarte de forma rápida como usarlo para crear una app Android con bases de datos.

Descarga el código de ejemplo aquí:

Frases App Android Studio

Aplicación Ejemplo De Frases

Crearemos una aplicación que muestre el listado de frases mencionadas por grandes personajes de la historia.

 

La imagen anterior muestra que cada ítem tendrá como texto primario la frase y como texto secundario el autor de esta.

Todos los datos estarán guardados en una base de datos SQLite para puedan sobrevivir al cerrar la app.

Veamos...

Crear Proyecto En Android Studio

1. Abre Android Studio, selecciona File > New > New project... y nombra al proyecto Frases App.

Configura su paquete como más te convenga al igual que el directorio donde se guardará.

 

2. Deja por defecto el target mínimo en 13 como muestra el wizard y presiona Next:

 

3. Cuando te pregunte por añadir una actividad al proyecto, selecciona la plantilla Basic Activity de la galería y clickea Next.

 

4. Usa como nombre de la actividad QuotesActivity y cambia su título a "Frases":

 

Presiona Finish y tendrás el nuevo proyecto.

Crear Base De Datos

Antes que nada crea un nuevo paquete java llamado data. Este permitirá separar los componentes que usaremos para SQLite:

 

Analiza y diseña la base de datos

En esta etapa debes identificar las entidades, atributos, relaciones y temporalidades que intervienen en tu problema.

Debido a que este ejemplo consiste de solo frases, entonces tendremos una sola entidad representada por una tabla llamada quote.

Este solo tendrá dos atributos:

  • quoteId: Identificador de la frase
  • body: Contenido de la frase
  • author: Autor de la frase

Aunque podría existir una tabla más para los autores, mantendremos simple el ejemplo.

Aprende más sobre apps con múltiples tablas

Crear contrato de base de datos

El contrato es una clase que contiene subclases que representan el esquema de las tablas. Estas guardarán los nombres de las columnas, tablas y uris por si usarás content providers.

Añade una nueva clase Java al paquete data con el nombre QuotesContract y pega el siguiente código:

/**
 * Esquema de la bd
 */
public class QuotesContract {

    public static abstract class QuoteTable implements BaseColumns{
        public static final String TABLE_NAME = "quote";

        public static final String QUOTE_ID = "quoteId";
        public static final String BODY = "body";
        public static final String AUTHOR = "author";
    }
}

Crear SQL Helper

El framework de Android provee una serie de clases con métodos de creación, actualización, borrado, acceso y modificación de bases de datos.

Una de ella es SQLiteOpenHelper, el cuál es el punto de entrada para crear la base de datos.

Solo basta con crear una clase que extienda de este y sobrescribir los controladores onCreate() y onUpgrade().

Con esto claro, añade una nueva clase a data llamada QuotesDbHelper y sobrescribe los controladores dichos:

/**

 * Controlador de la bd

 */

public class QuotesDbHelper extends SQLiteOpenHelper {

   

    public final static String DATABASE_NAME = "Quotes.db";

    public final static int DATABASE_VERSION = 1;

 

    public QuotesDbHelper(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);

    }

 

    @Override

    public void onCreate(SQLiteDatabase db) {

        // Comandos SQL

    }

 

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        // Ninguna operación por ahora

    }

}

Código SQL para creación de tablas

Recuerda que el comando CREATE TABLE es el encargado de crear una nueva tabla en los gestores basados en SQL.

Y es que generar la tabla quote solo requiere escribir el comando en un String y pasarlo al método SQLiteDatabase.execSQL() para ejecutarlo.

Observa:

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + QuoteTable.TABLE_NAME + "(" +
                QuoteTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                QuoteTable.QUOTE_ID + " TEXT NOT NULL ," +
                QuoteTable.BODY + " TEXT NOT NULL, " +
                QuoteTable.AUTHOR + " TEXT NOT NULL," +
                "UNIQUE(" + QuoteTable.QUOTE_ID + "))");
}

Insertar datos

La inserción de un registro en una tabla se realiza con SQLiteDatabase y su método insert().

Tan solo necesitas un objeto ContentValues con los valores de las columnas y el nombre de la tabla.

ContentValues values = new ContentValues();

        values.put(QuoteTable.QUOTE_ID, UUID.randomUUID().toString());
        values.put(QuoteTable.BODY, "Frase");
        values.put(QuoteTable.AUTHOR, "Autor"); 

        return db.insert(
                QuoteTable.TABLE_NAME,
                null,
                values
        );

La clase ContentValues requiere el nombre de la columna junto al valor correspondiente para armar la tupla.

Sabiendo esto, inserta 8 registros de prueba en la tabla quote.

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + QuoteTable.TABLE_NAME + "(" +
                QuoteTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                QuoteTable.QUOTE_ID + " TEXT NOT NULL ," +
                QuoteTable.BODY + " TEXT NOT NULL, " +
                QuoteTable.AUTHOR + " TEXT NOT NULL," +
                "UNIQUE(" + QuoteTable.QUOTE_ID + "))");

        mockData(db);
    }

    private void mockData(SQLiteDatabase db) {
        mockQuote(db, "El ignorante afirma, el sabio duda y reflexiona",
                "Aristóteles");
        mockQuote(db, "Hay derrotas que tienen mas dignidad que la victoria",
                "Jorge Luis Borges");
        mockQuote(db, "Si buscas resultados distintos, no hagas siempre lo mismo",
                "Albert Einstein");
        mockQuote(db, "Donde mora la libertad, allí está mi patria",
                "Benjamin Franklin");
        mockQuote(db, "Ojo por ojo y todo el mundo acabará ciego",
                "Mahatma Gandhi");
        mockQuote(db, "Ama hasta que te duela. Si te duele es buena señal",
                "Madre Teresa de Calcuta");
        mockQuote(db, "Si sientes que todo perdió su sentido, siempre habrá un ¨te quiero¨, siempre habrá un amigo",
                "Emerson");
        mockQuote(db, "Un amigo es uno que lo sabe todo de ti y a pesar de ello te quiere",
                "Elbert Hubbard ");
    }

    private long mockQuote(SQLiteDatabase db, String body, String author) {
        ContentValues values = new ContentValues();
        values.put(QuoteTable.QUOTE_ID, UUID.randomUUID().toString());
        values.put(QuoteTable.BODY, body);
        values.put(QuoteTable.AUTHOR, author);

        return db.insert(
                QuoteTable.TABLE_NAME,
                null,
                values
        );
    }

Crear lista de frases

1. Abre el layout de la actividad activity_quotes.xml y elimina el fab que se agregó por defecto:


xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.herprogramacion.frasesapp.QuotesActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />

 

 

 

2. Abre el layout de contenido referenciado en el componente . Dentro de este agrega un componente ListView a la jerarquía.

content_quotes.xml


xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_horizontal_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.herprogramacion.frasesapp.QuotesActivity"
tools:showIn="@layout/activity_quotes">

<ListView
android:id="@+id/quotes_list"
android:layout_width="match_parent"
android:divider="@null"
android:dividerHeight="@dimen/activity_vertical_margin"
android:layout_height="match_parent" />

3. En QuotesActivity obtén la instancia de la lista en onCreate():

public class QuotesActivity extends AppCompatActivity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_quotes);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);

 

        ListView quotesList = (ListView) findViewById(R.id.quotes_list);

    }

 

}

Leer datos de la tabla

La lectura de datos se realiza con el método SQLiteDatabase.query().

Su firma es la siguiente:

 

Sus parámetros son: Nombre de la tabla, columnas a consultar, condición del where, argumentos del where, columna para la sentencia group by, condición del group by y el orden.

Y el retorno es de tipo Cursor.

Un cursor es un objeto que almacena las referencias de las filas de una tabla, el cual permite movimientos de lectura dependiendo de la posición deseada.

Por ejemplo...

Para leer todas las frases de la tabla quote usaremos la siguiente expresión:

 

QuotesDbHelper dbHelper = new QuotesDbHelper(this);

Cursor c = dbHelper.getReadableDatabase().query(
        QuoteTable.TABLE_NAME,
        null,
        null,
        null,
        null,
        null,
        null
);

La mayoría de campos son null, ya que no tendremos ningún filtro ni excepción.

 

Poblar lista desde cursor

Crea una instancia de la clase SimpleCursorAdapter. Este nos permitirá generar un adaptador a partir de un Cursor.

SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                this,
                android.R.layout.two_line_list_item,
                c,
                new String[]{QuoteTable.BODY, QuoteTable.AUTHOR},
                new int[]{android.R.id.text1, android.R.id.text2},
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 

quotesList.setAdapter(adapter);

 

El primer parámetro es el contexto, en este caso la actividad.

Luego sigue el layout con el que inflarás los ítems. Aquí puedes apalancarte de un layout del sistema llamado two_line_list_item.xml, el cual contiene dos textviews en línea vertical.

El tercero es el cursor como fuente de datos. Luego van las columnas que se leerán para poblar los textviews identificados en el siguiente arregla de enteros y al final una bandera que autoriza el refresco automático de la lista, si hay cambios en el cursor.

Por último añade el adaptador a la lista con setAdapter().

El código final quedaría así:

QuotesActivity.java

 

public class QuotesActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quotes);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ListView quotesList = (ListView) findViewById(R.id.quotes_list);

        QuotesDbHelper dbHelper = new QuotesDbHelper(this);
        Cursor c = dbHelper.getReadableDatabase().query(
                QuoteTable.TABLE_NAME,
                null,
                null,
                null,
                null,
                null,
                null
        );

        SimpleCursorAdapter adapter = new SimpleCursorAdapter(
                this,
                android.R.layout.two_line_list_item,
                c,
                new String[]{QuoteTable.BODY, QuoteTable.AUTHOR},
                new int[]{android.R.id.text1, android.R.id.text2},
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

        quotesList.setAdapter(adapter);
    }

}

 

 

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO