No es un bug, es una característica no documentada

jueves, 3 de marzo de 2016

Acceso a datos. Bases de datos orientadas a objetos

2:37 Posted by Inazio Claver , No comments
(Fragmento obtenido de la Universidad de Los Andes, Venezuela)

Condiciones en las que nacen los SGBDR (años 60 – 70)

Uniformidad. Muchos datos estructurados de forma similar.
Orientación a Registros. Datos básicos organizados en registros de longitud fija.
Datos pequeños. Registros cortos, de 80 bytes o menos.
Campos atómicos. Cortos, indivisibles y de longitud fija.
Transacciones cortas. Tiempo de ejecución medido en fracciones de segundos / sin interacción del usuario.
Esquemas Conceptuales Estáticos. El esquema de la BD se cambia con muy poca frecuencia.
Procesamiento por Lotes. Poca interacción con el usuario.
Aplicaciones Casi Inexistentes. O a muy bajo nivel, embebidas e implementadas en el SGBD.

Con el tiempo, debido a la mayor capacidad de cómputo de los procesadores, mayor cantidad de memoria principal y secundaria y a la reducción generalizada de los costos del hardware fue posible desarrollar nuevos tipos de aplicaciones.
  • Diseño Asistido por Computador (CAD)
  • Ingeniería de Software Asistida por Computador (CASE)
  • Bases de datos de Multimedios
  • Sistemas de Información de Oficina
  • Sistemas de Información / Aplicaciones Empresariales
  • Sistemas Expertos de Bases de Datos (el cielo es el límite)

Nuevos tipos de aplicaciones, más capacidad de cómputo, más memoria principal y secundaria, implica que se producen cambios en la forma en que se ven y usan los SGBD.


Nuevas necesidades

Nuevas capas de aplicación
  • Reglas más complejas asociadas mucho más a nivel de aplicación (general) que a nivel de tuplas.
  • Mayor interacción (y más compleja) entre el usuario y la aplicación.
  • Transacciones de larga duración (en parte por el punto anterior).

Información más compleja à Objetos
Comportamiento asociado a la información à Objetos
Reducir la impedancia entre las nuevas capas de aplicación (Objetos) y el almacenamiento persistente de los datos (Relacional).

Sistemas de Gestión de BD Orientados a Objetos

Un Sistema de Gestión de Base de Datos Orientado a Objetos (SGBDOO) es un SGBD que integra de forma transparente características de las bases de datos (almacenamiento y acceso a la información, entre otros) con características de los lenguajes de programación de aplicación orientados a objetos.

Es decir, el SGBDOO se puede ver como una extensión que le da características de persistencia a algunos objetos de un lenguaje orientado a objetos, o como una extensión que añade características orientación a objetos a un Sistema de Gestión de Bases de Datos.

¿Cuál es la idea?



Nuestro trabajo es diseñar e implementar el modelo de datos OO


¿Impedancia?


Reducir la impedancia entre las nuevas capas de aplicación (Objetos) y el almacenamiento persistente de los datos (Relacional). 

Desarrollo con SGBDR y SGBDOO


Aplicación OO con un SGBDR

Ejemplo 1. Impedancia o acoplamiento

Class.formName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/persona", "root", "");

Statement statement = connection.createStatement();

Persona p = new Persona();
p.setCedula("13556901");
p.setNombre("Pedro Perez");

/* Aquí hay que transformar los datos
 * de un objeto a una sentencia DML
 * en SQL. En este caso es simple,
 * pero se puede volver repetitivo y
 * propenso a errores
 */
String sql = "INSERT INTO t_persona VALUES(" + getNextId(connection) + ", '" + p.getCedula() + "', '" + p.getNombre() + "')";
System.err.println(sql);

statement.execute(sql);

connection.close();

Ejemplo 2. Impedancia o acoplamiento

Class.formName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/persona", "root", "");

Statement statement = connection.createStatement();

ResultSet rs = statement.executeQuery("SELECT * FROM t_persona WHERE cedula='13556901'");

Persona p = null;

/* Nuevamente es necesario transformar
 * los datos resultantes de la consulta
 * a variables u objetos
 */
if (rs.next()){
      p = new Persona(rs.getString("cedula"), rs.getString("nombre"));
      p.setId(rs.getInt("id"));
}
else{
      System.err.println("Persona no encontrada");
}

System.err.println(p.getId() + ";" + p.getCedula() + ";" + p.getNombre());
connection.close();

Ejemplo 3. Orientado a objetos / Mínimo acoplamiento

Session session = CledaConnector.getInstance().getSession();
session.beginTransaction();

Persona p = new Persona();
p.setCedula("13556901");
p.setNombre("Pedro Peréz");

// ¿Qué pasó aquí? ¡No puede ser tan facil!
session.saveOrUpdate(p);

session.getTransaction().commit();
session.close();

La instancia p de tipo persona es persistido automáticamente.

Ejemplo 4. Orientado a Objetos / Mínimo acoplamiento

Session session = CledaConnector.getInstance().getSession();
session.beginTransaction();

Query q = session.createQuery("FROM Persona WHERE cedula=:cedula");
q.setString("cedula", "13556901");

