Objetos Persistentes x JDBC/SQL => qual o pulo do gato?

Ola pessoal,

Tenho lido muitas msgs sobre este assunto aqui no forum. Tambem dei uma olhada boa no Hybernate e no Torque. Trabalho com Java Servlets usando JDBC/SQL direto desde 2000, e quando vi pela 1a. vez estas camadas de persistencia ainda estavam muito fracas. Hoje parece que o Hybernate é o que existe de mais interessante nisso.

Contudo, nao sei se é pelo fato que eu acho que “penso relacional”, mas nao consigo ver uma melhoria substancial em usar uma Camada de Persistencia. Fala-se muito que usando isso pode-se programar puramente OO e tudo mais, mas gostaria de uma opiniao sincera de voces se o topico “aumento de produtividade de desenvolvimento” é satisfeito ao usar esta camada. Ate o momento, parece pra mim mais um formalismo pra gente “nao ficar estressado” de misturar OO com relacional, do que propriamente para tornar o trabalho de desenvolvimento melhor. Podem “mandar bala” nas criticas, pois o que eu quero saber é se realmente meu pensamento é “retrogado/desatualizado/sem sentido” e que preciso “evoluir” para a Camada de Persistencia.

Eu fico olhando os codigos que faco, usando SQLs diretos (é claro que usando aquele esquema de colocar os SQLs em arquivo de properties, que da uma limpada boa no codigo), e depois comparo com exemplos que fiz com o Hybernate, que tem que criar uma classe bean, arquivo XML, etc, etc, etc, pra fazer exatamente a mesma coisa: inserir/alterar/remover/consultar! Qual é de verdade, “caso exista”, o pulo do gato desta Camada?

Produtividade nao eh a unica metrica que existe, Edilmar. Cuspir codigo pra cima e pra baixo feito uma AK-47 eh bastante produtivo, mas nao quer dizer que a qualidade do seu sistema vai ser boa: ele provavelmente nao sera performatico, nao sera facil de manter ou atualizar, vai consumir mais memoria do que deveria, e, pode ter certeza, vai ter mais bugs do que se gostaria.

O pulo do gato aqui eh bem simples: se voce esta usando uma linguagem orientada a objetos, vc quer trabalhar com objetos, e nada mais do que objetos. E eles tem que ser lindinhos, isolados do mundo nojento la fora (leia-se, RDBMS’s). Usar uma camada de persistencia boa, como o Hibernate, te deixa muito proximo disso. Mas ainda nao eh 100%, afinal existe um bocado de impedancia entre os dois modelos (OO e relacional).

Ola cv,

Agora deixa eu “pensar relacional” mais um pouco: eu tenho um sistema C/S Delphi para Escolas com um DER tradicional que trabalho desde 1997. Entao, em 2000 fiz um modulo Web em Java/Servlets para fornecer alguns servicos adicionais para professores/alunos/etc.

Nesta situacao, eu ja “era” relacional, ou seja, naquela epoca eu nem sabia o que era Diagrama de Classes/UML/etc. Entao, no meu “pensamento relacional”, eu acabei fazer a Servlet cheia de JDBC/SQL direto, e achei que o codigo ficou organizado, pois sempre costumo criar classes para as diversas funcionalidades do sistema. Somente a “ponta do iceberg” é JDBC/SQL, pois a logica do negocio, cheia de objetos transientes, tem “momentos” de acesso ao BD. Pensando neste tipo de “sistema legado”, o “pensar relacional” é o “normal” de se fazer, ou tem alguma coisa a se ganhar com a camada de persistencia?

Outra coisa: se o codigo for bem organizado/legivel/extensivel deixando o JDBC “na ponta” apenas, entao posso dizer que a persistencia é desnecessaria?

Agora, da proxima vez que comecar um projeto do zero, acho que a ideia de persistencia pode ser realmente “um mundo melhor”, se eu “pensar objetos”, estou certo?

Codigo que, aos olhos do autor, eh organizado, nem sempre o eh aos olhos de outros - e, organizacao, apesar de ser uma otima qualidade, nao quer dizer que o codigo eh bem orientado a objetos. Da pra fazer sistemas organizadissimos em C, pq nao? :slight_smile:

Queria te propor um desafio: como voce faria um sistema desses SEM um banco de dados, so usando objetos e os relacionamentos entre eles? Imagine que voce nunca vai desligar a maquina, entao nao eh necessario salvar nada em disco. O ponto aqui eh que voce sofreu uma lavagem cerebral esses anos todos, e o seu pensamento esta engessado no modelo relacional… entao, pra usar legal orientacao a objetos, vc vai ter que esquecer um bocado de coisas primeiro :wink:

PS: calma, eu nao estou xingando nem nada. Foi a minha percepcao sobre a sua situacao atual. Se eu estiver errado, peco desculpas adiantado :smiley:

