Está en la página 1de 14

Base de datos SQLite

SQLite es un motor de base de datos relacional de cdigo abierto y muy potente, eso hace
que actualmente sea muy usado por los desarrolladores. Sus principales caractersticas son
que precisa de poca configuracin, no necesita ningn servidor ya que directamente lee y
escribe en archivos de disco normales, ocupa muy poco tamao en el almacenamiento y a
parte es multiplataforma.

Android ofrece de serie soporte total para la creacin y administracin de base de datos
SQLite a travs del paquete "android.database.sqlite". Solo tendremos que definir las
sentencias SQL para crear y gestionar la base de datos.

En este caso nos vamos a centrar en:
Creacion y gestion de una base de datos SQLite
Copia base de datos existente a nuestra aplicacion


1. Creacin base de datos SQLite
Para poder crear bases de datos en nuestra aplicacin debemos usar las clases hijas de
"SQLiteOpenHelper". Que nos pide crear un constructor y sobreescribir dos mtodos:
"onCreate(SQLiteDatabase db)"
"onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)"
El primero se encargara de crear las tablas si no existen y el segundo las actualizara si nos
es necesario (imaginemos que creamos una tabla con 2 columnas y mas adelante nos hace
falta aadir mas columnas, con este mtodo podramos hacerlo pasndole como parmetro
la versin de la tabla antigua y la versin de la nueva tabla).

Dentro de una base de datos podemos crear tantas tablas como nos sea necesario, su
estructura y la que usaremos en el ejemplo tendr la siguiente forma:
id nombre telefono email
1 Pedro 111111111 pedro@DB.es
2 Sandra 111111111 sandra@DB.es
3 Maria 111111111 maria@DB.es
4 Daniel 111111111 daniel@DB.es


As que vamos a verlo en un ejemplo:
public class MiBaseDatos extends SQLiteOpenHelper {

private static final int VERSION_BASEDATOS = 1;

// Nombre de nuestro archivo de base de datos
private static final String NOMBRE_BASEDATOS =
"mibasedatos.db";

// Sentencia SQL para la creacin de una tabla
private static final String TABLA_CONTACTOS = "CREATE TABLE
contactos" +
"(_id INT PRIMARY KEY, nombre TEXT, telefono INT,
email TEXT)";


// CONSTRUCTOR de la clase
public MiBaseDatos(Context context) {
super(context, NOMBRE_BASEDATOS, null, VERSION_BASEDATOS);
}

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

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLA_CONTACTOS);
onCreate(db);
}
}
Como vemos en el ejemplo, en muy pocas lineas de cdigo podemos crear una tabla en
nuestro archivo de base de datos.

Lo primero que hacemos es crear tres variables:
NOMBRE_BASEDATOS: sera el nombre de nuestro archivo de base de datos
VERSION_BASEDATOS: la versin de nuestra base de datos
TABLA_CONTACTOS: un string que contiene una sentencia SQL para la creacin de una
tabla llamada contactos. Lo que tenemos en parentesis son las columnas, un ndice INT
primario (no es obligatorio pero si muy recomendable para no tener problemas a la hora de
insertar, modificar o borrar alguna fila ya que es un valor nico), un nombre TEXT, un
telefono INT y un e-mail TEXT. Como podemos ver hay que especificar que tipo de datos
va a manejar esa columna (TEXT, NUM, INT, REAL, ...)
La sintaxis SQL es muy extensa y aqu nos vamos a centrar en lo justo y necesario si deseas
conocer mas sobre ella te recomiendo que visites tu pagina web SQLite.

Seguimos con el constructor de la clase que nos pide como parmetros un context, el
nombre del archivo de la base de datos, un CursorFactory que no lo vamos a necesitar y por
lo tanto lo ponemos a null y la versin de nuestra base de datos.

Comentar que para gestionar la base de datos y la clase que estamos creando, vamos a usar
mtodos de la clase "SQLiteDatabase".

Y para terminar la clase sobreescribimos los mtodos onCreate y onUprade usando el
mtodo "execSQL()" que nos pide como parametro una unica sentencia SQL que no sea un
SELECT o cualquier otra sentencia que devuelva datos. Entonces en el onCreate
simplemente creamos la tabla si no existe y en el onUpgrade borramos la tabla si existe y
creamos una nueva.



2. Gestionar base de datos

Para gestionar la base de datos vamos a crear unos mtodos personalizados para leer,
escribir, modificar y eliminar registros de nuestra tabla. Aunque tambin podramos usar
sentencias SQL con el mtodo execSQL, pero este no va a ser el caso.