/* La consulta aquí retorna
 * un objeto directamente
 * (Al contrario que SQL)
 */
Persona p = (Persona) q.uniqueResult();
System.err.println(p.getId() + ";" + p.getCedula() + ";" + p.getNombre());

session.getTransaction().commit();
session.close();

El lenguaje de consulta es “parecido” a SQL, usa principios similares, pero es orientado a objetos (en este caso es HQL).

El estándar ODMG-93

Esto lo voy a mencionar más por razones históricas que prácticas.

El reléase 1.1 del estándar del ODMG (Object Database Management Group) es un esfuerzo por estandarizar los conceptos fundamentales de los SGBDOO.

El estándar fue desarrollado entre los años 1993 y 1994 por representantes de un amplio conjunto de empresas relacionadas al desarrollo de software y sistemas orientados a objetos.

El estándar define:

El modelo de objetos

Que incluye y define conceptos de:

  • Interfaces, tipos, implementaciones e instancias (objetos).
  • Atributos / métodos (Comportamiento)
  • Representación de Vínculos entre Tipos (Colecciones / Referencias)
  • Herencia (Jerarquías de Tipos y Clases / Especialización / Generalización / Supertipos / Subtipos)
  • Extensiones de Tipos (Listas de objetos de cierto tipo)
  • Claves de Tipos
  • Identidad de los Objetos (OID)
  • Polimorfismo
  • Encapsulamiento
  • Excepciones
  • Estructura de complejidad arbitraria (vs información dispersa a lo largo de varias relaciones)
  • Persistencia (Objetos que “existe de forma permanente”)
  • Soporta transacciones

Los tipos atómicos no están compuestos de otros objetos, mientras que los estructurados pueden estar compuestos de otros objetos.


Lenguaje de definición de objetos (ODL)

El ODL (Object Definition Language) es un lenguaje usado para definir las interfaces de tipos de objetos. Tiene las siguientes características:
  • Debe soportar todos la semántica del modelo de objetos de la ODMG.
  • No es un lenguaje de programación completo, sólo un lenguaje de especificación de interfaces (y atributos).
  • Debe ser independiente de cualquier lenguaje de programación (independiente de C/C++, Java u otro).
  • Debe ser compatible con IDL (Interface Definition Language).
  • Debe ser simple y práctico, brindar valor a los desarrolladores de aplicaciones.



Un ejemplo de ODL sería

interface Course
(    extent courses
     keys name, number)
{
     attribute String name;
     attribute String number;
     relationship List<Section> has_sections
          inverse Section::is_section_of
          {order_by Section::number};
     relationship Set<Course> has_prerequisites
          inverse Course::is_prerequisite_for;
     relationship Set<Course> is_prerequisite_for
          inverse Course::has_prerequisites;
         
     Boolean offer (in Unsigned Short semester) raises (alredy_offered);
     Boolean drop (in Unsigned Short semester) raises (not_offered);
};

interface Student
(    extent students
     keys name, student_id)
{
     attribute String name;
     attribute String student_id;
     attribute Struct Address{String college, String room_number}
          dorm_address;
     relationship Set<Section> takes inverse Section::is_taken_by;
     Boolean register_for_course (in Unsigned Short course, in      Unsigned Short Section)
          raises (unsatisfied_prerequisites, section_full, course_full);
     void drop_course (in Unsigned Short Course)
          raises (not_registered_for_that_course);
     void assign_major (in Unsigned Short Department);
     Shot transfer (in Unsigned Short old_section, in Unsigned Short new_section)
          raises (section_full, not_registered_in_section);
};

interface Section(
     extent sections
     key(is_section_of, number)
)
{
     attribute String number;
     relationship Professor is_taught_by inverse Professor::teaches;
     relationship TA has_TA inverse TA::assists;
     relationship Course is_section_of inverse Course::has_sections;
     relationship Set<Student> is_taken_by inverse Student::takes;
};

interface Professor: Employee
(    extent professors)
{
     attribute Enum Rank{full, associate, assistant} rank;
     relationship Set<Section> teaches inverse Section::is_taught_by;
     Short grant_tenure () raises (ineligible_for_tenure);
}




Lenguaje de consultas de objetos (OQL)

OQL (Object Query Language) es un lenguaje de consulta orientado a objetos simple y completo con las siguientes características:

  • Es orientado a objetos
  • Declarativo / Abstracto (no es completo desde el punto de vista computacional)
  • Su sintaxis es similar a SQL (que es uno de los lenguajes de consulta más usados en la industria)
  • Acceso declarativo a objetos (propiedades y métodos)
  • Semántica formal bien definida
  • Basado en el modelo de objetos de la ODMG
  • No incluye operaciones de actualización (sólo de consulta)


Algunos ejemplos

select distinct x.edad from x in Personas where x.nombre="Pedro"

select distinct struct(e : x.edad, s : x.sexo)
   from x in Personas where x.nombre="Pedro"
  
select distinct struct(nombre : x.nombre, conjunto_subordinados :
     (select y
       from y in x.subordinados
       where y.salario >100000)
)
from x in Empleados

