SQLite, Android y Phonegap, adios Localstorage

Conforme la aplicación fue avanzando nos vimos obligados a cambiar el sistema de almacenamiento de datos para hacerlo un poco más robusto. Para ello optamos por implementar SQLite en la aplicación.

SQLite viene por defecto en la API de Android y no es necesario incluir ninguna librería extra. Como introducción está bien, pero vamos a pasar a lo interesante.

Para crear la Base de Datos que va a usar la aplicación solo necesitamos instanciar una clase que extienda de SQLiteOpenHelper. Cuando se haga esa llamada al constructor de la clase, el método super, comprobará internamente si existe la base de datos, en caso contrario la creará inmediatamente y ejecutará el método onCreate donde tendremos las queries que queremos ejecutar al iniciar. Este método sólo se ejecutará si la base de datos no existía. En cualquier otra instanciación de la clase DataBase no se ejecutará.

private String CREATE_USER_SQL = "CREATE TABLE accounts (_id INTEGER PRIMARY KEY AUTOINCREMENT, nif VARCHAR(10), name TEXT, bolsa TEXT)";

private String CREATE_POSITIONS_SQL = "CREATE TABLE positions (_id INTEGER PRIMARY KEY AUTOINCREMENT, general INTEGER, sevilla INTEGER, nif VARCHAR(10), fecha DATETIME DEFAULT CURRENT_TIMESTAMP)";

public class DataBase extends SQLiteOpenHelper{

     public DataBase(Context context) {
         super(context,InfobolsaConstants.DATABASE_NAME, null, InfobolsaConstants.DATABASE_VERSION);
     }

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

     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         if(oldVersion == 1){
	     db.execSQL(InfobolsaConstants.ALTERTABLE_POSITIONS_SQL);
	     db.execSQL(InfobolsaConstants.CREATE_POSITIONS_SQL)
        }
        if(newVersion == InfobolsaConstants.DATABASE_VERSION){
             db.execSQL(InfobolsaConstants.ALTERTABLE_BOLSAS_SQL);
             db.execSQL(InfobolsaConstants.CREATE_BOLSAS_SQL);
             db.execSQL(InfobolsaConstants.ALTERTABLE_BOLSAS_DATA_SQL);
        }
     }
}

Posteriormente, si la versión de la base datos es superior a la que había antes, se ejecutará el método onUpgrade que o bien podemos dejar vacío o bien podemos ejecutar una SQL que nos permita hacer una migración o actualización de datos. Para ello, podemos usar los parámetros oldVersion y newVersion para saber con cual versión queremos que se ejecute dicha actualización.

Una vez creada la Base de Datos ya podemos realizar consultar e inserciones sobre la misma. Para ello, vamos a poner unos ejemplos básicos.

¿Cómo puedo realizar un INSERT y un UPDATE en una base de datos SQLite en Android?


public User saveData(String nif, String name, String bolsa){

     SQLiteDatabase db = null;
     User us = new User();
     try{
          ContentValues cv = new ContentValues();
          cv.put("nif", nif);
          cv.put("name", name);
          cv.put("bolsa", bolsa);
          db = SQLiteDatabase.openOrCreateDatabase(getWritableDatabase().getPath(), null) ;
          long rowid = db.insertOrThrow(InfobolsaConstants.USER_TABLE, null, cv);
          if(rowid > 0){
               us = new User(name, nif, bolsa);
          }
     }catch(Exception e){
          Log.e("DATABASE", "saveData: "+e.getMessage());
     }finally{
         if(db != null){
             db.close();
         }
     }
     return us;
 }

public void updateBolsas(List bolsasToUpdate){

      SQLiteDatabase db = null;
      try{
           db = SQLiteDatabase.openOrCreateDatabase(getWritableDatabase().getPath(), null);
           for(Bolsa b: bolsasToUpdate){
               ContentValues cv = new ContentValues();
               cv.put("lastAct", b.getLastAct().getTime());
               if(db.update(InfobolsaConstants.BOLSAS_TABLE, cv, "bolsa = ?", new String[]{b.getBolsa()}) == 0){
                   cv.put("bolsa", b.getBolsa());
                   db.insert(InfobolsaConstants.BOLSAS_TABLE, null, cv);
               }
           }
       }catch(Exception e){
              Log.e("DATABASE", "updateBolsas: "+e.getMessage());
       }finally{
           if(db != null){
                db.close();
           }
       }
 }

