Persistência transparente, limitada, mas útil para CRUDs simples [RETOMADO]

26 respostas
saoj

Estava pensando em fazer um esquema de persistência assim:

public class User {
    
    private int _id;
    private String _username;
    private Date _regdate;
    
    // ...
    
}

Daí teríamos um código tabajara assim:

User u = new User(...);
tabajara.insert(u);

O insert do tabajara basicamente descobre todos campos privados que começam com ‘_’ e tenta improvisar uma query para insert.

Os tipos da variável teriam que ter um mapeamento padrão para os tipos do banco: int = Integer ; String = varchar ; e por aí vai.

O nome da tabela seria o nome da classe mais a letra s, ou, seria definido por uma variável privada _table.

private String _table = "users";

Observações:

  • É claro que isso é limitado pra caramba e só serviria para casos básicos. Mas não estamos cheios de casos básicos por aí onde isso poderia ser aplicado ?

  • É claro que com annotations tudo fica maravilhoso, só que estou falando de Java 1.4 aqui. Acho até que poderia ter uma versão 1.4 e uma 1.5 com annotations.

O que vcs acham disso ??? Seria reinventar o Hibernate ou há espaço para algo bem simples assim?

26 Respostas

Mauricio_Linhares

Isso tá parecendo com AR do Rails, mas eu não acho que seja um coisa tão necessária assim, CRUD é a parte mais simples da persistência, qualquer framework disponibiliza isso “de graça”, o complicado acontece quando começam as queries, é aí que você vai ver se o framework aguenta o tranco ou se vai deixar você na mão.

Mas se o cara não quer fazer mais nada além de CRUD grosseiro (o que é muito pouco provável na maioria das aplicações) pode ser uma boa opção.

saoj

Maurício Linhares:
qualquer framework disponibiliza isso “de graça”

Como assim ??? Eu sempre fiz isso na mão. :?

Aonde eu consigo isso “de graça” ???

Mauricio_Linhares

O Hibernate tem “save()”, “update()”, “delete()”, já deu tudo.

Rafael_Steil

Meio suspeito isso :).

Voce estara forcando um padrao de codificacao que foge bastante a convencao de codigo usada pela maior parte do pessoal e recomendada pela Sun. Alem do mais, como vc mesmo disse, eh uma solucao limitadissima.

Eh bastante questionavel essa feature.

Rafael

saoj

:lol: :lol: Hibernate não vale né Maurício !!! Se eu for usar o Hibernate essa discussão não faz o menor sentido. :wink:

Outra peguntinha:

Quando vc fala:

Por que vc diz que é pouco provável ?

Na maioria das minhas aplicações eu uso um CRUD grosseiro e faço todo o resto com JDBC.

Levando-se em conta que não quero usar o Hibernate, o que eu estou fazendo de errado ? Estou papando mosca em alguma coisa ?

Mauricio_Linhares

Mas é exatamente esse o problema Sérgio, pra quê ter isso? Por que eu usaria isso se eu já tenho uma ferramenta muito melhor pra resolver o meu problema?

Imagina que o cara começa a usar, aí chega a um momento que ele tem uma relaçao 1:1 com outro objeto, ele simplesmente não vai conseguir fazer isso funcionar. Será que ele ainda vai querer utilizar isso?

Agora, se você quizer fazer uma coisa simples e realmente interessante, indo nesse mesmo caminho de facilidade, bem que você poderia pensar no Active Record do Rails. É claro que não é o Hibernate (nem foi feito pra ser) mas é simples e já resolve um bocado de problemas, e você não vai forçar ninguém a seguir nada, campos private devem ser sempre isso, private.

Mauricio_Linhares

Ah, aí está o problema, você faz todo o resto com JDBC, eu faço todo o resto com o Hibernate e só uso JDBC quando é estritamente necessário, até porque eu posso definir uma query em SQL no Hibernate que ele mesmo cuida de transformar em um PreparedStatement e de manter em cache se eu mandar.

