Si eres un desarrollador de aplicaciones multiplataforma, seguramente, alguna vez has programado una aplicación que se conecta a una base de datos.
Realizar el mapeo, que no es otra cosa que transformar la información de la base de datos en tablas a objetos de la aplicación y viceversa, es un arduo trabajo y realizar acceso a datos desde un lenguaje orientado a objetos (POO) como pueden ser .NET o Java, era necesario mezclar código y conceptos muy diferentes.
Por un lado teníamos la aplicación en sí,
escrita en alguno de estos lenguajes como Java o C#. Dentro de éste programa
hacíamos uso de ciertos objetos especializados en conectarse
con bases de datos y lanzar consultas contra ellas. Estos objetos de tipo Connection
, Query
y similares,
eran en realidad conceptos de la base de datos llevados a un programa orientado
a objetos que no tenía nada que ver con ellos. Finalmente, para lanzar
consultas (tanto de obtención de datos como de modificación o de gestión) se
introducían instrucciones en lenguaje SQL, en forma de cadenas
de texto, a través de estos objetos.
El ORM es un modelo de programación que transforma las tablas de una base de datos en entidades para simplificar enormemente la tarea del programador.
Las complejidades del modelo tradicional
Desarrollar aplicaciones web, desktop o móviles que tengan persistencia de datos ha tenido durante mucho tiempo ciertas complejidades, entre las que resaltamos las siguientes:
- Tipos de dato: En base de datos manejamos tipos de datos, muchas veces estos tipos de dato tienen una particularidad específica como podría ser el manejo de fechas, que no siempre es fácil de trabajar en un entorno de la aplicación.
- Valores nulos: Muchas veces manejamos el valor null de algún tipo de datos, pero por ejemplo si definimos un tipo de dato entero en base de datos y el valor es null en base de datos esto no tiene mayor problema, pero si vamos a mapear por ejemplo este valor en una variable de tipo int primitivo que no puede tener valores nulos, podríamos tener inconsistencia de información, ya que la particularidad del lenguaje podría inducir error en nuestra aplicación.
- Procedimientos o funciones: Si deseamos brindar soporte de este tipo de función propia de base de datos, se debe adecuar la aplicación, lo que conlleva tiempo.
- desfase de impedancia: Son las diferencias entre conceptos, tipos de datos, y modos de trabajar pueden causar muchos problemas y agregarle complejidad a nuestra aplicación.
Los mapeadores al rescate
Como acabamos de ver, lo ideal en una aplicación escrita en un lenguaje orientado a objetos sería definir una serie de clases, propiedades de éstas que hagan referencia a las otras, y trabajar de modo natural con ellas.
¿Qué quieres una factura? Simplemente instancias un objeto Factura
pasándole
su número de factura al constructor. ¿Necesitas sus líneas de detalle? LLamas a
la propiedad Lineas
del objeto. ¿Quieres ver los datos de un producto que está en una de
esas líneas? Solo lee la propiedad correspondiente y tendrás la información a
tu alcance. Nada de consultas, nada de relaciones, de claves foráneas…
Eso precisamente es lo que intenta conseguir el software llamado ORM, del inglés Object-Relational Mapper o «Mapeador» de relacional a objetos (y viceversa). Un ORM es una biblioteca especializada en acceso a datos que genera por ti todo lo necesario para conseguir esa abstracción de la que hemos hablado.
Que ORM’s existen para cada lenguaje?
- En Java el ORM más conocido y utilizado es Hibernate que pertenece a Red Hat aunque es gratuito y Open Source. Hay muchos otros como Jooq, ActiveJDBC que trata de emular los Active Records de Ruby On Rails, o QueryDSL, pero en realidad ninguno llega ni por asomo al nivel de uso de Hibernate. Si necesitas un ORM en Java debes aprender Hibernate, y luego ya si quieres te metes con otro, pero este es indispensable
- En la plataforma .NET tienes varios conocidos, pero el más popular y utilizado es Entity Framework o EF, que es el creado por la propia Microsoft y que viene incluido en la plataforma .NET (tanto en la «tradicional» como en .NET Core). También existe un «port» de Hibernate para .NET llamado NHibernate y que a mucha gente le gusta más que EF. Hay otros como Dapper que está creado por la gente de Stack Exchange y es mucho más sencillo que los anteriores, lo cual es considerado una gran virtud por mucha gente (entre los que me incluyo), y también es muy utilizado. Y es muy conocido Subsonic, que lleva casi diez años en activo pero que puede llegar a ser bastante complicado (a mí personalmente no me gusta nada).
- En PHP tienes Doctrine, tal vez el más conocido y recomendado (utilizado por el framework Symfony), pero también se usan bastante Propel, RedbeanPHP y uno muy popular pero ya en desuso es Xyster (pero te lo encontrarás aún bastante por ahí).
- En Python el híper-conocido framework Django (así sinónimo de desarrollo web con este lenguaje) incluye su propio ORM, pero también tenemos SQLAlchemy por el que muchos beben los vientos y lo califican como el mejor ORM jamás hecho (no tengo experiencia con él como para saberlo). También están Peewee o Pony ORM entre otros.
Prácticamente todas las plataformas tienen el suyo, así que búscalos para la tuya y mira cuál es el más popular y el que más comunidad reúne.
Ventajas y desventajas de un ORM
Los ORM ofrecen enormes ventajas, como ya hemos visto, al reducir esa «impedancia» que impide el buen flujo de información entre los dos paradigmas POO-Relacional. Pero además:
- No tienes que escribir código SQL, algo que muchos programadores no dominan y que es bastante complejo y propenso a errores. Ya lo hacen por nosotros los ORM.
- Te dejan sacar partido a las bondades de la programación orientada a objetos, incluyendo por supuesto la herencia, lo cual da mucho juego para hacer cosas.
- Nos permiten aumentar la reutilización del código y mejorar el mantenimiento del mismo, ya que tenemos un único modelo en un único lugar, que podemos reutilizar en toda la aplicación, y sin mezclar consultas con código o mantener sincronizados los cambios de la base de datos con el modelo y viceversa.
- Mayor seguridad, ya que se ocupan automáticamente de higienizar los datos que llegan, evitando posibles ataques de inyección SQL y similares.
- Hacen muchas cosas por nosotros: desde el acceso a los datos (lo obvio), hasta la conversión de tipos o la internacionalización del modelo de datos.
Pero no todo va a ser alegría. También tienen sus inconvenientes:
- Para empezar pueden llegar a ser muy complejos. Por ejemplo, NHibernate tiene ya más de medio millón de líneas de código ahora mismo, y muchas clases y detalles que hay que saber. Eso hace que su aprendizaje sea complejo en muchos casos, y hay que invertir tiempo en aprenderlos y practicar con ellos hasta tener seguridad en su manejo diario.
- Puede llevar una curva de aprendizaje que podría retrasar el tiempo de desarrollo del proyecto.
- Se necesita alta estandarización de código y una buena arquitectura de la aplicación.
Conclusiones
En definitiva los ORM agregan ventajas y desventajas al desarrollo del software, pero ¿Cuándo se debe utilizar uno u otro?
Si tu proyecto tiene un requerimiento de escalabilidad (bastante grande en tiempo) deberías aplicar un ORM. Haciendo mension a la frace de un amigo y compáñero de trabajo, aplicar un ORM a un proyecto pequeño es como «matar una mosca con un misil balístico».