domingo, 10 de abril de 2016

Tutorial SQLite en Android - Ejemplo CRUD

En este tutorial vamos a ver cómo crear una base de datos en Android, además analizaremos que clases y métodos necesitamos, para que sirven y cómo utilizarlos. El ejemplo consistirá en una tabla llamada Clientes y dividiré el articulo en dos partes, este que es el de la creación y el segundo en el que realizaremos todas las operaciones CRUD (Create, Read, Update and Delete).

La tabla que vamos a crear es la siguiente:

tabla sqlite android

Con los campos:

  • _id  INTEGER PRIMARY KEY AUTOINCREMENT
  • nombre TEXT NOT NULL
  • telefono TEXT
  • email TEXT


La sentencia PRIMARY KEY AUTOINCREMENT indica que además de ser la clave primaria de la tabla se va a incrementar automáticamente cada vez que añadamos un nuevo cliente. Por otro lado NOT NULL en el nombre indica que este campo no puede estar vacío. Es SQL básico.

Como los nombres de los campos y otros Strings los vamos a utilizar bastante voy a crear una clase llamada ConstansDB que además incluirá la sentencia SQL de creación de la tabla:



ConstansDB.java

package net.codigoalonso.sqlitetutorial;

// codigoalonso.net
public class ConstantsDB {

    //General
    public static final String DB_NAME = "database.db";
    public static final int DB_VERSION = 1;


    //TABLA CLIENTES
    public static final String TABLA_CLIENTES = "clientes";

    public static final String CLI_ID = "_id";
    public static final String CLI_NOMBRE = "nombre";
    public static final String CLI_TELF = "telefono";
    public static final String CLI_MAIL = "email";

    public static final String TABLA_CLIENTES_SQL =
            "CREATE TABLE  " + TABLA_CLIENTES + "(" +
            CLI_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
            CLI_NOMBRE + " TEXT NOT NULL," +
            CLI_TELF   + " TEXT," +
            CLI_MAIL   + " TEXT);" ;

    //Otras tablas
}

También necesitaremos nuestra clase cliente:

Cliente.java

package net.codigoalonso.sqlitetutorial;

public class Cliente {

    private int id;
    private String name;
    private String telf;
    private String mail;

    public Cliente() {}

    public Cliente(String name, String telf, String mail) {
        this.name = name;
        this.telf = telf;
        this.mail = mail;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTelf() {
        return telf;
    }

    public void setTelf(String telf) {
        this.telf = telf;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    @Override
    public String toString() {
        return "Cliente{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", telf='" + telf + '\'' +
                ", mail='" + mail + '\'' +
                '}';
    }
}


Ahora voy a crear una clase que se encargará de todo lo demás, la llamaré ClientesDB y tendrá dos objetos principales de tipo SQLiteDatabase y DBHelper. El primero lo utilizaremos para realizar las operaciones de insertar, borrar, actualizar y leer los datos mientras que el segundo nos permite abrir la base de datos para lectura o escritura:

ClientesDB.java

package net.codigoalonso.sqlitetutorial;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;


public class ClientesDB {
    private SQLiteDatabase db;
    private DBHelper dbHelper;

    public ClientesDB(Context context) {
        dbHelper = new DBHelper(context);
    }

    private void openReadableDB() {
        db = dbHelper.getReadableDatabase();
    }

    private void openWriteableDB() {
        db = dbHelper.getWritableDatabase();
    }

    private void closeDB() {
        if(db!=null){
            db.close();
        }
    }

   // CRUD...

    private static class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context) {
            super(context, ConstantsDB.DB_NAME, null, ConstantsDB.DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(ConstantsDB.TABLA_CLIENTES_SQL);
        }

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

        }
    }

}


La clase interna DBHelper será la encargada de crear la base de datos en el caso de que no exista, llamando al método onCreate y ejecutando las sentencias de creación de las tablas.
El método onUpgrade es utilizado para modificar la estructura de las tablas normalmente con la sentencia "ALTER TABLE" cuando queremos realizar cambios sin perder los datos, para ello necesitaríamos incrementar la versión de nuestra BD.

Ahora vamos a añadir una serie de métodos para realizar las operaciones CRUD sobre nuestra clase ClientesDB, pero antes añadiré un método que utilizaremos bastante para devolver un objeto de tipo ContentValues que almacenará los valores de los atributos de un objeto cliente:

    private ContentValues clienteMapperContentValues(Cliente cliente) {
        ContentValues cv = new ContentValues();
        cv.put(ConstantsDB.CLI_NOMBRE, cliente.getName());
        cv.put(ConstantsDB.CLI_TELF, cliente.getTelf());
        cv.put(ConstantsDB.CLI_MAIL, cliente.getMail());
        return cv;
    }