Pra mim, o maior problema de trabalhar com bancos é performance, e fazendo SQL “no braço” eu vou terminar trabalhando muito pra montar a persistência e depois vou ter que trabalhar mais ainda pra dar um tunnig nela. Já com o Hibernate, o grosso fica pronto num instante, o resto do tempo é só pra avaliar a aplicação, montar cache e queries SQL quando elas forem necessárias.

É muito mais produtivo, pelo menos pra mim :mrgreen:

saoj

Vc está completamente certo.

Para persistência a solução é o Hibernate, e não se fala mais nisso. :roll:

É que eu não gosto muito de ficar configurando os mapeamentos no XML do Hibernate. :roll:

Tem como fugir disso ???

Mauricio_Linhares

De um certo modo, nem eu… acho que conhecer AR me deixou meio baleado :lol:

Mas dê uma olhada no ActiveRecord Sérgio, talvez seja o que você está procurando :mrgreen:

M

Use o Hibernate com Annotations, estou usando aqui, e estou bastante satisfeito.

Mauricio_Linhares

Como é que se declara uma named query com annotations Mauro?

Rafael_Steil

XDoclet, mas isso eh bem pior do que fazer xml.

Se xml te incomoda tanto assi, faz uma tool em beanshell - vc configura o hibernate via script, que por sua vez gera o xml para vc :wink:

Rafael

M

Como é que se declara uma named query com annotations Mauro?

@NamedQuery

Rafael_Steil

lindo… e ai vc amarra todo o seu codigo com configuracoes de banco de dados… :roll:

Rafael

M

lindo… e ai vc amarra todo o seu codigo com configuracoes de banco de dados… :roll:

Rafael
Não entendi

Mauricio_Linhares

Nã, sou mais os arquivos XML mesmo…

Mauricio_Linhares

lindo… e ai vc amarra todo o seu codigo com configuracoes de banco de dados… :roll:

Rafael
Não entendi

Em vez de no arquivo .java só ter a sua classe, vai ter toda a configuração dela pro Hibernate, se você resolver não usar o Hibernate, ou a estrutra de annotations do Hibernate mudar, sua classe vai virar um maravilhoso espaguetti :mrgreen:

renatosilva

saoj:
É que eu não gosto muito de ficar configurando os mapeamentos no XML do Hibernate. :roll:

Tem como fugir disso ???

Digo o mesmo (apesar de nunca ter feito :smiley: ). E anotações como disseram acho que não é legal não. Eu tava pensando nos casos onde os nomes e atributos das classes correspondem exatamente às tabelas e campos do banco… talvez poderia-se fazer algo como você falou no início… num existir nem mapeamento… Resumindo: automatizar ao máximo.

saoj

Tenho uma solução que usei durante muito tempo.

Persistência através de herança.

Olhando o AR do Rails aqui: http://ar.rubyonrails.com/, percebo que ele faz o mesmo. :? :? :? :? :?

O problema desse approach é:

- Precisa de herança, logo não é totalmente transparente. (Isso raramente é um problema!)

- Também só serve para CRUD

É aquilo que eu falei: Se o cara quer só CRUD e vai fazer o resto com JDBC (sem mudar de idéia depois :D ), acho que hibernate é desnecessário, e até overkill.

Por isso que eu nunca usei Hibernate, pois só queo o CRUD.

Veja como fica bonito um objeto persistente:

package com.sellmate.beans.impl;

import java.util.*;

import com.sellmate.beans.*;
import com.smartjava.web.persistence.*;
import com.smartjava.web.persistence.db.*;
import com.smartjava.web.db.*;

public class DBInviteImpl extends DBPersistent implements Invite {
	
    private IntField id = new AutoIncrementField(this, "id", true);
	private StringField email = new StringField(this, "email");
	private IntField status = new IntField(this, "status");
	private BooleanField deleted = new BooleanField(this, "deleted");
	private DateTimeField senddate = new DateTimeField(this, "senddate");
	private IntField owner_id = new IntField(this, "owner_id");
	private IntField locale_id = new IntField(this, "locale_id");
	