2.1 Insertar registros
public void insertarCONTACTO(int id, String nom, int tlf, String
email) {
SQLiteDatabase db = getWritableDatabase();
if(db != null){
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.insert("contactos", null, valores);
db.close();
}
}
Creamos un mtodo "insertarCONTACTO" y como parmetros los datos que queremos
insertar en la tabla (id, nombre, telefono, email). Dentro del mtodo creamos una instancia
de la clase "SQLiteDatabase" y usamos su mtodo "getWritableDatabase()" para poder
escribir en la base de datos. Encapsulamos todo en un if por si acaso la base de datos no
existe y ya dentro del if creamos una instancia de la clase "ContentValues" que como su
nombre indica es un almacenador de un conjunto de datos. Usamos el metodo "put(key,
value)" que nos pide como primer parmetro "key" el nombre donde establecer el valor
almacenado y como segundo parmetro el valor que queremos almacenar. Una vez
almacenamos los datos insertamos una fila en la tabla usamos el mtodo "insert(table,
nullColumnHack, values)" que nos pide el nombre de la tabla "table", un segundo
parmetro en caso de que necesitemos insertar valores nulos en la tabla "nullColumnHack"
en este caso lo dejaremos pasar ya que no lo vamos a usar y por lo tanto lo ponemos a null
y como tercer parmetro "values" nos pide un ContentValues. Para concluir deberemos
cerrar la base de datos con el mtodo "close()".


2.2 Modificar registros

public void modificarCONTACTO(int id, String nom, int tlf, String
email){
SQLiteDatabase db = getWritableDatabase();
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.update("contactos", valores, "_id=" + id, null);
db.close();
}
Prcticamente es igual que el anterior mtodo pero con la excepcin de que aqu estamos
usando el mtodo "update(table, values, whereClause, whereArgs)" para
actualizar/modificar registros de nuestra tabla. Este mtodo nos pide el nombre de la tabla
"table", los valores a modificar/actualizar "values" (ContentValues), una condicin
WHERE "whereClause" que nos sirve para indicarle que valor queremos que actualic (en
este caso cogemos como referencia la id de nuestro contacto) y como ultimo parmetro
"whereArgs" podemos pasarle los valores nuevos a insertar, en este caso no lo vamos a
necesitar por lo tanto lo ponemos a null. Para terminar deberemos cerrar siempre nuestra
base de datos con el mtodo "close()".


2.3 Borrar registros

public void borrarCONTACTO(int id) {
SQLiteDatabase db = getWritableDatabase();
db.delete("contactos", "_id="+id, null);
db.close();
}
Para borrar registros usaremos el mtodo "delete(table, whereClause, whereArgs)" que nos
pide el nombre de la tabla "table", el registro a borrar "whereClause" que tomaremos como
referencia su id y como ultimo parmetro "whereArgs" los valores a borrar.


2.4 Leer registros
Para leer registros vamos a crear una clase "Contactos" con un constructor y varios mtodos
get/set para convertir una fila de la tabla en un objeto y nos sea mas fcil acceder a
cualquier valor de ese registro. Los mtodos get/set simplemente son mtodos para
recuperar o establecer un valor del objeto Contactos.

public class Contactos {

private int id;
private String nombre;
private int telefono;
private String email;

// Constructor de un objeto Contactos
public Contactos(int id, String nombre, int telefono, String
email) {
this.id = id;
this.nombre = nombre;
this.telefono = telefono;
this.email = email;
}

// Recuperar/establecer ID
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}

// Recuperar/establecer NOMBRE
public String getNOMBRE() {
return nombre;
}
public void setNOMBRE(String nombre) {
this.nombre = nombre;
}

// Recuperar/establecer TELEFONO
public int getTELEFONO() {
return telefono;
}
public void setTELEFONO(int telefono) {
this.telefono = telefono;
}

// Recuperar/establecer EMAIL
public String getEMAIL() {
return email;
}
public void setEMAIL(String email) {
this.email = email;
}
}
Una vez creada nuestra clase Contactos volvemos a la clase "MiBaseDatos" para crear los
mtodos de lectura de un registro y lectura de todos los registros de la tabla.


2.4.1 Leer un registro
Para realizar consultas a la base de datos podremos utilizar cualquiera de estos dos
mtodos:
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit) -
Mtodo que usaremos en el ejemplo, como se puede observar recibe muchos
parametros que son utilizados para crear la declaracin SQL.
rawquery(sql, selectionArgs) - Este mtodo es mucho mas simple que el anterior,
directamente recibe una declaracin SQL como primer parmetro y un segundo
parmetro opcional (Recomendado para los que tengan experiencia en lenguaje
SQL, Gracias al usuario por el comentario !)