Yeap. Geralmente seu codigo fica mais limpo, extensivel e especialmente flexivel quando vc abstrai o banco de dados do seu sistema. Lembrando que “camada de persistencia” eh qualquer coisa que fala com uma outra coisa qualquer que sabe gravar dados. Ou seja, voce provavelmente esta fazendo as suas camadas de persistencia na mao, talvez atraves de Data Access Objects (DAOs - de uma lida sobre esse pattern, eh possivel que vc tenha aplicado ele, talvez sem nem saber ;)).

Se voce esta salvando dados em algum lugar, voce esta fazendo persistencia. Persistir, no sentido literal da coisa, eh resguardar dados de possiveis quedas do sistema. Se voce nao fizesse persistencia nenhuma, uma queda do seu sistema limparia a memoria dele, e ele nao teria nenhum dado guardado. :wink:

Sua ideia de fazer um projeto pensando como se tudo estivesse em RAM é boa. O que realmente esta me faltando é “limpar a minha RAM” de pensamento relacional. Talvez comecando um projeto do zero pensando em Diagrama de Classes seja o primeiro passo! Valeu!

[quote=“edilmar”]
Eu fico olhando os codigos que faco, usando SQLs diretos (é claro que usando aquele esquema de colocar os SQLs em arquivo de properties, que da uma limpada boa no codigo), e depois comparo com exemplos que fiz com o Hybernate, que tem que criar uma classe bean, arquivo XML, etc, etc, etc, pra fazer exatamente a mesma coisa: inserir/alterar/remover/consultar! Qual é de verdade, “caso exista”, o pulo do gato desta Camada?[/quote]

Ola edilmar

Eu também cheguei ter essa dúvida, pois acreditava que ficar fazendo arquivos XML, alguns Beans e etc, seria menos produtivo.
Mas quando eu fui fazer a coisa funcionar na prática, e com auxílio de outras ferramentas, eu ví que é bastante simples e produtivo (como o cv disse, produtividade não é apenas fazer o mais rápido possível).
Eu por exemplo, como eu monto meus Beans? simples… um simples diagrama de classe, cria seus Beans automaticamente a partir do seu modelo, o processo é bem rápido e simples, mais rápido do que ficar codificando todo seu Beans. AHHHHH!! Mas eu não uso UML, eu odeio UML, Morte a UML!!!
Tudo bem!! eu também não uso muito UML, apenas diagrama de classes para os Beans :wink: , mas uma outra solução rápida, no caso do Eclipse, seria você criar a classe, criar os objetos e mandar encapsular eles com os Getters e Setters, pronto, você tem um Bean de uma maneira rápida.

-Legal, mas e meus arquivos XML? ficar montando todos os arquivos de todos os beans é um saco!!!
Concordo, por isso temos outras soluções… Ant + Xdoclet cria os arquivos .hbm.xml para você, apenas um arquivo do ant, pode criar todos os arquivos .hbm.xml, através de simples comentário no seu código (se precisar eu posto um exemplo aqui).

Tendo os beans e os xml, falta apenas o DAO, que é bem simples de fazer… Geralmente não passa de 30 linhas de códigos e você usa o mesmo DAO para todo o sistema.

Agora com tudo isso pronto, armazenando as suas informações na memória com Beans e Collections, o que seria mais fácil com uma tabela de 30 registros:
:arrow: Montar um SQL enorme, por exemplo pra inserir dados na tabela, montar um Insert gigantesco ou…
:arrow: Fazer o código abaixo

DAO db = new DAO();
db.insert(MyBean);

Pronto, com os comandos acima as informações são gravadas :lol:

Agora, além do ganho de tempo, a manutenção é bem mais simples do que em um SQL, além de ficar muito mais claro para os outros programadores da equipe.

Junior, posta um exemplo sim…

Hibernate melhora muito tua produtividade pq simplifica maioria das tarefas chatas e sucetiveis a erros, como inserir/remover/atualizar/pesquisar. Alem de te darrecursos como caching e eager/lazy loading que ajudam em muito na performance da tua aplicação.

Outra coisa, eu gastei poucas horas dia para escrever 1 utilitariozinho que conecta em um banco, le a estrutura dele e gera todos beans e xmls necessarios. Isso me permite trabalhar ainda no modelo relacional enquanto gradualmente vou integrando os recursos de O/R avançados do Hibernate.

Mesmo sem utilizar relacionamentos, trabalhando no modelo relacional. O Hibernate, ou qualquer outra boa ferramenta de ORM, ajuda muito.

Eu tentei usar o hibernate esses dias e não deu muito certo…

Alguém sabe onde tem aquelas receitinhas de bolo pra bem iniciantes mesmo?

Que tal o tutorial aqui do GUJ? :slight_smile:

Eu fiz, mas chega uma hora que ele deixa uma dúvida assim.
Depois que ele cria o DAO, ele não mostra uma classe para testar tudo isso… e isso me deixa uma dúvida a respeito de como colocar pra rodar tudo isso… como ver resultado.

