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>

那么"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?控制器感觉它在做一些服务的工作

这是正确的做事方式吗?

除了在托管bean getter方法中以低效的方式执行业务逻辑,以及使用太宽的托管bean作用域之外,它看起来还可以。如果您将服务调用从getter方法移动到@PostConstruct方法,并使用@RequestScoped@ViewScoped而不是@SessionScoped,则看起来会更好。

参见:

  • 为什么JSF多次调用getter
  • 如何选择合适的bean scope?

我的术语对吗?

没关系。只要您与它保持一致,并且代码以一种合理的方式可读即可。只是您命名类和变量的方式有些笨拙(不合逻辑和/或重复)。比如,我个人会用users代替userList,用var="user"代替var="u",用idname代替userIduserName。还有一个"UserListService"听起来它只能处理用户列表,而不是一般的用户。我宁愿使用"userservice"。所以你也可以用它来创建、更新和删除用户。

参见:

  • JSF管理bean命名约定

"service"感觉更像刀?

它不是一个DAO。基本上,JPA是这里真正的DAO。以前,当JPA还不存在时,每个人都自己开发DAO接口,以便服务方法可以继续使用它们,即使底层实现("普通旧的")。JDBC,或者"good old";Hibernate等)的变化。服务方法的真正任务是透明地管理事务。这不是DAO的责任。

参见:

  • 我发现JPA,或类似的,不鼓励DAO模式
  • DAO和JDBC关系?
  • 什么时候需要或方便使用Spring或EJB3或所有它们一起?

控制器感觉它在做一些服务的工作

我可以想象它在这个相对简单的设置中是这样做的。然而,控制器实际上是前端的一部分,而不是后端。服务是后端的一部分,在后端应该被设计成可以在所有不同的前端(如JSF、JAX-RS、plain)上重用的方式。JSP+Servlet,甚至Swing等等。此外,前端专用控制器(也称为"后台bean");或"present")允许您以特定于前端的方式处理成功和/或异常结果,例如在JSF的情况下,在服务抛出异常时显示faces消息。

参见:

    JSF服务层
  • JSF MVC框架中的MVC组件是什么?

总之,正确的方法如下:
<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。

参见:

  • 为实体创建主-详细页面,如何链接它们以及选择哪个bean作用域
  • 将JSF2托管pojo bean传递到EJB或将所需的内容放入传输对象
  • Filter不初始化EntityManager
  • javax.persistence。小块应用中的TransactionRequiredException

这是一个DAO,实际上是一个存储库,但不要太担心差异,因为它是使用持久性上下文访问数据库的。

您应该创建一个Service类,它包装了该方法,并且是调用事务的地方。

有时service类感觉没有必要,但是当你有一个service方法调用许多DAO方法时,它们的使用是更有必要的。

我通常最终只是创建service,即使它确实感觉没有必要,以确保模式保持不变,DAO永远不会直接注入。

这为添加了一个额外的抽象层,使将来的重构更加灵活。

相关内容

  • 没有找到相关文章

最新更新