Skip to content

Persistencia

vjgonzalez edited this page May 11, 2019 · 2 revisions

Información general

El módulo persistencia está implementado usando Sugar ORM v1.5.

La clase principal es ObjetoPersistente:

  • Cualquier clase que la extienda automáticamente habilita persistencia para sus instancias
  • Implementa una serie de métodos auxiliares para obtener objetos persistidos

Ejemplo de uso

Definir la clase persistente

public class Persona extends ObjetoPersistente {

    @Unique
    private Integer documento;
    private String nombre;
    private Persona madre;

    public Persona() {} // SugarORM requiere que la clase tenga constructor por defecto sin parámetros

    public Persona (Integer documento, String nombre, Persona madre) {
        super();
        this.documento = documento;
        this.nombre = nombre;
        this.madre = madre;
    }
}

Crear un objeto

Persona madre = new Persona(11111111, "Madre", null);
madre.save();

Persona hija = new Persona(22222222, "Hija", madre);
hija.save();

// Para obtener el id único que asigna SugarORM:
Long idHija = hija.getID();

Obtener objetos

Todos los objetos de una clase - buscando todas las Personas:

List<Persona> personas = ObjetoPersistente.listarTodos(Persona.class);

Por Id - buscando la Persona con id == idHija:

Persona hija = ObjetoPersistente.encontrarPorId(Persona.class, idHija );

Por atributo - buscando sólo una Persona llamada "Hija":

String clausulaWhere = NamingHelper.toSQLNameDefault("documento") + " = ?";
Persona hija = ObjetoPersistente.encontrarPrimero(Persona.class, clausulaWhere, "Hija");

Por atributo de tipo ObjetoPersistente - buscando todas las Personas por madre:

// [madre] es un objeto de tipo Persona ya inicializado
String idMadre = madre.getId().toString;
String clausulaWhere = NamingHelper.toSQLNameDefault("madre") + " = ?";
List<Persona> hijas = ObjetoPersistente.encontrar(Persona.class, clausulaWhere, idMadre );

Eliminar objetos

Todos los objetos de una clase - eliminando todas las Personas:

List<Persona> personas = ObjetoPersistente.borrarTodos(Persona.class);

Un objeto - eliminando una Persona con id == idHija:

Persona hija = ObjetoPersistente.encontrarPorId(Persona.class, idHija );
hija.delete();

Relaciones de distinta cardinalidad

Relaciones uno-a-uno

Como se puede ver en el ejemplo, relaciones uno-a-uno son soportadas, simplemente definiendo como miembro de la clase un ObjetoPersistente. Internamente es referenciado por una combinación de nombre de clase y valor de id.

Relaciones uno-a-muchos

Relaciones uno-a-muchos son soportadas también siguiendo el ejemplo anterior: Una Persona puede ser madre de N Personas.

Relaciones muchos-a-muchos

SugarORM no soporta de manera nativa relaciones muchos-a-muchos. UtilidadesDANE agrega soporte a esta cardinalidad mediante la clase auxiliar ParObjetoPersistente. Por ejemplo, dadas las clases Alumno y Curso (ambas extienden ObjtoPersistente):

Agregar un Alumno a un Curso:

Las siguientes alternativas son equivalentes:

// [alumno] y [curso] son objetos ya inicializados
curso.agregarObjeto(alumno);

o bien

// [alumno] y [curso] son objetos ya inicializados
alumno.agregarObjeto(curso);

Obtener todos los Alumnos que atienden un Curso:

// [curso] en un objeto ya inicializado
List<Alumno> alumnos = curso.obtenerRelaciones(Alumno.class);

Obtener todos los Cursos que atiende un Alumno:

// [alumno] en un objeto ya inicializado
List<Curso> cursos = alumno.obtenerRelaciones(Curso.class);

Quitar un Alumno de un Curso:

// [alumno] y [curso] son objetos ya inicializados
ParObjetoPersistente.eliminarPar(alumno,curso); // Los parámetros pueden pasarse en cualquier orden

Modificación de la definición de los ObjetosPersistentes

Al modificar la definición de ObjetosPersistentes (agregar o quitar atributos, modificar el nombre o el tipo de atributos existentes), si la aplicación ya se ejecutó en el dispositivo, se producen alteraciones a las tablas usadas por el ORM. SugarORM povee métodos para manejar estos casos de manera de procesar manualmente los datos existentes: SQL scripts y mediante el método onUpgrade.

Observaciones

  • SugarORM requiere que la clase tenga constructor por defecto sin parámetros
  • El objeto no se persiste hasta que se llama a save().
  • A cada ObjetoPersistente se le asigna un miembro id, de tipo Long, que es usado para referenciarlo unívocamente.
  • SugarORM soporta annotations: @Ignore, @Unique, @NotNull, etc. La lista completa puede encontrarse en github.
  • SugarORM convierte los nombres de clases y atributos para usar como nombres de tablas y columnas mediante el método NamingHelper.toSQLNameDefault(...). Según su documentación, el método devuelve:

    The equivalent string converted to UPPER_CASE_UNDER_SCORE unless camelCased equals "_id" (not case sensitive) in which case "_id" is returned.

Problemas conocidos

  1. Instant Run puede provocar que Sugar ORM no pueda crear las tablas de la BD al correr la aplicación por primera vez. Si se obtienen errores al correr la aplicación, deshabilitar Instant Run para permitir la creación de las tablas (se puede activar nuevamente después de crear las tablas). Para deshabilitar Instant Run en Android Studio: Settings -> Build, Execution, Deployment -> Instant Run -> [] "Enable Instant Run...".