JSF控制器,服务和DAO [英] JSF Controller, Service and DAO
问题描述
我正在创建一个简单的例子来维护一个用户列表,我有一些类似
< 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;
私人列表<用户>用户列表;
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
,看起来会更好。
另见:
- 为什么JSF多次呼叫getter
- 如何选择正确的bean范围?
我的术语是否正确?
没关系只要你符合它,代码是可读的方式。只有你的命名类和变量的方式有些尴尬(不合逻辑和/或重复)。例如,我个人将使用用户
而不是 userList
,并使用 var =user
而不是 var =u
,并使用 id
和 name
而不是 userId
和 userName
。此外,UserListService听起来像只能处理一般的用户而不是用户的列表。我宁愿使用UserService,因此您也可以使用它来创建,更新和删除用户。
另请参见:
服务感觉更像一个DAO?
这不完全是一个DAO。基本上,JPA是这里的真正的DAO。以前,当JPA不存在时,每个人都会建立DAO接口,这样即使底层实现(普通旧JDBC还是旧的Hibernate等)发生变化,服务方法也可以继续使用它们。服务方法的真正任务是透明地管理事务。这不是DAO的责任。
另请参见:
控制器感觉像是在做某些服务。
我可以想象这样做在这个比较简单的设置中。然而,控制器实际上是前端的一部分,而不是后端。该服务是后端的一部分,应该被设计为可以在所有不同的前端(如JSF,JAX-RS,plainJSP + Servlet,甚至Swing等)可重用。此外,前端特定的控制器允许您可以以成功和/或异常结果处理前端特定的方式,例如在JSF的情况下显示面孔消息,以防从服务中抛出异常。
另请参见:
总而言之,我的方法将如下所示:
< h:dataTable value = #{userBacking.users}var =user>
< h:column>#{user.id}< / h:column>
< h:column>#{user.name}< / h:column>
< / h:dataTable>
@Named
@RequestScoped //使用@ViewScoped一旦你带入ajax(例如CRUD)
public class UserBacking {
private List< User>用户;
@EJB
私人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启动应用程序。
另请参见:
- 为实体创建主专页,如何链接它们以及哪个bean范围进行选择
- 筛选器不初始化EntityManag呃
- 小脸孔应用程序中的javax.persistence.TransactionRequiredException
I'm trying to get used to how JSF works with regards to accessing data (coming from a spring background)
I'm creating a simple example that maintains a list of users, I have something like
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
Then the "controller" has something like
@Named(value = "userListController")
@SessionScoped
public class UserListController {
@EJB
private UserListService userListService;
private List<User> userList;
public List<User> getUserList() {
userList = userListService.getUsers();
return userList;
}
}
And the "service" (although it seems more like a DAO) has
public class UserListService {
@PersistenceContext
private EntityManager em;
public List<User> getUsers() {
Query query = em.createQuery("SELECT u from User as u");
return query.getResultList();
}
}
Is this the correct way of doing things? Is my terminology right? The "service" feels more like a DAO? And the controller feels like it's doing some of the job of the service.
Is this the correct way of doing things?
Apart from performing business logic the inefficient way in a managed bean getter method, and using a too broad managed bean scope, it looks okay. If you move the service call from the getter method to a @PostConstruct
method and use either @RequestScoped
or @ViewScoped
instead of @SessionScoped
, it will look better.
See also:
Is my terminology right?
It's okay. As long as you're consistent with it and the code is readable in a sensible way. Only your way of naming classes and variables is somewhat awkward (illogical and/or duplication). For instance, I personally would use users
instead of userList
, and use var="user"
instead of var="u"
, and use id
and name
instead of userId
and userName
. Also, a "UserListService" sounds like it can only deal with lists of users instead of users in general. I'd rather use "UserService" so you can also use it for creating, updating and deleting users.
See also:
The "service" feels more like a DAO?
It isn't exactly a DAO. Basically, JPA is the real DAO here. Previously, when JPA didn't exist, everyone homegrew DAO interfaces so that the service methods can keep using them even when the underlying implementation ("plain old" JDBC, or "good old" Hibernate, etc) changes. The real task of a service method is transparently managing transactions. This isn't the responsibility of the DAO.
See also:
- 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.
I can imagine that it does that in this relatively simple setup. However, the controller is in fact part of the frontend not the backend. The service is part of the backend which should be designed in such way that it's reusable across all different frontends, such as JSF, JAX-RS, "plain" JSP+Servlet, even Swing, etc. Moreover, the frontend-specific controller allows you to deal in a frontend-specific way with success and/or exceptional outcomes, such as in JSF's case displaying a faces message in case of an exception thrown from a service.
See also:
All in all, "my" approach would be like below:
<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();
}
}
You can find here a real world kickoff project here utilizing the canonical Java EE / JSF / CDI / EJB / JPA practices: Java EE kickoff app.
See also:
- Creating master-detail pages for entities, how to link them and which bean scope to choose
- Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
- Filter do not initialize EntityManager
- javax.persistence.TransactionRequiredException in small facelet application
这篇关于JSF控制器,服务和DAO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!