ORMs vs MicroORMs vs ADO.NET: Cuándo usar cada uno

A raíz de mi último post en el que comparaba el rendimiento de NHibernate y Dapper, surgió una entretenida discusión en Twitter sobre si usar o no ORMs. Como Twitter no es el mejor medio para discutir cosas complicadas, me ha parecido más cómodo escribir este post para explicar mi postura y así la próxima vez sólo tengo que twittear un enlace.

Cuándo usar un ORM

Por definición un ORM es una herramienta que permite mapear un modelo relacional a un modelo de objetos. Eso implica que para que tenga sentido usar un ORM necesitamos dos cosas: un modelo relacional y un modelo de objetos.

Puede parece una tontería, pero es que muchas veces no se tiene (ni se necesita) un modelo real de objetos, sino simplemente una representación directa de las tablas, con clases que sólo actúan como meros contenedores de datos y sin apenas relaciones entre sí.

Aunque hay ocasiones que se ve el ORM como algo que simplemente evita escribir sentencias SQL y escribir código para mover datos de un DataReader a nuestros objetos, un ORM es mucho más que eso.

Una de las características más importantes de todo ORM que se precie es la implementación del identity map, que nos garantiza que cuando cargamos dos veces una misma entidad desde la base de datos obtenemos el mismo objeto.

El otro aspecto fundamental de un ORM es la gestión del Unit of Work, que nos permite trabajar con los objetos en memoria y hacer el seguimiento de los cambios que hemos realizado.

Además de esto, el ORM nos facilita la navegación por las relaciones entre entidades con técnicas como lazy load o utilizando distintas estrategias de carga de datos para optimizar el número de consultas lanzadas a la base de datos. También nos ofrece funcionalidades muy útiles como persistencia por alcance y seguimiento de cambios.

Todo esto no es gratis e introduce una complejidad adicional en la aplicación, por lo que si no hay un modelo real de objetos, puede no merecer la pena.

Lo que nunca puedes olvidar es que por mucho ORM que tengas, al final estás tratando con una base de datos y eso impone ciertas restricciones a la hora de trabajar con el ORM. Aunque tengamos la ilusión de que estamos tratando con objetos, la base de datos sigue ahí y no puedes olvidarte por completo de ella. Este es el motivo de que mucha gente considere el ORM como una leaky abstraction.

Como ya he dicho en otras ocasiones, utilizar un framework para aumentar el nivel de abstracción no te exime de comprender aquello que se está abstrayendo. Si usas un ORM pensando que no hay base de datos, se volverá en tu contra.

Cuándo usar un MicroORM

Antes de nada, quiero dejar claro que no me gusta el término MicroORM, porque realmente no se trata de un ORM. Si un ORM se encarga de salvar la impedancia entre dos modelos, un MicroORM lo único que hace es mover datos de un sitio a otro, pero usando el mismo modelo. Más que un ORM, un MicroORM es un DataMapper.

Dejando de lado la nomenclatura, un MicroORM también tiene su utilidad. Hay aplicaciones en las cuales no tiene sentido crear un modelo complejo de objetos y podemos limitarnos a replicar el modelo relacional en memoria. Para este tipo de aplicaciones, un MicroORM, o incluso Active Record, es una buena salida porque nos permite evitar código repetitivo y genera por nosotros gran parte de las sentencias SQL para leer y escribir en la base de datos.

En un MicroORM generalmente no tenemos implementación del identity map y, si existe, la implementación de Unit Of Work es bastante más básica que la de un ORM completo.

Esta reducción en funcionalidades tiene sus ventajas. Un MicroORM es mucho más ligero que un ORM y suele estar más optimizado, ofreciéndonos un rendimiento muy bueno, prácticamente igual que ADO.NET.

Además su API es más limpia y es muy fácil de utilizar, aunque a cambio tendremos que hacer más cosas a mano, sobre todo por no tener seguimiento de cambios ni navegación por las relaciones de los objetos.

Cuándo usar ADO.NET

Otra alternativa es tirar por la calle de en medio y no emplear ninguna librería, sino usar directamente ADO.NET. La ventaja es que evitas tener más dependencias y puedes exprimir al máximo el rendimiento.

Sin embargo, usar ADO.NET me parece una pérdida de tiempo en la mayoría de los casos. Está claro que si tienes una aplicación sumamente sencilla que sólo usa una o dos tablas, es una opción viable, pero en cuanto la aplicación tiene un número razonable de tablas, resulta poco rentable.

Al final la mejora de rendimiento no es tan grande y el trabajo adicional que hay que realizar es aburrido y aporta poco valor.

Una situación bastante frecuente es empezar usando ADO.NET y acabar implementando nuestro propio pseudo MicroORM. Cuando uno ha escrito 15 veces el mismo código para pasar datos de un DataReader a objetos, empieza a plantearse si no se podría hacer por reflection, o mejor aún usando generación dinámica de código para no perder eficiencia y al final… pues al final te has implementado tu propio Dapper.

No me malinterpretéis, a veces está bien reinventar la rueda (yo lo acabo de hacer con TinyTwitter), pero no hay que olvidar el objetivo es aportar valor al negocio, no implementar capas de acceso a datos (a menos que ese sea tu negocio o sea un aspecto crítico del mismo).

Conclusión

A los desarrolladores nos suele gustar mucho hacer analogías con herramientas físicas y hablamos de martillos para los que todo son clavos o de navajas suizas.

Es muy importante entender que ninguna de las técnicas, ni ORMs, ni DataMappers, ni ADO.NET, es una navaja suiza que nos sirva para todo, pero sí podemos verlas como distintas hojas de una misma navaja suiza para resolver nuestras necesidades de acceso a datos.


5 comentarios en “ORMs vs MicroORMs vs ADO.NET: Cuándo usar cada uno

  1. Interesante artículo.

    Parece que las alternativas a acceso a datos son MicroORMs , Entity Framework (ORM), ADO.NET. Y obsoleto quedó Linq to Sql.

  2. kiquenet, tienes otros ORMs que funcionan muy bien, como NHibernate. Aunque no tenga soporte para algunas de las cosas más “modernas”, sigue siendo muy superior a Entity Framework en algunas áreas.

  3. Bueno muy bien explicado, pero hay personas que en verdad no investigan, no me lo tomen a mal, pero si se compara el performance de linq con dapper, pues me voy por dapper, ya que en la vida real lo que el usuario final quiere rapidez.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>