46 votes

Modèle DAO vs ORM (hibernation)

j'ai lu dans certains articles de DAO n'est pas obligatoire avec hibernate et de sa mise en œuvre est par "ça dépend", en d'autres termes, on peut choisir entre les ORM vs DAO modèle.

Ok, supposons que je ne veux pas utiliser un pattern DAO, donc im à l'aide de la seule session CRUD de requête et de fonctionnement d'hibernate(mon ORM).

En particulier pour la "recherche" et "trouver" des requêtes n'est pas correct de les réécrire toujours, est donc raisonnable de penser à les mettre dans une classe.

Mais alors que cette classe est un simple DAO sans la mise en œuvre de DAO modèle et DAOFactory, seulement une légère mise en œuvre d'un DAO. Donc, le point est que nous devons toujours un DAO et le choix est lourd de DAO de mise en œuvre de vs léger DAO mise en œuvre?

Ce que j'ai dit est faux?

MODIFIER Un autre problème que j'ai est où mettre dao interactions, par exemple, j'ai un login d'un Utilisateur et d'écrire un Journal de la connexion (inutile exemple, je sais...)

Ainsi, dans un DAO modèle que j'ai tous les génériques de dao implémentations, un DAOFactory et enfin UserHibernateDAO et LogHibernateDAO. Le login est une méthode commerciale:

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();
}

Est-ce raisonnable? Puis-je utiliser dao de cette façon? Si je veux gérer l'exception, le meilleur endroit pour le faire est de l'ina, à une logique d'entreprise?

EDIT2 Supposons d'utiliser un pattern DAO, la principale raison de le faire est d'être en mesure de basculer entre tecnhology(ORM->JDBC etc..), toute fine et ok, MAIS où puis-je gérer la session hibernate et de transaction? Je ne peux pas le mettre dans un DAO, c'est anty modèle, et je ne peux pas le mettre dans une couche de service, parce que dans un hipohtetycal switch je dois enlever toutes cette opération(parce que les autres tecnhology ne peut pas les utiliser).

76voto

hvgotcodes Points 55375

L'ORM et DAO sont orthogonaux concepts. On a à faire avec la façon dont les objets sont mappés à des tables de base de données, l'autre est un modèle de conception pour l'écriture des objets d'accès aux données. Vous ne choisissez pas "entre" eux. Vous pouvez avoir l'ORM et DAO est la même, tout comme vous n'avez pas besoin d'un ORM pour utiliser le pattern DAO.

Cela dit, alors que vous n'avez jamais vraiment besoin de quelque chose, vous devez utiliser des DAOs. Le modèle se prête à la modularité du code. Vous conservez tous vos persistance de la logique en un seul endroit (la séparation des préoccupations, la lutte abstractions qui fuient). Vous vous permettez de test d'accès aux données séparément du reste de l'application. Et vous vous permettez de tester le reste de l'application isolées à partir des données d'accès, vous pouvez vous moquer de votre DAOs).

De Plus, à la suite de la DAO motif est facile, même si la mise en œuvre de l'accès aux données peut être difficile. Donc, il vous en coûte très peu (ou rien) et vous gagnez beaucoup.

EDIT -- Quant à votre exemple, votre méthode de connexion doit être dans une sorte de AuthenticationService. Vous pouvez gérer les exceptions il y a (dans la méthode de login). Si vous avez utilisé le Printemps, qu'il pouvait gérer un tas de choses pour vous: (1) les transactions, (2) l'injection de dépendance. Vous n'auriez pas besoin d'écrire vos propres opérations ou dao usines, vous avez juste à définir les limites de transaction autour de votre service méthodes, et de définir votre DAO implémentations de haricots et puis de fil à votre service.

EDIT2

La raison principale de l'utilisation du modèle à deux questions distinctes. Cela signifie que tout votre code de persistance est en un seul endroit. Un effet secondaire de ceci est, la testabilité et la facilité de maintenance, et le fait qu'il est plus facile de passer des implémentations plus tard. Si vous êtes à la construction d'Hibernate en fonction DAOs, vous pouvez absolument manipuler la session dans le DAO, c'est ce que vous êtes censé faire. L'anti-modèle, c'est quand persistance relative de code qui se passe à l'extérieur de la couche de persistance (loi des abstractions qui fuient).