Los dos mtodos expuestos nos devolvern un Cursor que podremos recorrer para recuperar
todos los registros de la base de datos. Vamos a continuar con el atculo y vamos a crear el
mtodo para recuperar un registro:

public Contactos recuperarCONTACTO(int id) {
SQLiteDatabase db = getReadableDatabase();
String[] valores_recuperar = {"_id", "nombre", "telefono",
"email"};
Cursor c = db.query("contactos", valores_recuperar, "_id=" +
id,
null, null, null, null, null);
if(c != null) {
c.moveToFirst();
}
Contactos contactos = new Contactos(c.getInt(0),
c.getString(1),
c.getInt(2), c.getString(3));
db.close();
c.close();
return contactos;
}
Este mtodo devuelve un objeto Contactos con los datos del contacto (id, nombre, telefono,
email). En este caso como queremos leer hacemos uso del mtodo
"getReadableDatabase()". Creamos una variable "valores_recuperar" con las columnas que
queremos recuperar, en este caso vamos a recuperar todos los datos de un registro.
Continuamos creando un "Cursor" que se encarga de devolver el resultado de un registro de
la tabla y lo almacena en la memoria, le aplicamos el mtodo:
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
Con este mtodo conseguimos leer un registro de la tabla. Como primer parmetro "table"
nos pide el nombre de la tabla , "columns" las columnas que queremos recuperar, con
"selection" le indicamos el registro a recuperar (en este caso recuperamos con el id), o los
registros a recuperar "selectionArgs", "groupBy" para agrupar los registros consultados ,
"having" es un filtro para incluir los registros en el cursor (este parmetro se usara con
groupBy), "orderBy" para ordenar las filas y "limit" para limitar el numero de filas
consultadas.

Con el mtodo "moveToFirst()" ponemos el cursor al inicio de los datos almacenados. Lo
encapsulamos en un if por si acaso no hay datos almacenados.

Continuamos creando un objeto "Contactos" para almacenar los datos consultados de un
registro, y los vamos recuperando del cursor con mtodos get indicando la posicin de la
columna.

Para terminar debemos cerrar la base de datos y el cursor.


2.4.2 Leer todos los registro

public List<Contactos> recuperarCONTACTOS() {
SQLiteDatabase db = getReadableDatabase();
List<Contactos> lista_contactos = new
ArrayList<Contactos>();
String[] valores_recuperar = {"_id", "nombre", "telefono",
"email"};
Cursor c = db.query("contactos", valores_recuperar,
null, null, null, null, null, null);
c.moveToFirst();
do {
Contactos contactos = new Contactos(c.getInt(0),
c.getString(1),
c.getInt(2), c.getString(3));
lista_contactos.add(contactos);
} while (c.moveToNext());
db.close();
c.close();
return lista_contactos;
}
El mtodo que usamos en este casp es muy similar al de leer un registro pero en este caso
no especificamos que registro queremos recuperar, por lo tanto ponemos su parmetro a
null. A parte creamos una variable "lista_contactos" donde almacenaremos todos los
registros de la tabla en objetos contactos. En el bucle do-while usamos el mtodo
"moveToNext()" como parmetro que se encargara de pasar al siguiente registro de la tabla
y por lo tanto recorrer todos los registros de la tabla.



3. Uso de nuestra base de datos en una
Activity