select struct(e : x.edad, s : x.sexo)
   form x in (select y
               from y in Empleados
                   where y.antiguedad = 10)
   where x.nombre="Pedro"

Otros lenguajes de consulta

Criteria Query

En un query de tipo criteria, la condición se construye encandenando una serie de “átomos” generados por un conjunto de métodos predefinidos.

-- Ejemplo 1

ODB odb = ODBFactory.open(ODB_NAME);

IQuery query = new CriteriaQuery(Sport.class, Where.equal("name", "volley-ball"));

Sport volleyball = (Sport) odb.getObjects(query).getFirst();

query = new CriteriaQuery(Player.class, Where.equal("favoriteSport", volleyBall));
Objects<Player> players = odb.getObjects(query);

int i = 1;

while (players.hasNext()){
      System.out.println((i++) + "\t " + players.next());
}

-- Ejemplo 2

odb.close();

ODB odb = ODBFactory.open(ODB_NAME);

IQuery query = new CriteriaQuery(Player.class, Where.or().add(Where.equal("favoriteSport.name", "volley-ball")).add(Where.like("favoriteSport.name", "%nnis")));

Objects<Player> players = odb.getObjects(query);

int i = 1;

while (players.hasNext()){
      System.out.println((i++) + "\t:" + players.next());
}

odb.close();

-- Ejemplo 3

ODB odb = ODBFactory.open(ODB_NAME);

IQuery query = new CriteriaQuery(Player.class, Where.or().add(Where.equal("favoriteSport.name", "volley-ball")).add(Where.like("favoriteSport.name", "%nnis")));

Objects<Player> players = odb.getObjects(query);

int i = 1;

while (players.hasNext()){
      System.out.println((i++) + "\t: " + players.next());
}

odb.close();

Consultas nativas

-- Ejemplo 1

ODB odb = ODBFactory.open(ODB_NAME);

IQuery query = new SimpleNativeQuery(){
      public boolean match(Player player){
            // Se incluye el objeto si retorna true
            return player.getFavoriteSport().getName().toLowerCase().startWith("volley");
      }
};

Objects<Player> players = odb.getObjects(query);

int i = 1;

while (players.hasNext()){
      System.out.println((i++) + "\t: " + players.next());
}

odb.close();

ODL / OQL / OML. Integración con un Lenguaje de programación

La idea es que el acceso al SGBDOO sea una “extensión” del lenguaje nativo en el que se va a utilizar.


Algunos SGBDOO (Comerciales y Free Software)


Alternativas a los SGBDOO


Mapeo Objeto – Relacional / ORM

Tiene una transformación automática (componente de persistencia).
La correspondencia (mapa) entre las relaciones y los objetos se describe utilizando:
  • XML
  • XDoclet
  • Anotaciones (Dependiente del Lenguaje)
  • Otros

Hay un componente que en base a la descripción de correspondencia genera de forma automática todos los SQL necesarios para consultar y actualizar la base de datos.

El cliente utiliza / consulta / actualiza los objetos persistentes y el ORM se encarga de sincronizar el estado con la Base de Datos.

Desde el punto de vista del cliente es como si usara un SGBDOO.

ORM utilizando Hibernate

Hibernate permite configurar en un archivo .properties la base de datos a la que se desea conectar. Nuevas versiones hacen esto en XML.
Actualmente, además de XML Hibernate permite usar Java Annotations para definir la correspondencia Objeto-Relacional.

Vista general de Hibernate



Arquitectura “full cream” de Hibernate


Objetos de acceso a datos (DAO)

Trasformación manual (Data Transfer Objects (DAO) / Otros)

Se encapsulan las operaciones de acceso a la base de datos implementando un objeto especial (DAO).

La clase DAO implementa métodos para hacer CRUD (Create Read Update Delete) básico.

Adicionalmente, la interfaz DAO implementa métodos para consultas (Ej: findByXXX(…) / listByXXX(…))

Se implementa un TO (Tranfer Object) que contiene la información a almacenar y sirve para interactuar con el DAO.

Se implementa una clase Factory que retorna el DAO adecuado según el tipo de Base de Datos a la que se desea acceder.


En este esquema, DataAccessObject es el responsable de realizar las consultas y las operaciones DML necesarias para mantener el estado de la BD sincronizado con el del objeto, y TransferObject es el objeto que contiene los datos que vienen de (o van a) la Base de Datos.


Este es un caso concreto del patrón de la lámina anterior (para un objeto “Cliente” (Customer) y para “Cloudscape” como Base de Datos (Data Source / Fuente de Datos).


En este nuevo ejemplo, DAOFactory sirve de fábrica para crear los DAOs requeridos según el Modelo a persistir y la fuente de datos específica que se necesite.
La segunda línea de clases son implementaciones concretas de la Fábrica dependiendo de la fuente de datos seleccionada.
La tercera fila de clases son las implementaciones concretas del DAO dependiendo de la fábrica usada seleccionada.
Y por último, CustomerDAO es la interfaz que define las operaciones que se pueden hacer sobre el DAO cliente (Customer).

Algunos productos ORM / DAO Software Libre

0 comentarios:

Publicar un comentario