JSF控制器,服务和DAO
我试图习惯JSF如何处理访问数据(来自Spring背景)
我创建了一个维护用户列表的简单示例,我有类似的东西
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
然后“控制器”有类似的东西
@Named(value = "userListController")
@SessionScoped
public class UserListController {
@EJB
private UserListService userListService;
private List<User> userList;
public List<User> getUserList() {
userList = userListService.getUsers();
return userList;
}
}
而“服务”(尽管看起来更像是一个DAO)
public class UserListService {
@PersistenceContext
private EntityManager em;
public List<User> getUsers() {
Query query = em.createQuery("SELECT u from User as u");
return query.getResultList();
}
}
这是做事的正确方法吗? 我的术语是对的吗? “服务”更像是一个DAO? 控制器感觉自己在做这项服务的一些工作。
这是做事的正确方法吗?
除了在托管bean getter方法中执行业务逻辑效率低下以及使用过于宽泛的托管bean范围之外,它看起来没问题。 如果将服务调用从getter方法移动到@PostConstruct
方法,并使用@RequestScoped
或@ViewScoped
而不是@SessionScoped
,则它看起来会更好。
也可以看看:
我的术语是对的吗?
没关系。 只要你符合它,并且代码可以以合理的方式阅读。 只有你命名类和变量的方式有些尴尬(不合逻辑和/或重复)。 例如,我个人会使用users
而不是userList
,并使用var="user"
而不是var="u"
,并使用id
和name
代替userId
和userName
。 此外,“UserListService”听起来像它只能处理用户列表,而不是一般用户。 我宁愿使用“UserService”,以便您也可以使用它来创建,更新和删除用户。
也可以看看:
“服务”更像是一个DAO?
它不完全是一个DAO。 基本上,JPA是真正的DAO。 以前,当JPA不存在时,每个人都会自定义DAO接口,以便服务方法可以继续使用它们,即使底层实现(“普通旧式”JDBC或“老式”Hibernate等)发生更改时也是如此。 服务方法的真正任务是透明地管理事务。 这不是DAO的责任。
也可以看看:
控制器感觉自己在做这项服务的一些工作。
我可以想象,这是在这个相对简单的设置中。 但是,控制器实际上是前端的一部分,而不是后端。 该服务是后端的一部分,其设计应该可以跨所有不同的前端重用,如JSF,JAX-RS,“普通”JSP + Servlet,甚至是Swing等。此外,前端特定的控制器也称为“支持bean”或“演示者”)允许您以成功和/或特殊结果的方式处理前端特定的方式,例如在JSF的情况下显示面部消息以防从服务中抛出异常。
也可以看看:
总而言之,正确的方法如下所示:
<h:dataTable value="#{userBacking.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.name}</h:column>
</h:dataTable>
@Named
@RequestScoped // Use @ViewScoped once you bring in ajax (e.g. CRUD)
public class UserBacking {
private List<User> users;
@EJB
private UserService userService;
@PostConstruct
public void init() {
users = userService.listAll();
}
public List<User> getUsers() {
return users;
}
}
@Stateless
public class UserService {
@PersistenceContext
private EntityManager em;
public List<User> listAll() {
return em.createQuery("SELECT u FROM User u", User.class).getResultList();
}
}
您可以在这里找到一个真正的世界启动项目,这里使用规范的Java EE / JSF / CDI / EJB / JPA实践:Java EE启动应用程序。
也可以看看:
这是一个道,实际上是一个存储库,但不要太担心这种差异,因为它使用持久化上下文访问数据库。
您应该创建一个服务类,该类包装该方法并且是调用事务的地方。
有时服务类别是不必要的,但是当你有一个调用多个dao方法的服务方法时,它们的使用更有保证。
我通常最终只是创建服务,即使它确实没有必要,确保模式保持不变,并且dao从不直接注入。
这增加了一个额外的抽象层,使未来的重构更灵活。
链接地址: http://www.djcxy.com/p/76545.html