public class MainActivity extends Activity {

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

MiBaseDatos MDB = new
MiBaseDatos(getApplicationContext());

// Escribimos 4 registros en nuestra tabla
MDB.insertarCONTACTO(1, "Pedro", 111111111,
"pedro@DB.es");
MDB.insertarCONTACTO(2, "Sandra", 222222222,
"sandra@DB.es");
MDB.insertarCONTACTO(3, "Maria", 333333333,
"maria@DB.es");
MDB.insertarCONTACTO(4, "Daniel", 444444444,
"daniel@DB.es");

// Recuperamos los 4 registros y los mostramos en el log
Log.d("TOTAL",
Integer.toString(MDB.recuperarCONTACTOS().size()));
int[] ids = new int[MDB.recuperarCONTACTOS().size()];
String[] noms = new
String[MDB.recuperarCONTACTOS().size()];
int[] tlfs = new int[MDB.recuperarCONTACTOS().size()];
String[] emls = new
String[MDB.recuperarCONTACTOS().size()];
for (int i = 0; i < MDB.recuperarCONTACTOS().size(); i++)
{
ids[i] = MDB.recuperarCONTACTOS().get(i).getID();
noms[i] = MDB.recuperarCONTACTOS().get(i).getNOMBRE();
tlfs[i] =
MDB.recuperarCONTACTOS().get(i).getTELEFONO();
emls[i] = MDB.recuperarCONTACTOS().get(i).getEMAIL();
Log.d(""+ids[i], noms[i] + ", " + tlfs[i] + ", " +
emls[i]);
}

// Modificamos el registro 3
MDB.modificarCONTACTO(3, "PPPPP", 121212121,
"xxxx@xxxx.es");

// Recuperamos el 3 registro y lo mostramos en el log
int id = MDB.recuperarCONTACTO(3).getID();
String nombre = MDB.recuperarCONTACTO(3).getNOMBRE();
int telefono = MDB.recuperarCONTACTO(3).getTELEFONO();
String email = MDB.recuperarCONTACTO(3).getEMAIL();
Log.d(""+id, nombre + ", " + telefono + ", " + email);

// Borramos el registro 3
MDB.borrarCONTACTO(3);
}
}
Lo primero que hacemos es crear una instancia de nuestra clase "MiBaseDatos" pasndole
como parmetro un contexto.

Para insertar registros llamamos al mtodo "insertarCONTACTO(id, nom, tlf, email)" y
simplemente le indicamos los valores a insertar.

A la hora de recuperar registros hacemos uso del mtodo
"MDB.recuperarCONTACTOS.size()" que nos devuelve el numero de registros de la tabla,
sabiendo esto podemos crear 4 arrays con ese tamao para almacenar los datos separados
por categora. Con el mtodo "get(i)" recuperamos un registro de la tabla y despus con los
mtodos "getID()", "getNOMBRE()", "getTELEFONO()" y "getEMAIL()" vamos
recuperando los datos de ese registro. Para terminar mostramos todo en el log.

Podemos modificar un registro de nuestra tabla con el mtodo "modificarCONTACTO(id,
nom, tlf, email)". Como primer parmetro indicaremos el registro a modificar y los
siguientes parmetros sern los nuevos valores para ese registro. Mostramos el nuevo
registro en el log.

Para concluir podemos borrar registros de la tabla con el mtodo "borrarCONTACTO(id)"
que nos pide como parmetro la id del registro a borrar.



CODIGO DE EJEMPLO: DESCARGAR



4. Copiar base de datos existente

En ocasiones ser necesario incluir a nuestro proyecto un archivo de base de datos ya
creado. O podriamos crearlo nosotros mismos con cualquiera de estos dos gestores de bases
de datos:
SQLite Database Browser (Gratuita, multiplataforma y de cdigo abierto)
Valentina estudio (Aplicacin multiplataforma recomendada en los comentarios)
En este caso incluiremos el archivo de base de datos en la carpeta assets de nuestro
proyecto. Y por ejemplo crear un mtodo personalizado en nuestra Activity principal y
copiar la base de datos de la carpeta assets a la carpeta privada de base de datos de nuestra
aplicacin. A continuacin dejo un ejemplo:
private void copiarBaseDatos() {
String ruta = "/data/data/com.example.sqlite/databases/";
String archivo = "contactos.db";
File archivoDB = new File(ruta + archivo);
if (!archivoDB.exists()) {
try {
InputStream IS =
getApplicationContext().getAssets().open(archivo);
OutputStream OS = new FileOutputStream(archivoDB);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = IS.read(buffer))>0){
OS.write(buffer, 0, length);
}
OS.flush();
OS.close();
IS.close();
} catch (FileNotFoundException e) {
Log.e("ERROR", "Archivo no encontrado, " +
e.toString());
} catch (IOException e) {
Log.e("ERROR", "Error al copiar la Base de Datos, " +
e.toString());
}
}
No me voy a parar a explicar esto ya que tenemos en este mismo blog un articulo que trata
sobre como manejar los archivos. Simplemente comentar que usaramos el mtodo al
comienzo del onCreate para tener disponible la base de datos desde el primer comienzo de
la aplicacin, a parte comentar que en la ruta
"/data/data/'NOMBREdelPAQUETE'/databases" se encuentran nuestros archivos de base
de datos. Para mas informacin sobre manejar archivos visitar: Opciones de
almacenamiento.

También podría gustarte