Com um pouco de atraso, finalmente estou postando a parte 3 deste tutorial voltado para a introdução ou fixação de conceitos utilizados na programação para web usando Java.

Nesta parte, criaremos uma busca de models pelo id e implementaremos uma idéia bastante legal e “preguiçosa” usada em JPA ou Hibernate.

Vejam também a parte 1 e a parte 2 do tutorial, caso ainda não o tenham feito.

No final da parte anterior concluimos a persistência de um novo model com retorno do id gerado e implementamos a atualização de um model já persistido. Entretanto, não pudemos testar propriamente sem uma busca de model pelo seu id. Podemos começar por este ponto.

 

Find by Private Key

Caso você tenha lido as partes anteriores, provavelmente deve estar imaginando (ou já ter implementado =P) como poderia ser este método. Se pensou em construir um SQL para a busca como “SELECT * FROM Pessoa WHERE id = 1“, pensou certo.

Após construirmos o SQL e realizarmos a consulta, convertemos o ResultSet obtido para um BasicModel da seguinte forma:

Então temos o model buscado pelo seu id. =)

Podemos atualizar o teste e criar um novo teste apenas para esta operação. E falando em testes, eu alterei um pouquinho a classe BasicDaoTest para ficar melhor apresentada. Antes de cada teste o banco é limpo, melhorando o isolamento dos testes.

E no BasicDao, implementei um método simples para limpeza de tabelas.

 

Lazy Connection

Bem, será que alguém notou que, ao buscar um BasicModel, nenhum outro model ou collection relacionados são obtidos?  Na linha 15 do findByPK nada é feito quando o atributo do model é do tipo model ou collection.

Isso é feito visando a questão de performace, apesar de se tratar de um exemplo meramente didático.

Para visualizar o problema, imagine que tenhamos muitos dados (pessoas) no banco. Se na busca por id incluíssemos todos os atributos, acabaria gerando uma busca recursiva (busca uma pessoa, e os pais dessa pessoa, e os pais dos pais…), passando por todas as pessoas com alguma ligação à pessoa buscada. Se necessitarmos apenas dos dados de uma pessoa, todas as outras muitas buscas realizadas foram um desperdício de processamento, conexão com o banco e tempo.

Para resolver isso, o Java Persistence API (JPA) possui o conceito de Lazy Connection (ou conexão preguiçosa ^^). Utilizando essa especificação, podemos mapear modelos de dados utilizando relacionamentos “preguiçosos”. No nosso exemplo, poderíamos mapear o relacionamento pai-filho como lazy de modo que, ao obter uma pessoa, o seu pai não é imediatamente consultado no banco. Ao invéz disso, um proxy fica no lugar do pai até que este seja requerido através, por exemplo, de um getPai().

Como não utilizaremos nenhum framework, teremos que implementar esse conceito no braço! =D

Mas não será nada muito complexo… A idéia é basicamente implementar uma busca por pai, mãe e filhos partindo de uma pessoa e, então, alterar os getters do model Pessoa para realizar a busca se necessário.

 

Lazy getMae() / getPai()

Como pai e mãe de uma pessoa obtida através de uma consulta ao banco estarão nulos, não temos informação para realizar uma busca por essas pessoas. Por isso, antes de fazer um findByPK para pai e mãe, temos que obter os seus id consultando o próprio filho.

Bastante simples. Agora alteramos os getters em questão de Pessoa para verificar a nulabilidade dos pais e buscar por eles caso afirmativo.

Temos, é claro, que testar! Então adicionemos o seguinte teste ao BasicDaoTest:

Se tudo ocorrer bem, podemos avançar para a próxima e um pouco mais complexa parte.

 

Lazy getFilhos()

Antes de mais de nada, existe uma observação que deve ser feita com relação ao modelo de dados utilizado aqui.

Como esse projeto tem uma função apenas didática e como estamos construindo cada um dos SQLs de interação com o banco, podemos nos dar a liberdade de realizar escolhas visando a facilidade de implementação. Mas nem sempre essas escolhas poderão ser feitas.

Por exemplo, no BasicModel implementado, cada pessoa possui pai, mae e filhos de maneira direta. Entretando, se fôssemos utilizar um framework de persistência como o Hibernate, teríamos que estudar um pouco melhor esses relacionamentos.

No momento de mapear a coleção de filhos, precisamos informar qual o atributo do outro lado que comanda o relacionamento. Por exemplo, num relacionamento Estado-Cidade, um Estado possui um conjunto de cidades, e o atributo que comanda esse relacionamento é Cidade.estado. Entretanto, no relacionamento de Pai-Filho, temos mais de um atributo que pode comandar (pai e mae). Por isso, utilizando o Hibernate teríamos que alterar o modelo, talvez criando uma tabela intermediária com o tipo de relacionamento.

relacionamento_pessoa.jpg

Mas voltando à nossa realidade, podemos criar um SQL como “SELECT * FROM Pessoa WHERE pai = 1 OR mae = 1“. Então mãos à obra!

A implementação não ficou muito complicada. Apenas obtemos todas as pessoas cujo pai ou mãe é a pessoa base (atenção… nós não restringimos que uma pessoa pode ser apenas pai ou mãe!) e retornamos uma lista com essas pessoas.

Em Pessoa temos que alterar o getFilhos():

E então, podemos testar!

Se tudo deu certo os testes deverão estar 100% e estamos prontos para começar, efetivamente, a camada web!… Outro dia, claro…

(Bruno! Agora é com você!)

Baixe aqui o código fonte do core com o que foi visto até agora: arvore-ginecologica. (Obs: necessita o driver do pgsql e não notem o nome “zuado” do projeto ^^)

WARNING! POST EXTENSO DETECTADO! o_O