Insertar en la base de datos:


    public long insertCliente(Cliente cliente) {
        this.openWriteableDB();
        long rowID = db.insert(ConstantsDB.TABLA_CLIENTES, null, clienteMapperContentValues(cliente));
        this.closeDB();

        return rowID;
    }


Actualizar o modificar:


    public void updateCliente(Cliente cliente) {
        this.openWriteableDB();
        String where = ConstantsDB.CLI_ID + "= ?";
        db.update(ConstantsDB.TABLA_CLIENTES, clienteMapperContentValues(cliente), where, new String[]{String.valueOf(cliente.getId())});
        db.close();
    }


Borrar:


    public void deleteCliente(int id) {
        this.openWriteableDB();
        String where = ConstantsDB.CLI_ID + "= ?";
        db.delete(ConstantsDB.TABLA_CLIENTES, where, new String[]{String.valueOf(id)});
        this.closeDB();
    }


Leer:


    public ArrayList loadClientes() {

        ArrayList list = new ArrayList<>();

        this.openReadableDB();
        String[] campos = new String[]{ConstantsDB.CLI_ID, ConstantsDB.CLI_NOMBRE, ConstantsDB.CLI_TELF, ConstantsDB.CLI_MAIL};
        Cursor c = db.query(ConstantsDB.TABLA_CLIENTES, campos, null, null, null, null, null);

        try {
            while (c.moveToNext()) {
                Cliente cliente = new Cliente();
                cliente.setId(c.getInt(0));
                cliente.setName(c.getString(1));
                cliente.setTelf(c.getString(2));
                cliente.setMail(c.getString(3));
                list.add(cliente);
            }
        } finally {
            c.close();
        }
        this.closeDB();

        return list;
    }


Obtener un registro:


    public Cliente buscarCliente(String nombre) {
        Cliente cliente = new Cliente();
        this.openReadableDB();
        String where = ConstantsDB.CLI_NOMBRE + "= ?";
        String[] whereArgs = {nombre};
        Cursor c = db.query(ConstantsDB.TABLA_CLIENTES, null, where, whereArgs, null, null, null);

        if( c != null || c.getCount() <=0) {
            c.moveToFirst();
            cliente.setId(c.getInt(0));
            cliente.setName(c.getString(1));
            cliente.setTelf(c.getString(2));
            cliente.setMail(c.getString(3));
            c.close();
        }        
        this.closeDB();
        return cliente;
    }


Ahora vamos a comprobar que todo funciona correctamente:


package net.codigoalonso.sqlitetutorial;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ClientesDB db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        db = new ClientesDB(this);

        Cliente cliente1 = new Cliente("Jaime","11111","jaime@mail.net");
        Cliente cliente2 = new Cliente("Juan","22222","juan@mail.net");
        Cliente cliente3 = new Cliente("Pedro","33333","pedro@mail.net");
        Cliente cliente4 = new Cliente("David","44444","david@mail.net");

        Log.i("---> Base de datos: ", "Insertando Clientes....");
        db.insertCliente(cliente1);
        db.insertCliente(cliente2);
        db.insertCliente(cliente3);
        db.insertCliente(cliente4);
        Log.i("---> Base de datos: ", "Mostrando Clientes....");
        mostrarClientesLog();

        Log.i("---> Base de datos: ", "Borrando Cliente con id 1....");
        db.deleteCliente(1);
        mostrarClientesLog();

        Log.i("---> Base de datos: ", "Cambiando el nombre de cliente2....");
        cliente2.setName("María");
        db.updateCliente(cliente2);
        mostrarClientesLog();

        Log.i("---> Base de datos: ", "Buscando datos de cliente....");
        Cliente cliente = new Cliente();
        cliente = db.buscarCliente("Juan");
        Log.i("---> Base de datos: ", "Los datos de pedro son: "+cliente.toString());

        Log.i("---> Base de datos: ", "Cambiando el nombre de Juan....");
        cliente.setName("Maria");
        db.updateCliente(cliente);
        mostrarClientesLog();
    }

    private void mostrarClientesLog() {
        List list = db.loadClientes();

        for(Cliente cliente : list) {
            Log.i("---> Base de datos: ", cliente.toString());
        }
    }
}

Salida:
Ejemplo sqlite logcat output




No hay comentarios:

Publicar un comentario