我正在尝试习惯 JSF 在访问数据方面的工作方式(来自 spring 背景)
我正在创建一个简单的示例来维护用户列表,我有类似的内容
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
然后“ Controller ”有类似的东西
@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? Controller 感觉它正在执行服务的一些工作。
最佳答案
Is this the correct way of doing things?
除了在托管 bean getter 方法中以低效的方式执行业务逻辑以及使用太宽的托管 bean 范围之外,它看起来还不错。如果将服务调用从 getter 方法移至 @PostConstruct
方法,并使用 @RequestScoped
或 @ViewScoped
而不是 @SessionScoped
,看起来会更好。
另请参阅:
<小时/>Is my terminology right?
没关系。只要您与它保持一致并且代码可以以合理的方式可读。只是您命名类和变量的方式有点尴尬(不合逻辑和/或重复)。例如,我个人会使用 users
而不是 userList
,使用 var="user"
而不是 var="u"
,并使用 id
和 name
而不是 userId
和 userName
。此外,“UserListService”听起来好像只能处理用户列表,而不是一般用户。我宁愿使用“UserService”,这样您也可以使用它来创建、更新和删除用户。
另请参阅:
<小时/>The "service" feels more like a DAO?
它并不完全是一个 DAO。基本上,JPA 才是真正的 DAO。以前,当 JPA 不存在时,每个人都自行开发 DAO 接口(interface),以便即使底层实现(“普通的旧”JDBC 或“好旧”Hibernate 等)发生变化,服务方法也可以继续使用它们。服务方法的真正任务是透明地管理事务。这不是 DAO 的责任。
另请参阅:
- I found JPA, or alike, don't encourage DAO pattern
- DAO and JDBC relation?
- When is it necessary or convenient to use Spring or EJB3 or all of them together?
And the controller feels like it's doing some of the job of the service.
我可以想象它在这个相对简单的设置中做到了这一点。然而, Controller 实际上是前端的一部分而不是后端。该服务是后端的一部分,应该以这样的方式设计,以使其在所有不同前沿中都可以重复使用,例如JSF,JAX-RS,“Plain” JSP+Servlet,什至摇摆,挥杆等。此外,此外,此外,前端特定的 Controller (也称为“Backing Bean”或“Beacking Bean”或“Edrestrer”)允许您列出列为“成功”和“exclort and Offort in Casef”的示例。服务。
另请参阅:
<小时/>总而言之,正确的方法如下:
<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 kickoff app .
另请参阅:
关于JSF Controller 、服务和 DAO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38828482/