Si vas a usar esta clase con un plugin de Phonegap, os recomendamos poner siempre el return al final de la clase ya que se ejecuta como si fuera un script.

¿Cómo puedo realizar una SELECT sobre una base de datos SQLite en Android?


public List getAllUsers(){

     List usuarios = new ArrayList();
     User us = null;
     SQLiteDatabase db = null;
     Cursor users = null;
     try{
          db = SQLiteDatabase.openOrCreateDatabase(getReadableDatabase().getPath(), null);
          users = db.rawQuery(InfobolsaConstants.USER_SELECT_QUERY, new String[]{nif});
          if(users.moveToFirst()){
              do{
                   usuarios.add(new User(users));
              }while(users.moveToNext());
          }

     }catch(Exception e){
         Log.e("DATABASE", "getUserByNif: "+nif+ " - "+e.getMessage());
     }finally{
         if(users != null){
             users.close();
         }
         if(db != null){
             db.close();
         }
     }
     return usuarios;
 }

..........................

public class User {
      // En el constructor obtenemos los datos del CURSOR de SQLite
      public User(Cursor c){
           if(c.getColumnIndex(InfobolsaConstants.COLUMN_ID) > 0){
                this.id = c.getInt(c.getColumnIndex(InfobolsaConstants.COLUMN_ID));
           }
           this.name = c.getString(c.getColumnIndex(InfobolsaConstants.COLUMN_NAME));
           this.nif = c.getString(c.getColumnIndex(InfobolsaConstants.COLUMN_NIF));
           this.bolsa = c.getString(c.getColumnIndex(InfobolsaConstants.COLUMN_BOLSA));
      }
}

¿Cómo puedo hacer un DELETE en una base de datos SQLite en Android?

public boolean deleteUser(String nif){
      SQLiteDatabase db = null;
      int result = -1;
      try{
           db = SQLiteDatabase.openOrCreateDatabase(getReadableDatabase().getPath(), null);
           result = db.delete(InfobolsaConstants.USER_TABLE, "nif = ?", new String[]{nif});
           if(result > 0){
                result = db.delete(InfobolsaConstants.POSITIONS_TABLE, "nif = ?", new String[]{nif});
           }
      }catch(Exception e){
           Log.e("DATABASE", "deleteUser: "+nif + " - "+e.getMessage());
      }finally{
           if(db != null){
              db.close();
           }
      }
      return (result > 0);
}

¿Cómo puedo usar la base de datos desde Phonegap? Lo mejor es crearte una Plugin que es el encargado de acceder a los datos.

Esperamos que te haya sido útil.

Vida EXTRA: ¿Necesitas hacer una query para comparar fechas en SQLite y Android? Después de mil y un intentos, lo mejor fue hacer esta “CHAPUZA”

    String query = "SELECT * FROM positions where nif = ? AND fecha between  F1 AND F2 ORDER BY fecha DESC";
    query = query.replaceAll("F1", ""+last2Month.getTime().getTime()).replaceAll("F2", ""+today.getTime().getTime());
    db.rawQuery(query, new String[]{nif});
Cuidado con el SQL Inyection
Anuncios

3 comentarios

  1. Al actualizar a la versión 2.0.2 ya no funciona. El programa ahora ni siquiera arranca. He borrado la caché, lo he desinstalado, y lo he vuelto a instalar pero sigue sin arrancar el programa. Uso android ICS.

    1. Hola, gracias por ponerse en contacto, que dispositivo es? Qué versión de Android?

  2. […] esta aplicación, en lugar de usar SQLite y así evitar tener que trabajar en todas las plataformas optamos por WEBSQL y LocalStorage […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: