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 ,则它看起来会更好。

也可以看看:

  • 为什么JSF多次调用getters
  • 如何选择合适的bean范围?

  • 我的术语是对的吗?

    没关系。 只要你符合它,并且代码可以以合理的方式阅读。 只有你命名类和变量的方式有些尴尬(不合逻辑和/或重复)。 例如,我个人会使用users而不是userList ,并使用var="user"而不是var="u" ,并使用idname代替userIduserName 。 此外,“UserListService”听起来像它只能处理用户列表,而不是一般用户。 我宁愿使用“UserService”,以便您也可以使用它来创建,更新和删除用户。

    也可以看看:

  • JSF管理的bean命名约定

  • “服务”更像是一个DAO?

    它不完全是一个DAO。 基本上,JPA是真正的DAO。 以前,当JPA不存在时,每个人都会自定义DAO接口,以便服务方法可以继续使用它们,即使底层实现(“普通旧式”JDBC或“老式”Hibernate等)发生更改时也是如此。 服务方法的真正任务是透明地管理事务。 这不是DAO的责任。

    也可以看看:

  • 我发现JPA或类似的,不鼓励DAO模式
  • DAO和JDBC的关系?
  • 何时将Spring或EJB3或它们全部一起使用是必要的还是方便的?

  • 控制器感觉自己在做这项服务的一些工作。

    我可以想象,这是在这个相对简单的设置中。 但是,控制器实际上是前端的一部分,而不是后端。 该服务是后端的一部分,其设计应该可以跨所有不同的前端重用,如JSF,JAX-RS,“普通”JSP + Servlet,甚至是Swing等。此外,前端特定的控制器也称为“支持bean”或“演示者”)允许您以成功和/或特殊结果的方式处理前端特定的方式,例如在JSF的情况下显示面部消息以防从服务中抛出异常。

    也可以看看:

  • 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启动应用程序。

    也可以看看:

  • 为实体创建主 - 细节页面,如何链接它们以及选择哪个bean范围
  • 将JSF2托管的pojo bean传递到EJB中或将所需内容放入传输对象中
  • 过滤器不会初始化EntityManager
  • 小型facelet应用程序中的javax.persistence.TransactionRequiredException

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

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

    有时服务类别是不必要的,但是当你有一个调用多个dao方法的服务方法时,它们的使用更有保证。

    我通常最终只是创建服务,即使它确实没有必要,确保模式保持不变,并且dao从不直接注入。

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

    链接地址: http://www.djcxy.com/p/76545.html

    上一篇: JSF Controller, Service and DAO

    下一篇: What components are MVC in JSF MVC framework?