tutorial datos conexion jsf java-ee jpa ejb dao

datos - Controlador JSF, Servicio y DAO



jsf primefaces tutorial (2)

Estoy tratando de acostumbrarme a cómo funciona JSF con respecto al acceso a datos (proveniente de un fondo de primavera)

Estoy creando un ejemplo simple que mantiene una lista de usuarios, tengo algo como

<h:dataTable value="#{userListController.userList}" var="u"> <h:column>#{u.userId}</h:column> <h:column>#{u.userName}</h:column> </h:dataTable>

Entonces el "controlador" tiene algo como

@Named(value = "userListController") @SessionScoped public class UserListController { @EJB private UserListService userListService; private List<User> userList; public List<User> getUserList() { userList = userListService.getUsers(); return userList; } }

Y el "servicio" (aunque parece más un DAO) tiene

public class UserListService { @PersistenceContext private EntityManager em; public List<User> getUsers() { Query query = em.createQuery("SELECT u from User as u"); return query.getResultList(); } }

¿Es esta la forma correcta de hacer las cosas? ¿Es correcta mi terminología? El "servicio" se siente más como un DAO? Y el controlador siente que está haciendo parte del trabajo del servicio.


¿Es esta la forma correcta de hacer las cosas?

Además de realizar la lógica de negocios de la manera ineficiente en un método getter de bean administrado, y usar un alcance de bean administrado demasiado amplio, se ve bien. Si mueve la llamada de servicio del método getter a un método @PostConstruct y usa @RequestScoped o @ViewScoped lugar de @SessionScoped , se verá mejor.

Ver también:

¿Es correcta mi terminología?

Está bien. Siempre y cuando sea coherente con él y el código sea legible de manera sensata. Solo su forma de nombrar clases y variables es algo incómoda (ilógica y / o duplicación). Por ejemplo, yo personalmente usaría users lugar de userList , y usaría var="user" lugar de var="u" , y usaría id y name lugar de userId y userName . Además, un "UserListService" parece que solo puede tratar con listas de usuarios en lugar de usuarios en general. Prefiero usar "UserService" para que también pueda usarlo para crear, actualizar y eliminar usuarios.

Ver también:

El "servicio" se siente más como un DAO?

No es exactamente un DAO. Básicamente, JPA es el verdadero DAO aquí. Anteriormente, cuando JPA no existía, todos crecían interfaces DAO caseras para que los métodos de servicio puedan seguir usándolas incluso cuando cambia la implementación subyacente (JDBC "simple" o "Hibernate" bueno, etc.). La verdadera tarea de un método de servicio es gestionar de manera transparente las transacciones. Esta no es responsabilidad del DAO.

Ver también:

Y el controlador siente que está haciendo parte del trabajo del servicio.

Me imagino que hace eso en esta configuración relativamente simple. Sin embargo, el controlador es de hecho parte de la interfaz, no del servidor. El servicio es parte del backend que debe diseñarse de tal manera que sea reutilizable en todos los frentes diferentes, como JSF, JAX-RS, JSP + Servlet "simple", incluso Swing, etc. Además, el controlador específico de la interfaz ( también llamado "bean de respaldo" o "presentador") le permite tratar de manera específica a la interfaz con el éxito y / o resultados excepcionales, como en el caso de JSF que muestra un mensaje de rostros en caso de una excepción lanzada desde un servicio.

Ver también:

En general, el enfoque correcto sería el siguiente:

<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(); } }

Puede encontrar aquí un proyecto de lanzamiento del mundo real aquí utilizando las prácticas canónicas Java EE / JSF / CDI / EJB / JPA: la aplicación de lanzamiento Java EE .

Ver también:


Es un dao, bueno en realidad un repositorio, pero no se preocupe demasiado por esa diferencia, ya que está accediendo a la base de datos utilizando el contexto de persistencia.

Debe crear una clase de servicio, que envuelva ese método y es donde se invocan las transacciones.

A veces, las clases de servicio se sienten innecesarias, pero cuando tiene un método de servicio que llama a muchos métodos dao, su uso está más garantizado.

Normalmente termino simplemente creando el servicio, incluso si se siente innecesario, para asegurar que los patrones permanezcan igual y que el dao nunca se inyecte directamente.

Esto agrega una capa adicional de abstracción que hace que la futura refactorización sea más flexible.