	public static Invite getInstance() {
		return new DBInviteImpl();
	}
	
	protected DBInviteImpl() { }
	
	public ConnectionHandler getConnectionHandler() { 
		return DefaultConnectionHandler.getInstance("sellmate");
	}
	
	public String getTableName() { return "invites"; }
	
	public  		void			setId(int id) { this.id.setValue(id); }
	public  		int 			getId() { return id.getValue(); }
	
	public  		void	  		setEmail(String email) { this.email.setValue(email); }
	public  		String  		getEmail() { return email.getValue(); }
	
	public  		void			setStatus(int status) { this.status.setValue(status); }
	public  		int 			getStatus() { return status.getValue(); }
	public  		boolean 		isWaiting() { return getStatus() == Invite.WAIT_STATUS; }
	public  		boolean 		isAccepted() { return getStatus() == Invite.ACCEPTED_STATUS; }
	public  		boolean 		isOtherUser() { return getStatus() == Invite.OTHERUSER_STATUS; }
	
	public  		void			setDeleted(boolean deleted) { this.deleted.setValue(deleted); }
	public  		boolean 		isDeleted() { return deleted.getValue(); }
	
	public  		void			setSendDate(Date senddate) { this.senddate.setValue(senddate); }
	public  		Date			getSendDate() { return senddate.getValue(); }
	
	public  		void			setOwnerId(int profile_id) { this.owner_id.setValue(profile_id); }
	public  		int 			getOwnerId() { return owner_id.getValue(); }
	
	public  		void			setLocaleId(int locale_id) { this.locale_id.setValue(locale_id); }
	public  		int 			getLocaleId() { return locale_id.getValue(); }
	
}
louds

Usando Hibernate 3 você pode sobrescrever TODOs valores das anotation, inclusive acrescentar coisas a mais, via xml.

Ou seja, não tem galho.

M


Em vez de no arquivo .java só ter a sua classe, vai ter toda a configuração dela pro Hibernate, se você resolver não usar o Hibernate, ou a estrutra de annotations do Hibernate mudar, sua classe vai virar um maravilhoso espaguetti :mrgreen:

Não é nao, a configuração de banco, continua num XML, e a estrutura de Annotations, segue o padrao EJB3 de persistencia. Onde outros frameworks de persistencia, estarão seguindo a mesma linha, ou seja, nao estara atrelado ao Hibernate. Eu sei que a especificação do EJB3 nao saiu e pode ter mudanças nas annotations de persistencia, mas eu acho q vale a pena.

pcalcado

Sergio. a sua ideia tb nao eh transparente, voce vai rpecisar de um .save() no final :wink:

saoj

pcalcado:
saoj:

  • Precisa de herança, logo não é totalmente transparente. (Isso raramente é um problema!)

Sergio. a sua ideia tb nao eh transparente, voce vai rpecisar de um .save() no final ;)

O save viria do DBPersistent, isto é, vc nunca vai precisar implementar o save. Vai simplesmente chamar:

invite.save();

Conversando com o Rafael, acho que dar um jeito de usar um esquema de gerar o XML do Hibernate automaticamente seria a melhor solução:

Algo como isso:

http://today.java.net/pub/a/today/2005/06/23/trails.html

pcalcado

saoj:
Vai simplesmente chamar:

invite.save();

Sim, mas numa persistencia transparente nem isso voce precisa fazer :wink:

renatosilva

Sérgio, não acho que serviria só pra CRUD, se é que eu sei o que é CRUD :smiley:

E, deixa eu ver se entendi, você tem uma classe persistente genérica e a especializa com sua lógica de negócios?

louds

O hibernate vem com uma ferramenta que conecta numa base de dados e vomita um monte de VOs e xml, isso para mim é mais que o suficiente para “CRUD simples”

Criado 13 de julho de 2005
Ultima resposta 13 de jul. de 2005
Respostas 26
Participantes 7