A minha idéia com relação a este tópico é distribuir informações de padrões de implementação para lógica de negócio e dados, especificamente JPA e seus padrões. O padrão que adotei aqui não é o mais correto ou menos correto, é apenas um padrão, e como eu falei, a importância é discutir várias formas diferentes de implementações a fim de melhorar técnicas e padrões e também difundir conhecimento.
:: Criação de APIs
Para distribuir o JPA entre as aplicações, criamos uma API que servirá como base para qualquer projeto poder estender e usar suas funcionalidades, a priore essa API entrega:
[list]
- Estrutura de classes de exceção para a aplicação.
- Estrutura de login para as aplicações (para tier de negócio).
- Estrutura de acesso a uma abstração de JPA única
- Estrutura de classes de negócio básica
[/list]
Distribuíndo essa lib, a aplicação terá o suporte básico para inciar um projeto de camada de négocio e dados.
O projeto final será o resultado de 3 outros projetos. Um ou dois para apresentação (WEB ou Swing e REL) e um para négocio.
[URL=http://img257.imagevenue.com/img.php?image=30827_Arquitetura_Basica_122_521lo.jpg][/URL]
Por exemplo, o nome do meu projeto fictício é Sistema de Controle Externo (SCE), ele irá constituir de:
[list]
- SCE_API.jar
- SCE_REL.jar
e
Se for Swing:
- SCE_SWING.jar
Se for Web: - SCE_WEB.war
[/list]
Dessa forma componentizada, permite melhor reaproveitamento do código, se eu desenvolver incialmente para Swing, poderei migrar para web de forma mais rápida e com menos problemas, já que a estrutura de negócio estará contida em um .jar isolado da apresentação.
Das classes representantes:
:: A estrutura do modelo para JPA utilizada:
Existe uma interface e uma classe abstrata para a JPA:
[list]
- JPAUtil (interface)
- JPAUtilBase (classe)
[/list]
Para a Interface temos:
public final static String PU_ONLINE="ONLINE";
public final static String PU_OFFLINE="OFFLINE";
public void setOnline(Boolean pOnLine);
public Boolean isOnline();
public void close();
public void commitTran();
public List executarQuery(String pQuery, Map pParametros);
public List executarNamedQuery(String pQueryName, Map pParametros);
public List executarNativeQuery(String pQuery, Map pParametros, Class pEntidade);
public List executarNativeQuery(String pQuery, Map pParametros);
public void executarNativeUpdate(String pUpdateCommand);
public void executarUpdate(String pUpdateCommand);
public ModelGeral find(Class pClasseEntidade, Long pId) throws RegistroNaoEncontradoException;
public void flush();
public EntityManager getEntityManager();
public ModelGeral reference(Class pClasseEntidade, Long pId) throws RegistroNaoEncontradoException;
public List obterTodos(Class pClasseEntidade, int pOffset, int pQtde);
public ModelGeral persist(ModelGeral pEntidade);
public ModelGeral refresh(ModelGeral pEntidade)throws RegistroNaoEncontradoException;
public void remove(ModelGeral pEntidade) throws RegistroNaoEncontradoException, RegistroDependenteException;
public void rollbackTran();
public void closeEMF();
NOTA:
- O ‘ModelGeral’ é uma classe abstrata que estabelece um model primário para qualquer entidade de qualquer projeto. Voltando ao exemplo do SCE, se eu for criar uma entidade no projeto SCE, crio antes uma abstração que estender de ModelGeral que se chamara ModelSCE, que todas as entidades desse projeto passarão a ser uma ModelSCE que por sua vez é uma ModelGeral.
- As exceções checked criadas são as de NegocioExcepion, AmbienteException e SegurancaException, dessas a NegocioException tem suas especializacoes em RegistroDependenteException, RegistroNaoEncontradoException, etc.
A JPAUtilBase irá implementar vários desses métodos especificados na interface, porém alguns deverão ser implementados para cada projeto, eles são:
getEntityManagerFactory
getPUMap
getPUName
Como a lógico de acesso ao banco de dados colocamos em um outro jar isolado, então é obrigatório a implementação do PUMaps que será um HashMap de algumas propriedades do hibernate-jpa como a exemplo o pool de conexão da aplicação considerada e dados de acesso ao banco como URL, username e pasword.
Mais informações eu poderei detalhar, por enquanto dá para se ter uma base de como os projetos são feitos aqui, poderiamos discutir maneiras diferentes, aprimorar e comentar os padrões aqui adotados.