Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DAO与ORM(hibernate)模式_Java_Hibernate_Design Patterns_Dao - Fatal编程技术网

Java DAO与ORM(hibernate)模式

Java DAO与ORM(hibernate)模式,java,hibernate,design-patterns,dao,Java,Hibernate,Design Patterns,Dao,我在一些文章中读到,对于hibernate,DAO不是强制性的,它的实现是“依情况而定”的,换句话说,我们可以在ORM和DAO模式之间进行选择 好的,假设我不想使用DAO模式,所以我只使用hibernate(我的ORM)提供的会话CRUD和查询操作 特别是对于“搜索”和“查找”查询,总是重写它们是不正确的,因此有理由将它们放入一个类中 但是这个类是一个简单的DAO,没有DAO模式和DAOFactory的所有实现,只有DAO的轻量级实现。 所以,关键是我们总是需要一个DAO,选择重DAO实现还是轻

我在一些文章中读到,对于hibernate,DAO不是强制性的,它的实现是“依情况而定”的,换句话说,我们可以在ORM和DAO模式之间进行选择

好的,假设我不想使用DAO模式,所以我只使用hibernate(我的ORM)提供的会话CRUD和查询操作

特别是对于“搜索”和“查找”查询,总是重写它们是不正确的,因此有理由将它们放入一个类中

但是这个类是一个简单的DAO,没有DAO模式和DAOFactory的所有实现,只有DAO的轻量级实现。 所以,关键是我们总是需要一个DAO,选择重DAO实现还是轻DAO实现

我说的不对

编辑 我遇到的另一个问题是如何放置dao交互,例如,我必须登录一个用户并编写登录日志(我知道的无用示例…)

所以在DAO模式中,我有所有通用的DAO实现,一个DAOFactory,最后是UserHibernateDAO和LogHibernateDAO。 登录操作是一种业务方法

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();
}
这合理吗?我可以这样用刀吗? 如果我想处理异常,最好的方法是在业务逻辑中处理

EDIT2 让我们假设使用DAO模式,这样做的主要原因是能够在技术(ORM->JDBC等)之间切换,这一切都很好,但我在哪里可以处理hibernate会话和事务?
我不能把它放进DAO,它是anty模式,我不能把它放进服务层,因为在hipohtetycal交换机中,我必须删除所有事务(因为其他技术可能不使用它们)。

不,我认为这不正确。ORM是实现DAO的一种方法;您可以选择在没有ORM的情况下使用DAO

<>你把它反了:我认为ORM比DAO重,因为依赖性更大。我可以在没有ORM的情况下直接用JDBC编写DAO。我想那更轻


我们是否同意取决于我们如何定义“轻”和“重”。我按照依赖关系来做——JDK本身之上需要的额外JAR的数量。

ORM和DAO是正交的概念。一个与对象如何映射到数据库表有关,另一个是用于写入访问数据的对象的设计模式。你不能在他们之间选择。您可以让ORM和DAO是同一个应用程序,就像您不需要ORM来使用DAO模式一样

这就是说,虽然您从来没有真正需要任何东西,但您应该使用DAO。该模式适合于模块化代码。您将所有的持久性逻辑都放在一个地方(分离关注点,对抗泄漏的抽象)。您允许自己独立于应用程序的其余部分测试数据访问。您还允许自己测试与数据访问隔离的应用程序的其余部分(即,您可以模拟DAO)

此外,遵循DAO模式很容易,即使实现数据访问可能很困难。因此,它花费你很少(或没有),你收获很多

编辑-- 关于您的示例,您的登录方法应该在某种AuthenticationService中。您可以在那里处理异常(在登录方法中)。如果您使用Spring,它可以为您管理很多事情:(1)事务,(2)依赖注入。您不需要编写自己的事务或dao工厂,只需围绕服务方法定义事务边界,将dao实现定义为bean,然后将它们连接到服务中

EDIT2

使用该模式的主要原因是分离关注点。这意味着您的所有持久性代码都在一个地方。这样做的一个副作用是测试能力和可维护性,这使得以后更容易切换实现。如果您正在构建基于Hibernate的DAO,您完全可以在DAO中操纵会话,这就是您应该做的。反模式是当持久性相关代码发生在持久性层之外时(泄漏抽象法则)

交易有点棘手。乍一看,事务似乎是持久性的一个关注点,而且它们是持久性的。但它们不仅仅是一个持久性问题。事务也是您的服务关注的问题,因为您的服务方法应该定义一个“工作单元”,这意味着,在服务方法中发生的一切都应该是原子的。如果您使用hibernate事务,那么您必须在DAO之外编写hibernate事务代码,以便围绕使用许多DAO方法的服务定义事务边界

但是请注意,事务可以独立于您的实现——无论是否使用hibernate,您都需要事务。还请注意,您不需要使用hibernate事务处理机制——您可以使用基于容器的事务、JTA事务等

毫无疑问,如果您不使用Spring或类似的东西,事务将是一件痛苦的事情。我强烈建议使用Spring来管理事务,或者使用EJB规范,我相信您可以使用注释围绕服务定义事务

查看以下链接,了解基于容器的事务

我从中得到的信息是,您可以在服务级别轻松地定义DAO之外的事务,并且不需要编写任何事务代码

另一个(不那么优雅的)选择是将所有原子工作单元放在DAO中。简单操作可以使用CRUD DAO,然后是执行多个CRUD操作的更复杂DAO。这样,您的编程事务就留在DAO中,您的服务将调用更复杂的DAO,而不必担心事务

下面的链接是DAO模式如何帮助您简化代码的一个很好的示例

(thanx@)

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