Antes mesmo de criar esse blog, eu tinha a idéia de redigir um tutorial de Java para a Web seguindo alguns exercícios que fiz para fixação de conceitos, sem a utilização de qualquer framework.

Num primeiro momento vamos ver a implementação do núcleo do sistema utilizado nesse tutorial, focando na camada de persistência. Por isso, inicialmente,  não serão vistos aspectos voltados à web. Mas depois que esse núcleo estiver satisfatório, poderemos avançar para à camada de apresentação voltada para a web.

Ambiente de Trabalho:

Primeiramente, precisamos montar um ambiente de trabalho. Num primeiro momento utilizaremos apenas uma IDE para o desenvolvimento e um banco de dados, não havendo a necessidade de um container já que não mexeremos com a parte web, propriamente dita, nessa parte do tutorial.

Primeiramente, baixe e instale o Java Development Kit (JDK) 6 aqui e certifique-se que as variáveis path foi atualizada e a JAVA_HOME foi criada.

Para a IDE eu sugiro a utilização do NetBeans. Já trabalhei bastante com o Eclipse, e posso dizer que este último é realmente mais rápido que o NetBeans… Mas enfrentei alguns problemas com ele e acabei desistindo. Apesar de não ser tão eficiente, o NetBeans possui um ótimo suporte a XML e torna bastante simples a instalação ou atualização de plugins. Bem, baixem a última versão do NetBeans aqui (versão Java) ou o Eclipse aqui (para desenvolvimetno Java EE).

O banco de dados que utilizarei será o PostgreSQL por ser simples, robusto e leve. É possível baixar gratuitamente o PgAdmin aqui que já vem com o agente do banco e uma interface de administração mais do que suficiente para o propósito desse tutorial.

Por agora, não vou me aprofundar na configuração dessas ferramentas já que não há muito a ser configurado de ante mão. Mas quaisquer dúvidas podem ser postadas nos comentários ou buscadas no Google… ^^

 

Objetivo do Projeto:

Agora que temos um ambiente configurado podemos determinar o que faremos. Precisamos de um objetivo simples e ao mesmo tempo abrangente. Um amigo sugeriu um bom tema: árvore genealógica.

Gostei da idéia, já que teríamos, a princípio, apenas 1 entidade (pessoa) que teria pai, mãe e filhos (mais pessoas). Levando em conta que não será utilizado qualquer framework, inclusive para persistência em banco de dados, é importante não complicar as entidades de persistência.

 

Criando o Projeto:

Arquivo → Novo Projeto → Java → Aplicativo Java. Vou chamá-lo de “core”. E desmarque a opção criar classe principal.

Você pode estar pensando “What the f#$!? Não vamos fazer uma aplicação para web?! Não deveríamos criar um projeto web?!”.

E vamos. Mas eu sempre prefiro criar um projeto separada do projeto web. Dessa forma, podemos criar a camada de negócios e de persistência totalmente separada da camada de apresentação, tornando o sistema mais flexível. Depois de criado o núcleo (core) do sistema, a camada de apresentação pode ser um projeto web, ou um projeto desktop, ou mesmo um projeto para dispositivos móveis.

 

Modelo de Dados:

Agora vamos começar a criar a entidade pessoa. Mas antes, crie um estrutura de pacotes para os modelos na pasta “Pacotes de código fonte” (Clique Direito → Novo → Pacote Java). No meu caso, criei “br.com.arvore.genealogica.core.model“.

Antes de criar a entidade “Pessoa”, vamos criar uma base para toda e qualquer entidade: “BasicModel”. Ela terá apenas o que é comum para qualquer outra entidade… E o que será isso? Hein?! Hein?!

Qualquer entidade de persistência terá um “id”, identificador único da entidade no banco de dados. Então, a nossa classe BasicDao ficaria mais ou menos assim:

Simples, não? Apesar disso, é uma classe importante. Agora pode criar a entidade Pessoa. Vou inclui apenas pai, mãe, filhos, nome e data de nascimento.

Notem que pessoa extende de BasicModel, tal como deverá ser com qualquer nova entidade.

 

Persistência de Entidades:

Antes de começar a implementar a nossa persistência em banco de dados, precisamos incluir em nosso projeto o driver do bd. No caso do postgre, o driver pode ser obtido aqui. Adicione-o à pasta “Bibliotecas” do seu projeto (pode ser arrastando mesmo).

Feito isso, vamos criar outro pacote (dao) na pasta dos fontes: “br.com.arvore.genealogica.core.dao“. Nesse pacote vamos criar uma classe java que poderá ser chamada de “BasicDao”, já que será a base para qualquer outro dao.

Ah. É importante saber a função de um dao (Data Access Object). Ele serve como uma ligação entre o banco de dados e o sistema, realizando inserções, atualizações e seleções de entidades. Ele não deverá possuir regras de negócio.  Para maiores informações, vide Google.com.

