2010-03-10 23 views
2

我正在阅读Apress“从新手到专业开始”,我发现这一节讨论了DAO的使用。这个例子是非常简单,我在这里粘贴在src:设计/代码问题 - 从Apress的春天书

高级java/spring用户可以直接引用最后一个链接(jdbc执行的DAO)。我感兴趣的是这件作品的源代码:

public List<UserAccount> list() { 
     final List<UserAccount> list = 
     getTemplate().query(SELECT_ACCOUNTS, userMapper); 
     for(final UserAccount account : list) { 
     populateRoles(account); 
     } 
     return list; 
    } 

这种方法应该是检索数据库中的所有UserAccounts的列表。通过执行查询“SELECT_ACCOUNTS”获得的第一个列表仅获取UserAccount表中的UserAccount详细信息。然而UserRoles在不同的桌子上。从上面的代码片段可以清楚地看出,对于每个UserAccount,populateRoles都会被执行。 populateRules(帐户)依次使用用户标识查询角色表。实际上,如果您有1000个用户,则此代码将发出1,000次准备好的声明!

所以来这里的问题:

第1部分:

是不是一个不好的做法?有没有简单的方法呢?你通常会怎么做?这里最好的做法是什么?

第2部分:

你如何决定的DAO?每个实体是否应该有一个DAO?例如,在上面的例子中,UserAccount和UserRoles代表两个实体。在数据库方面,你有USERS,ROLES表和USERS_ROLES映射表。那么,你如何决定要创建哪些DAO?它取决于要求吗?还是应该在对象相关时创建DAO(在数据库中有映射表?)?

回答

1

我会用懒惰初始化在UserAccount#getRoles

public Set<UserRole> getRoles() { 
    if (roles == null) { 
    XXX.populateRoles(this); // replace XXX with the class who populates the Roles. 
    } 
    return roles; 

}

这样一来,只有UserAccount小号谁曾经得到被问及自己的角色,实际上要求DB他们。我知道,如果你有要求他们所有为自己的角色代码不能很好地工作,但问题有:你绝对在启动需要的 UserAccount 的角色?

+1

XXX.populateRoles(这个) - 这意味着,你需要从实体调用你的DAO!?那有意义吗? – Jay 2010-03-10 14:00:50

+0

我想不是,但我不知道你是如何正确开发你的应用程序的。您可以将该代码移动到您的服务层的实用程序方法中,例如'UserAccountUtil.getRoles(UserAccount ua)'。我只是建议你如何避免数据库查询洪水。你如何编写你的应用程序作为一个整体(DAO,模型等)是你的工作。 ;) – dimitarvp 2010-03-10 14:12:28

0

section1 - 是的,这不是一个好的做法,因为在这一步你可以知道所有账户,并且可以用一个sql select加载所有角色。但是,由于这本书是关于Spring的,而不是关于SQL的,所以很好。通常情况下,如果你像使用Hibernate一样使用ORM,它会使用惰性或批量加载为你优化,例如。但是,你需要添加一些提示吧,手动配置Hibernate以获得最佳性能等

第2节 - 如果DAO的是简单的CRUD,这是更好地使个别DAO为每个实体。如果你有一些功能域,你可以按域分割你的DAO。等等。看看你会使用你的DAO,什么操作似乎很受欢迎,然后将它们分组在一个DAO中。

+0

@splix你可以详细说明section1吗?在上面的例子中,你如何解决这个问题? – Jay 2010-03-10 14:02:01

+0

我会使用Hibernate它,与角色启用延迟加载(但要看在哪里以及它如何被使用) – 2010-03-10 14:38:46

1

我觉得春天应用程序写入向您展示不同的东西怎么能没有过分担心性能来完成。

由逻辑去最好你不应该这样做()或queryAll(),尤其是在用户表列表(或为此事大多数表用> 1000行)。所以是的,这是不理想的,如果ORM/Hibernate不是一个选项,我会这样做。

//just queries userAccount with no roles populated 
public List<UserAccount> listAllUsersRolesNotPopulated(); 

//get userAccount with roles for an accId 
public UserAccount listUserWithRoles(int accId); 

并且调用者决定在他想要角色时调用第二个API。