Les Transactions sont un peu plus compliqué. Au premier coup d'œil, les transactions peut sembler être une préoccupation de la persistance, et ils le sont. Mais ils ne sont pas seulement une préoccupation de la persistance. Les Transactions sont également une préoccupation de vos services, de vos méthodes de service doit définir une "unité de travail", ce qui signifie, tout ce qui se passe dans un service méthode doit être atomique. Si vous utiliser hibernate transactions, alors vous allez avoir à écrire hibernate code de transaction à l'extérieur de votre DAOs, de définir les limites de transaction autour des services qui utilisent de nombreuses méthodes DAO.

Mais note que les transactions peuvent être indépendants de l'implémentation-vous avez besoin de transactions que vous utilisiez ou non mise en veille prolongée. Notez également que vous n'avez pas besoin d'utiliser la veille prolongée opération de machines, vous pouvez l'utiliser dans des conteneurs de transactions, de transactions JTA, etc.

Aucun doute que si vous n'utilisez pas de Printemps ou quelque chose de similaire, les transactions sont va être une douleur. Je recommande fortement d'utiliser le Printemps pour gérer vos transactions, ou les EJB spec où je crois que vous pouvez définir des transactions autour de vos services avec les annotations.

Consultez les liens suivants, pour conteneur de base de transactions.

Container-Managed Transactions

Des Sessions Et Les Transactions

Ce que je suis la collecte de ceci est que vous pouvez facilement définir les opérations à l'extérieur de la DAOs au niveau du service, et vous n'avez pas besoin d'écrire de code de transaction.

Un autre (moins élégant) alternative est de placer toutes les unités atomiques de travail dans les DAOs. Vous pourriez avoir CRUD DAOs pour les opérations simples, puis plus complexes DAOs qui ne sont plus de l'une des opérations CRUD. De cette façon, votre programmatique opérations de rester dans le DAO, et vos services pourrait appeler le plus compliqué DAOs, et ne pas avoir à vous soucier de la transaction.

Le lien suivant est un bon exemple de la façon dont le DAO de patron peut vous aider à simplifier le code

AO vs ORM(hibernate) modèle

(merci @daff)

Remarquez comment la définition de l'interface qu'il fait en sorte que vous avez une logique d'entreprise se soucie uniquement de la comportement de la UserDao. Il ne s'occupe pas de la mise en œuvre. Vous pourriez écrire un DAO de l'utilisation d'hibernate, ou tout simplement jdbc. Ainsi, vous pouvez modifier vos données d'accès mise en œuvre sans affecter le reste de votre programme.

32voto

Daff Points 22358

Permettez-moi de fournir un exemple de code source pour hvgotcodes bonne réponse:

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
    }
}

Donc, comme déjà mentionné, DAO est un modèle de conception afin de minimiser le couplage entre votre application et vous backend alors que l'ORM traite de la façon de les objets de la carte en un objet de base de données relationnel (ce qui réduit le couplage entre la base de données et vous demande, mais à la fin, sans l'aide de DAO votre demande sera dependend sur l'ORM utilisé ou à un niveau supérieur un standard comme JPA).

Par conséquent, sans DAOs, il serait vraiment difficile de changer votre application (par exemple, le déplacement d'une base de données NoSQL au lieu d'une APP compatible ORM).

12voto

duffymo Points 188155

Non, je ne pense pas que ce soit correct. ORM est une façon d'implémenter DAO; vous pouvez choisir de faire DAO sans ORM.

Vous l'avez à l'envers: je considérerais ORM plus lourd que DAO, car les dépendances sont plus importantes. Je peux écrire un DAO en JDBC droit sans ORM. C'est plus léger, OMI.

Que nous soyons d'accord ou non dépend de la façon dont nous définissons «léger» et «lourd». Je vais par dépendances - le nombre de fichiers JAR supplémentaires requis au-dessus du JDK lui-même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X