Nessa primeira parte do tutorial, vou me restringir à persistência de uma nova entidade, já que essa tarefa pode se tornar um pouco trabalhosa sem um framework para fazer o trabalho sujo.

Primeiramente, vamos realizar um teste de conexão com o banco de dados.

Vejam que criei strings estáticas com os dados para acesso ao banco de dados. Essas informações estariam melhor acomodadas em um arquivo de configuração (um properties ou xml). Se quiser fazer isso agora, Go for it and Google it! ^^

É uma boa hora pra começar a criar testes para o sistema. Como diria meu chefe: “Se não está testado, então não funciona!”.

No “Pacote de Testes” do seu projeto, crie um pacote para testes de dao (“br.com.arvore.genealogica.core.dao” no meu caso), e crie uma nova classe java chamada “BasicDaoTest” extendendo “junit.framework.TestCase”.

“Ha! Te Peguei! Você está usando um framework para testes!”… ¬¬

Bem, se quiser fazer classes executávei com o bom e velho “public static void main”, fique a vontade. Mas já que o projeto no NetBeans já é criado com essa biblioteca e não quero ficar sofrendo com meros testes, vou usar o JUnit sim!

Então a classe de testes, que depois deverá ser ampliada, fica mais ou menos assim:

Agora basta executar o arquivo. Se houver um problema na conexão com o banco de dados e uma exceção for lançada, o teste não será executado com sucesso. Caso haja algum problema nesse ponto, aconselho parar tudo e resolvê-lo.

Agora é uma boa hora para criar a tabela de pessoa no banco de dados, já que será necessário para a implementação da persistência. Sem enrolar muito, o script para criação da tabela no banco de dados ficaria mais ou menos assim:

Lembrando que o nome dos campos devem ser os mesmo nomes dos atributos da classe Pessoa. Veremos o porquê disso durante a implementação da persistência.

Então vamos prosseguir com a implementação do BasicDao.

Quando comecei a fazer o BasicDao notei que seria possível implementar todas as funções básicas de persistências sem a necessidade de criar um dao específico. E tentei seguir esse caminho (talvez por isso as coisas tenham se complicado um pouquinho).

Então vamos criar um método “persist” que recebe como parâmetro um BasicModel, e decide se deve inserir o model ou atualizá-lo. Decide como? Pelo “id”, claro! Uma entidade que não foi persistida não possui o id gerado pelo banco, enquanto uma entidade persistida possui.

O método não fará nada além de executar o sql correto. E é a geração desse sql que pega um pouco pesado.

O que faremos é gerar um sql padrão de inserção de dados, tipo “INSERT INTO Pessoa (Nome, dataNascimento, mae, pai)  VALUES (‘Pessoa Qualquer 1’, ‘2009-03-29’, null, null) “. Pra isso usaremos ferramentas padrão do java para obtenção de nomes de classe e atraibutos; por isso os nome das colunas do banco de dados devem ser os mesmo usados na classe java.

Infelizmente, não consigo pensar em uma forma melhor para explicar o método de geração do sql de inserção sem apresentá-lo de uma só vez para depois tentar clarera cada parte.

Bunito! ^^

Vamos então a algumas explicações que acho pertinentes:

Na linha 10, verifico se o atributo o atributo que está sendo analisado é uma coleção de objetos. Por exemplo, a lista de filho da Pessoa. Poderíamos também chamar a persistência para cada filho após a persistência do pai, de maneira recursiva. Mas isso seria ruim para a eficiência, já que, ao salvar a Pessoa que é raiz de uma árvore genealógica, todas as pessoas abaixo dessa seriam persistidas também. Por isso decidi que seria melhor (e mais fácil) persistir uma a uma e apenas quando necessário.

Na linha 24 é verificado se o atributo é um BasicModel, como é o caso do pai e mãe da pessoa. Se for, são verificados 3 cassos: se é nulo, persistimos como nulo mesmo (não restringimos a “nulabilidade” do atributo); se não é nulo, mas seu id é, então o model do atributo não foi persistido e, por isso, lançamos uma exceção (precisamos do id para fazer o relacionamento pai/filho); e se possui id simplemente salvamos com o valor desse.

Por fim, na linha 50 outros tipos de objetos são tratados.

Podemos agora adicionar outro método à nossa classe de testes (BasicDaoTest):

Se tudo der certo, a pessoa terá sido persistida no banco de dados.

Mas temos um pequeno problema: a pessoa que persistimos ainda não está com o id. De acordo com o que foi definido, se está persistido, tem um id originado da geração automática do banco.

Há uma solução bem simples, mas isso fica para a próxima parte, onde será abordado também a geração do sql de atualização.

PS: Não achei q ficaria grande assim. =P