Abstraccion, ORM y PDO

ORM: (Mapeo Objeto-Relacional – Object-Relational Mapping)

Un ORM es un Mapeo de Objetos a BD Relacionales, consiste en una serie de objetos que permiten acceder a los datos y que contienen en su interior cierta logica de negocio. Apunta a utilizar Objetos en vez de registros y Clases en vez de tablas.

Programar hoy en dia indicando muy explicitamente al tipo de base de datos al que se conectara y trabajara nuestro proyecto, solo podria aceptarse al estar netamente seguros que no se cambiara nunca del gestor de BD y en caso de paginas de poco tamano como proyecto. Pero para sistemas web grandes de empresas que mueven grandes cantidades de datos, la mejor forma de estructura seria abstraer el codigo de la BD.

Las bases de datos (BD) siguen una estructura relacional, para acceder a la BD como si fuera orientada a objetos, es necesario una interfaz que traduzca la logica de los objetos a la logica relacional, esta interfaz es lo que se denomina ORM, el cual es una capa de abstranccion.

Abstraccion: consiste en aislar un elemento de su contexto o del resto de los elementos que lo acompanan.

Con respecto a los ORM, una de las ventajas de utilizar esta capa de abstraccion de objetos/relacional es que evita utilizar una sintaxis especifica de un sistema de BD concreto. Esta capa transforma automaticamente las llamadas a los objetos en consultas SQL optimizadas para el sistema gestor de BD que se esta utilizando en cada momento.

El tema de abstraerse de la BD entra en muchos temas, no solo ORM lo toca, tambien el patron MVC al dividir la codificacion en sus 3 capas, nos permite abstraernos de la BD.

Esto quiere decir que en vez de escribir en el codigo mysql_connect() o mysql_query() y demas funciones afines, lo cual nos amarra a un motor de BD concreto, si en el futuro se cambia a otro gestor de BD, tendremos que cambiar toda esta nomenclatura que apunta al gestor BD previo y ser remplazado por el nuevo, si volviese a cambiarse el tipo de BD volveriamos a lo mismo. Para evitar esto es que recurririamos a una capa de abstraccion que nos abstraiga del gestor de BD.

A partir de PHP5.1 se encuentra PDO el cual nos brinda una POO que nos ayuda a abstraernos del gestor de BD y puede verse su amplia documentacion en la pagina de php.

La sintaxis de PDO de PHP es: $db = new PDO(driver:host=servidor;dbname=bd’, user, pass);

donde driver pondriamos el tipo de BD al cual nos conectariamos, si en el futuro se cambiara de BD simplemente con cambiar el driver, todo el resto del codigo a la BD quedaria igual.

Asi que en vez de escribir: mysql_connect(“localhost”, “usuario”, “password”);

Escribiriamos: $db = new PDO(mysql:host=localhost; dbname=mibasedatos’, ‘usuario’, ‘password’);

Si fuese otro tipo de BD como postgreSQL seria: $db = new PDO(pgsql:dbname=miBD host=localhost’, $user, $pass);

Teniendo entonces en $db una instancia de PDO_MySQL o PDO_PostgreSQL o del gestor de BD al que apuntara la aplicacion sin que su cambio tenga serias repercusiones en el programa.

De igual forma en vez de: mysql_query(‘SELECT * FROM tabla’);

Escribiriamos:  $consulta = $db->prepare(‘SELECT * FROM items’);
$consulta->execute();
while($fila = $consulta->fetch())
{
echo $fila[0] . ‘ ‘ . $fila[1] . ‘<br />’;
}
$db = null;

Asi en vez de: mysql_query(“INSERT INTO tabla (campo VALUES (‘dato’));

Seria:
$dato = $_POST[‘dato’];
$insertar = $db->prepare(‘INSERT INTO tabla (campo) VALUES (:dato)’);
$insertar->bindParam(:campo’, $dato);
$insertar->execute();

En vez de: mysql_query(‘UPDATE tabla SET nombre = $nombre WHERE id = $id’);

Seria:
$nombre = $_POST[‘nombre’];
$id = $_POST[‘id’];
$actualizar = $db->prepare(‘UPDATE tabla SET nombre = :nombre WHERE id = :id’);
$actualizar->bindParam(:nombre’, $nombre);
$actualizar->bindParam(:id’, $id);
$actualizar->execute();

En vez de: mysql_query(‘DELETE * FROM tabla WHERE id=$id’);

Seria:
$id = $_POST[‘id’];
$borrar = $db->prepare(‘DELETE FROM tabla WHERE id = :id’);
$borrar->bindParam(‘:id’, $id);
$borrar->execute();

De esta forma, es muy sencillo cambiar a otro sistema de BD completamente diferente en mitad del desarrollo de un proyecto. Estas tecnicas son utiles cuando se deba de desarrollar un prototipo rapido y el cliente aun no haya decidido el sistema de BD que mas le convenga. El prototipo se puede realizar utilizando SQLite y despues se puede cambiar facilmente a MySQL, PostgreSQL, Oracle, etc. El cambio se puede realizar modificando solamente una linea en un archivo de configuracion, el resto del codigo del proyecto hacia la BD queda igual.

Las claras ventajas de un ORM serian:

  • Ayuda a reducir el tiempo de desarrollo de software.
  • Permite la produccion de mejor codigo (mas organizado/estructurado).
  • Incentivan la portabilidad y escalabilidad de los programas.
  • Independencia de la base de datos.
  • Ofrece seguridad ya que recurre a mecanismos que protegen de la inyeccion SQL.

Desventaja: El desempeno esta ligado a la eficiencia del ORM.

Si no existiese PDO de PHP, tendriamos que abstraernos de la BD por ejemplo, con una idea como esta:

<?php
function crear_conexion($servidor, $usuario, $contrasena)
{
return mysql_connect($servidor, $usuario, $contrasena);
}
function cerrar_conexion($conexion)
{
mysql_close($conexion);
}
function consulta_base_de_datos($consulta, $base_datos, $conexion)
{
mysql_select_db($base_datos, $conexion);
return mysql_query($consulta, $conexion);
}
function obtener_resultados($resultado)
{
return mysql_fetch_array($resultado, MYSQL_ASSOC);
}
?>

Y trabajar con esto de esta forma:

function getTodosLosArticulos()
{
// Conectar con la base de datos
$conexion = crear_conexion(‘localhost’, ‘miusuario’, ‘micontrasena’);
// Ejecutar la consulta SQL
$resultado = consulta_base_de_datos(‘SELECT fecha, titulo FROM articulo’, ‘blog_db’,
$conexion);
// Crear el array de elementos para la capa de la vista
$articulos = array();
while ($fila = obtener_resultados($resultado))
{
$articulos[] = $fila;
}
// Cerrar la conexión
cerrar_conexion($conexion);
return $articulos;
}

En una pagina html tendriamos relacionado a esto:

<h1>Listado de Artículos</h1>
<table>
<tr><th>Fecha</th><th>Título</th></tr>
<?php foreach ($articulos as $articulo): ?>
<tr>
<td><?php echo $articulo[‘fecha’] ?></td>
<td><?php echo $articulo[‘titulo’] ?></td>
</tr>
<?php endforeach; ?>
</table>

Estos ultimos ejemplos fueron tomados del libro de Symfony 1.2 en pdf.


About this entry