tutorial - jsf primefaces




Controlador JSF, Serviço e DAO (2)

Estou tentando me acostumar com o funcionamento do JSF no que diz respeito ao acesso a dados (provenientes de um segundo plano na primavera)

Estou criando um exemplo simples que mantém uma lista de usuários, tenho algo como

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

Então o "controlador" tem 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;
    }
}

E o "serviço" (embora pareça mais com um DAO) tem

public class UserListService {

    @PersistenceContext
    private EntityManager em;

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

Essa é a maneira correta de fazer as coisas? Minha terminologia está correta? O "serviço" parece mais um DAO? E o controlador parece que está fazendo parte do serviço.


Essa é a maneira correta de fazer as coisas?

Além de executar a lógica de negócios da maneira ineficiente em um método gerenciador de beans gerenciados e usar um escopo de beans gerenciados muito amplo, parece bom. Se você mover a chamada de serviço do método getter para o método @PostConstruct e usar @RequestScoped ou @ViewScoped vez de @SessionScoped , a aparência será melhor.

Veja também:

Minha terminologia está correta?

Está bem. Desde que você seja consistente com ele e o código seja legível de maneira sensata. Somente sua maneira de nomear classes e variáveis ​​é um pouco estranha (ilógica e / ou duplicada). Por exemplo, eu pessoalmente usaria users vez de userList e usaria var="user" vez de var="u" e usaria id e name vez de userId e userName . Além disso, um "UserListService" parece que só pode lidar com listas de usuários em vez de usuários em geral. Prefiro usar o "UserService" para que você também possa usá-lo para criar, atualizar e excluir usuários.

Veja também:

O "serviço" parece mais um DAO?

Não é exatamente um DAO. Basicamente, o JPA é o verdadeiro DAO aqui. Anteriormente, quando o JPA não existia, todo mundo fazia a homologação de interfaces do DAO, para que os métodos de serviço possam continuar usando-os mesmo quando a implementação subjacente (JDBC "simples" ou "Hibernate" etc.) é alterada. A tarefa real de um método de serviço é gerenciar transações de forma transparente. Isso não é de responsabilidade do DAO.

Veja também:

E o controlador parece que está fazendo parte do serviço.

Eu posso imaginar que ele faz isso nesta configuração relativamente simples. No entanto, o controlador é de fato parte do front-end e não do back-end. O serviço faz parte do back-end, que deve ser projetado de forma que seja reutilizável em todos os diferentes front-ends, como JSF, JAX-RS, JSP + Servlet "simples", até Swing, etc. Além disso, o controlador específico do front-end ( também chamado de "backing bean" ou "apresentador") permite lidar de maneira específica com o front-end com êxito e / ou resultados excepcionais, como no caso do JSF, exibindo uma mensagem de rosto no caso de uma exceção lançada de um serviço.

Veja também:

Em suma, a abordagem correta seria como abaixo:

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

}

Você pode encontrar aqui um projeto de kickoff do mundo real aqui, utilizando as práticas canônicas de Java EE / JSF / CDI / EJB / JPA: aplicativo de kickoff de Java EE .

Veja também:


É um DAO , na verdade um repositório, mas não se preocupe muito com essa diferença, pois está acessando o banco de dados usando o contexto de persistência.

Você deve criar uma classe de Service que agrupe esse método e é onde as transações são invocadas.

Às vezes, as classes de service parecem desnecessárias, mas quando você tem um método de service que chama muitos métodos DAO , seu uso é mais garantido.

Normalmente, acabo criando o service , mesmo que pareça desnecessário, para garantir que os padrões permaneçam os mesmos e o DAO nunca seja injetado diretamente.

Isso adiciona uma camada extra de abstração, tornando a refatoração futura mais flexível.





dao