Edilmar,

Eu tb vim do “mundo” relacional…trabalho a 3 anos com oracle etb tive esta dificuldade. O problema comeca quando vc comeca a pensar o que fazer.
Ex. se vc tem uma tabela funcionarios e quer fazer cadastro nela a primeira coisa que eu pensave era em criar uma classe pra inserir, outra pra alterar, etc
E no “mundo” objeto vc pensa naum nestas 3 classes, mas sim em uma funcionarios e nela faz o que precisa.
Uma boa saida pra ti comecar a mudar a idéia é ler sobre padrões principalmente DAO.

[]'s

Fabio Patricio
Desenvolvedor Oracle/ Java

demorei mas vou postar :lol:

Bom, o que eu irei por como exemplo aqui, é um Bean e o uso do Xdoclet+Ant para gerar os arquivos .hbm.xml.
Se o seu problema for no funcionamento do Hibernate, esse exemplo não é para essa razão, mas ajuda na criação dos arquivos xml.

Arquivo Pessoas.java

/*Created on 05/01/2004*/
package br.com.junior.database;
/**
 * @hibernate.class table="Pessoas"
 * @author Junior
 */
public class Pessoas {
	private int ID;
	private String nome;
	/**
	 * @hibernate.id generator-class="native"
	 * @return
	 */
	public int getID() {
		return ID;
	}
	/**
	 * @hibernate.property
	 * @return
	 */
	public String getNome() {
		return nome;
	}

Esse aqui é um pedaço de um Bean, e nele que iremos colocar as tags para o Ant + Xdoclet fazer os arquivos .xml
os @hibernate, são as tags.
No começo eu informei qual classe esse Bean faz referência, depois falei qual o ID e depois o property.
Existem outras tags, que você pode ver na página do hibernate e do xdoclet. Mas o básico é essa ae mesmo.

Arquivo build.properties

xdoclet.dir = /mnt/servidor/ferramentas/xdoclet/lib
pacote = br/com/junior

Nota que o xdoclet.dir é o local onde estão as libs do xdoclet, no caso está em um servidor de arquivos, no diretório ferramentas/xdoclet/lib
o pacote é o pacote padrão que eu uso, por exemplo br.com.junior e dentro desse pacote terá um pacote chamado database onde eu armazeno meus Beans

Arquivo build.xml

<project name="Teste" default="generate.hibernate" basedir=".">
    <property file="build.properties"/>
    <path id="xdoclet.classpath">
        <fileset dir="${xdoclet.dir}" includes="*.jar"/>
    </path>
    <!--Target do Hibernate-->
	<target name="generate.hibernate" description="Gerar os arquivos .hbm.xml">
	    <!-- Tarefa do Hibernate -->
    	<taskdef name="hibernatedoclet"
        	classname="xdoclet.modules.hibernate.HibernateDocletTask">
	        <classpath>
    	        <fileset dir="${xdoclet.dir}">
        	        <include name="*.jar"/>
            	</fileset>
	        </classpath>
	   	</taskdef>
	    <!-- Executa a Tarefa do Hibernate -->
    	<hibernatedoclet
        	destdir="${basedir}"
	        excludedtags="@version,@author,@todo"
    	    force="${basedir}"
	        mergedir="${basedir}"
    	    verbose="false">
        	<fileset dir="${basedir}">
            	<include name="**/database/*.java"/>
	        </fileset>
	   	    <hibernate/>
	    </hibernatedoclet>
    	<!-- Muda de Hibernate 1.x para o Hibernate 2 -->
	    <replace dir="${basedir}">
	    	<include name="**/database/*.hbm.xml"/>
        	<replacefilter token="readonly=" value="inverse="/>
    	    <replacefilter token="role=" value="name="/>
	        <replacefilter token="hibernate-mapping.dtd" value="hibernate-mapping-2.0.dtd"/>
	    </replace>
	</target>
</project> 

dentro dele você irá ver o database, caso você queira trabalhar com outro folder para armazenar os Beans, é só alterar ae no build.xml.

Deixe os arquivos build.xml e build.properties na raíz do seu software, depois é só rodar o build.xml toda vez que você criar ou alterar um Bean e pronto!! seus arquivos .hbm.xml serão criados dentro do pacote, no local exato onde devem ser criados para o funcionamento do hibernate.

Outro detalhe, você pode usar outras ferramentas, como Maven + xdoclet, ou melhor ainda, o middlegen, esse por sinal é bem completo, você desenha suas tabelas em forma de diagrama, faz os relacionamentos, e depois manda gerar os xml, e com a maioria dos bancos de dados ele cria também a tabela. Vale a pena dar um olhada, eu fiz um teste básico com o mysql e funcionou normal, estou quase mudando minha forma de trabalhar atual, para o middlegen :wink: