2010-10-27 16 views
38

leo en algunos artículos DAO no es obligatorio con hibernación y su implementación es por "depende", en otras palabras, podemos elegir entre ORM vs DAO patrón.Patrón DAO vs ORM (hibernación)

Ok, supongamos que no quiero utilizar un patrón DAO, por lo que estoy usando solo la sesión CRUD y la operación de consulta proporcionada por hibernate (mi ORM).

Especialmente para las consultas "buscar" y "buscar" no es correcto reescribirlas siempre, por lo que es razonable pensar en ponerlas en una clase.

Pero esta clase es un DAO simple sin toda la implementación del patrón DAO y DAOFactory, solo una implementación liviana de un DAO. Entonces, ¿el punto es que necesitamos siempre un DAO y la elección es una implementación de DAO pesada frente a la implementación de DAO ligero?

Lo que dije es incorrecto?

EDITAR Otro problema que tengo es que las interacciones poner Dao, por ejemplo, tengo que iniciar sesión un usuario y escribir un registro de la sesión (ejemplo inútiles sé ...)

Así que en un DAO patrón tengo todas las implementaciones dao genéricas, una DAOFactory y finalmente UserHibernateDAO y LogHibernateDAO. La operación de inicio de sesión es un método negocio:

private void login(String username, String password){ 
    daoFactory.beginTransaction(); 
    UserDAO userDao=daoFactory.HIBERNATE.getUserDao(); 
    LogDAO logDao=daoFactory.HIBERNATE.getLogDao(); 
    if(userDao.checkAccount(username, password){ 
     User user=userDao.findByAccount(username, password); 
     logDao.save(new Log("log-in", user); 
    } 
    daoFactory.commit(); 
} 

Es esto razonable? ¿Puedo usar dao de esta manera? Si quiero una excepción de manejo, ¿el mejor lugar para hacerlo es una lógica comercial?

Edit2 Supongamos utilizar un patrón DAO, la razón principal para hacerlo es ser capaz de cambiar entre Tecnhology (ORM-> JDBC, etc ..), todo bien y bien, pero ¿dónde puedo manejar la sesión de hibernación y la transacción? No puedo ponerlo en un DAO, es un patrón anty, y no puedo ponerlo en una capa de servicio, ya que en un conmutador hipohtetycal tengo que eliminar toda esta transacción (porque es posible que otras tecnologías no las usen).

+0

posible duplicado de [Encontré JPA, o similar, no aliento el patrón DAO] (http://stackoverflow.com/questions/2100115/i-found-jpa-or-alike-dont-encourage-dao- patrón) – Bozho

+0

Tal vez verifique mi publicación en el blog sobre eso. Propongo cómo combinar JPA con el patrón DAO de la manera más directa y SECA posible: http://codeblock.engio.net/?p=180 – bennidi

Respuesta

68

ORM y DAO son conceptos ortogonales. Uno tiene que ver con la forma en que los objetos se asignan a las tablas de la base de datos, el otro es un patrón de diseño para escribir objetos que acceden a los datos. No eliges 'entre' ellos. Puede tener ORM y DAO es la misma aplicación, del mismo modo que no necesita ORM para usar el patrón DAO.

Dicho esto, aunque en realidad nunca necesita nada, debe usar DAO. El patrón se presta a código modularizado. Mantiene toda su lógica de persistencia en un solo lugar (separación de preocupaciones, lucha contra las abstracciones con fugas). Se permite probar el acceso a los datos por separado del resto de la aplicación. Y se permite probar el resto de la aplicación aislada del acceso a datos (es decir, puede burlarse de sus DAO).

Además, seguir el patrón DAO es fácil, incluso si implementar el acceso a los datos puede ser difícil. Entonces te cuesta muy poco (o nada) y ganas mucho.

EDITAR - Con respecto a su ejemplo, su método de inicio de sesión debe ser en algún tipo de servicio de autenticación. Puede manejar excepciones allí (en el método de inicio de sesión). Si usó Spring, podría administrar varias cosas para usted: (1) transacciones, (2) inyección de dependencia. No necesitaría escribir sus propias transacciones o fábricas dao, podría simplemente definir límites de transacciones en torno a sus métodos de servicio, y definir sus implementaciones DAO como beans y luego conectarlas a su servicio.

Edit2

La razón principal para usar el patrón es separar preocupaciones. Eso significa que todo su código de persistencia está en un solo lugar. Un efecto colateral de esto es la capacidad de prueba y mantenimiento, y el hecho de que esto hace que sea más fácil cambiar las implementaciones más tarde. Si está construyendo DAO basados ​​en Hibernate, puede manipular absolutamente la sesión en el DAO, eso es lo que se supone que debe hacer. El patrón anti es cuando el código relacionado con la persistencia ocurre fuera de la capa de persistencia (ley de abstracciones con fugas).

Las transacciones son un poco más complicadas. A primera vista, las transacciones pueden parecer una preocupación de la persistencia, y lo son. Pero no son solo una preocupación de persistencia. Las transacciones también son una preocupación de sus servicios, ya que sus métodos de servicio deben definir una 'unidad de trabajo', lo que significa que todo lo que sucede en un método de servicio debe ser atómico. Si usa transacciones de hibernación, entonces tendrá que escribir el código de transacción de hibernación fuera de sus DAO, para definir límites de transacción en torno a los servicios que utilizan muchos métodos DAO.

Pero tenga en cuenta que las transacciones pueden ser independientes de su implementación: necesita transacciones ya sea que use hibernate o no. También tenga en cuenta que no necesita utilizar la maquinaria de transacción de hibernación: puede usar transacciones basadas en contenedores, transacciones de JTA, etc.

Sin duda, si no utiliza Spring o algo similar, las transacciones se llevarán a cabo ser un dolor Recomiendo utilizar Spring para administrar sus transacciones, o las especificaciones de EJB donde creo cree que puede definir transacciones alrededor de sus servicios con anotaciones.

Consulte los siguientes enlaces, para transacciones basadas en contenedores.

Container-Managed Transactions

Sessions And Transactions

Lo que estoy recogiendo de esto es que se puede definir fácilmente las transacciones fuera de los DAOs al nivel de servicio, y que no es necesario escribir ningún código de transacción.

Otra alternativa (menos elegante) es poner todas las unidades de trabajo atómicas dentro de los DAO. Podría tener DAO CRUD para las operaciones simples, y luego DAOs más complicados que realicen más de una operación CRUD. De esta forma, sus transacciones programáticas permanecen en el DAO, y sus servicios llamarían a los DAO más complicados y no tendrían que preocuparse por las transacciones.

El siguiente enlace es un buen ejemplo de cómo el patrón DAO puede ayudar a simplificar el código

AO vs ORM(hibernate) pattern

(Gracias @daff)

Aviso cómo la definición de la interfaz hace que sea para que su lógica comercial solo se preocupa por el comportamiento del UserDao. No le importa la implementación. Puede escribir un DAO usando hibernación, o solo JDBC. Entonces puede cambiar su implementación de acceso a datos sin afectar el resto de su programa.

+0

está bien, pero si decido no utilizar el patrón DAO, ¿cómo debo proceder? ? en otras palabras, con Hibernate y WITHOUT DAO, donde puse mi entidad lógica CRUD y HQL consultas o consultas de criterios, etc ...? – blow

+1

@blow, ese es todo el punto. Tienes que poner el código de persistencia en algún lugar. Y debes mantenerlo separado de la lógica comercial de tu aplicación. Entonces, ¿por qué no ponerlo en un DAO? En otras palabras, vas a escribir un DAO, la pregunta es, ¿vas a seguir el patrón? – hvgotcodes

+0

gracias por la explicación, en este momento no quiero usar la primavera para administrar DAO, primero quiero saber cómo funciona el patrón DAO y si realmente lo necesito. PS. Tengo otra pequeña duda, he editado la primera pregunta. – blow

11

No, no creo que sea correcto. ORM es una forma de implementar DAO; puede elegir hacer DAO sin ORM.

Lo tienes al revés: consideraría que ORM es más pesado que DAO, porque las dependencias son mayores. Puedo escribir un DAO en JDBC directo sin ORM. Eso es más ligero, IMO.

Si estamos de acuerdo depende de cómo definamos "ligero" y "pesado". Estoy pasando por dependencias: la cantidad de JAR adicionales necesarios por encima del propio JDK.

25

Permítanme ofrecer un ejemplo de código fuente a hvgotcodes buena respuesta:

public class Application 
{ 
    private UserDao userDao; 

    public Application(UserDao dao) 
    { 
     // Get the actual implementation 
     // e.g. through dependency injection 
     this.userDao = dao; 
    } 

    public void login() 
    { 
     // No matter from where 
     User = userDao.findByUsername("Dummy"); 
    } 
} 


public interface UserDao 
{ 
    User findByUsername(String name); 
} 

public class HibernateUserDao implements UserDao 
{ 
    public User findByUsername(String name) 
    { 
     // Do some Hibernate specific stuff 
     this.session.createQuery... 
    } 
} 

public class SqlUserDao implements UserDao 
{ 
    public User findByUsername(String name) 
    { 
     String query = "SELECT * FROM users WHERE name = '" + name + "'"; 
     // Execute SQL query and do mapping to the object 
    } 
} 

public class LdapUserDao implements UserDao 
{ 
    public User findByUsername(String name) 
    { 
     // Get this from LDAP directory 
    } 
} 

public class NoSqlUserDao implements UserDao 
{ 
    public User findByUsername(String name) 
    { 
     // Do something with e.g. couchdb 
     ViewResults resultAdHoc = db.adhoc("function (doc) { if (doc.name=='" + name + "') { return doc; }}"); 
     // Map the result document to user 
    } 
} 

Así, como ya se ha mencionado, DAO es un patrón de diseño para minimizar el acoplamiento entre su aplicación y backend mientras que ofertas de ORM con la forma de asigna objetos a una base de datos objeto-relacional (que reduce el acoplamiento entre la base de datos y su aplicación, pero al final, sin usar un DAO su aplicación dependería del ORM utilizado o en un nivel superior un estándar como JPA)

Por lo tanto, sin DAO, sería muy difícil cambiar su aplicación (por ejemplo, pasar a una base de datos NoSQL en lugar de un ORM compatible con JPA).

+0

gracias a Daff, tu ejemplo es muy claro. usted dice "sin usar un DAO, su aplicación dependería del ORM utilizado o en un nivel superior, un estándar como JPA", vale, pero necesito escribir un DAO simple de todos modos, puedo llamar con otro nombre como UserService o UserManager o UserSessionfacade, pero es un DAO simple ... Por lo tanto, la elección real es entre una implementación real de un DAO con algunos beneficios, o un simple DAO de hibernación que incapsule toda mi operación CRUD o consultas para una entidad determinada. – blow

+0

ejemplo bueno y simple ... – hvgotcodes

+0

THanks. @blow: si está utilizando un enfoque de aplicación basado en servicios, puede ver sus servicios como DAO y, si no necesita otro nivel de abstracción, no necesita los DAO intermedios. En aplicaciones más grandes, por lo general, dejo que los servicios manejen las sesiones y la gestión de transacciones y redirijan el trabajo real a los DAO. Pero eso depende. – Daff

Cuestiones relacionadas