Tenho a mania de trocar poder por simplicidade. As vezes isso me ajuda, as vezes atrapalha. Mas uma coisa eu não tenho dúvida: Aumenta e muito a produtividade!
A complexidade e o receituário de EJB me deprimem.
Hibernate eu não conheço muito ainda, mas já dei uma olhada e achei legal. Entretanto eu tenho uma outra mania que é não gostar de arquivos de configuração, principalmente arquivos XML. Será que um dia haverá programadores que não precisam programar, mas apenas configurar arquivos XML ??? Essa idéia não me agrada e embora um arquivo de configuração XML traga flexibilidade eles acabam cortando o meu prazer de programar.
Então para a minha camada de persistência (Objetos -> DB) eu resolvi escrever meu próprio framework o mais simples possível e sem arquivos de configuração.
Apesar de simples, ele fornece o indispensável, por exemplo, ele só faz update dos campos que foram modificados, suporta transações, entre outras coisas.
O que vcs acham? Uso esse DBBean (veja código abaixo) ou melhor aprender Hibernate e começar a configurar os arquivos XML ???
import java.sql.SQLException;
import com.smartjava.dbbean.DBBean;
import com.smartjava.dbbean.DBField;
import com.smartjava.dbbean.DBType;
import com.smartjava.dbpool.ConnectionHandler;
public class Profile extends DBBean { // ou MySqlDBBean ou OracleDBBean
private static final ConnectionHandler connHandler = ConnectionHandler.getInstance("profile");
private DBField id = new DBField(this, DBType.AUTOINCREMENT, "id", true);
private DBField username = new DBField(this, DBType.STRING, "username");
private DBField deleted = new DBField(this, DBType.BOOLEAN, "deleted");
public Profile() {
super.setConnectionHandler(connHandler);
}
// função abstrata obrigatória...
public String getTableName() { return "profiles"; }
public void setId(int id) {
this.id.setValue(id);
}
public int getId() {
return id.getIntValue();
}
public void setUsername(String username) {
this.username.setValue(username);
}
public String getUsername() {
return username.getStringValue();
}
public void setDeleted(boolean deleted) {
this.deleted.setValue(deleted);
}
public boolean isDeleted() {
return deleted.getBooleanValue();
}
public static void main(String [] args) throws SQLException {
Profile p1 = new Profile();
p1.setId(1);
p1.setUsername("soliveira");
p1.insert();
Profile p2 = new Profile();
p2.setId(1);
if (p2.load()) {
System.out.println("USERNAME: " + p2.getUsername());
}
p2.setUsername("saoj");
p2.update();
Profile p3 = new Profile();
p3.setId(1);
if (p3.load()) {
System.out.println("USERNAME: " + p3.getUsername());
}
p3.delete();
}
}
A vantagem de usar frameworks hype é que, como todo mundo o conhece, fica mais facil você entrar em outros projetos ou outros entrarem no seu projeto.
Desenvolver o próprio framework é um ótimo exercício. Mas para virar um framework com alguma utilidade é preciso escrever um monte de documentos, how-tos, faq, user guide, 1-minute/2-hours/3-days introductions, etc. Esse é apenas parte do tamanho da encrenca. A outra parte é encontrar gente e projetos para validar o framework.
Uma outra consideração é que simplicidade é bom até que não atende um determinado caso e precisa de um puxadinho. Mais ou menos como acontece com casa de pobre. A idéia de configurações externas em xml ou não facilitam a expansão do framework sem precisar escarafunchar o código para ver onde há interferências.
Putz, faltou falar que o que fez parece bonitinho.
A vantagem de usar frameworks hype é que, como todo mundo o conhece, fica mais facil você entrar em outros projetos ou outros entrarem no seu projeto.
[/quote]
Acho mais fácil capacitar minha equipe nesse framework mínimo aí em cima do que no Hibernate. Acredito que a produtividade com o DBBean vai ser bem maior do que com o Hibernate. Mas posso estar enganado.
O objetivo não é criar um framework público e sim resolver o meu problema que é: preciso de uma solução simples e eficiente para persistir meus objetos no DB. PRECISO DE PRODUTIVIDADE, ISTO É, O PROJETO É PRA ONTEM !!!
Quando precisar de um puxadinho, isso será feito por fora do framework. Não estou falando de hacks pelo código, mas com a OO e herança vc pode ir fazendo especializações. (Vide MySqlDBBean.java abaixo)
Eu poderia ter criado um arquivo XML para definir os campos do meu bean, aí se eu quisesse incluir ou alterar algum campo eu não precisaria recompilar o código. ISSO É CHATO DEMAIS. Como programador eu prefiro fazer isso:
private DBField id = new DBField(this, DBType.AUTOINCREMENT, "id", true);
private DBField username = new DBField(this, DBType.STRING, "username");
private DBField deleted = new DBField(this, DBType.BOOLEAN, "deleted");
Valeu !!!
package com.smartjava.dbbean;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public abstract class MySqlDBBean extends DBBean {
public void insert(Connection conn) throws SQLException {
super.insert(conn);
DBField f = getAutoIncrementField();
if (f == null) return;
PreparedStatement stmt = null;
ResultSet rset = null;
try {
StringBuffer query = new StringBuffer(100);
query.append("select last_inserted_id() from ");
query.append(getTableName());
stmt = conn.prepareStatement(query.toString());
rset = stmt.executeQuery();
if (rset.next()) {
int id = rset.getInt(1);
f.setValue(id);
}
} finally {
try { stmt.close(); } catch(Exception e) { }
try { rset.close(); } catch(Exception e) { }
}
}
}
Bem interessante o teu framework mas ele parece atar demais as classes de modelo de forma intrusiva. Eu particularmente gosto de frameworks tão pouco intrusivos quanto possivel. O Hibernate é assim, o OJB parece ser tambem. Se vc não gosta de escrever codigo XML, uma boa pedida seria escrever tags XDoclet e deixar uma tarefa do Ant fazer o resto do serviço.
Antes de mais nada, eu daqui em diante declaro que esta thread nao mais conterá a palavra ‘framework’. Só pq eu posso. :mrgreen:
Gostei bastante da ideia, saoj, mas… (sempre tem um ‘mas…’, ou ninguem teria partido para solucoes de implementacao bem mais complexa como o Hibernate):
:arrow: Voce esta fazendo relacionamentos, queries e tudo mais na unha. Isso ta longe de ser produtivo, e eh esse um dos problemas mais dificeis que o hibernate resolve.
:arrow: Estender DBBean, MySQLDBBean ou o que for eh simplesmente impraticavel. Se voce nao se deu conta do estrago que isso faz, tente fazer um sistema com um domain model maiorzinho
:arrow: Singleton no ConnectionHandler. AAAAAAAARGH! O JUnit acabou de chorar, ali no cantinho.
:arrow: DBType: pra que ter constantes (AUTOINCREMENT, STRING, etc e tal), se vc poderia ter AutoIncrementType, StringType, etc e tal? O problema, eh claro, que em nenhum dos casos vc esta levando em consideracao tipos customizados. Mas ateh aih, pouquissima gente (ehrhm, eu) usa custom types.
:arrow: O que acontece se eu precisar pegar um porrilhão (vamos entender que ‘porrilhão’ é um número beeeeeeem grande) de registros? Como voce implementaria lazy-loading num modelo desses?
Me explica melhor o que vc quer dizer com intrusivo ???[/quote]
Sergio, vc teve que atar seu modelo ao esse tipo de implementação. Mesmo mantendo os metodos de acesso com tipos primitivos, a implementação está emparelhada com o framew… uops, erhm, do que eu vou chamar agora? Note por exemplo o metodo chamado getTableName() que é obrigatorio. Por que seu modeo deve conhecer a forma de persistencia? Bom, compare com uma classe de dominio assim:
import java.io.Serializable;
public class Profile implements Serializable {
private int id;
private String username;
private boolean deleted;
public void setId(int id) {
this.id.setValue(id);
}
public int getId() {
return id.getIntValue();
}
public void setUsername(String username) {
this.username.setValue(username);
}
public String getUsername() {
return username.getStringValue();
}
public void setDeleted(boolean deleted) {
this.deleted.setValue(deleted);
}
public boolean isDeleted() {
return deleted.getBooleanValue();
}
}
Valeu pelas dicas !!! O objetivo do meu post era esse mesmo: ouvir críticas para pesar os dois lados da moeda na minha cabeça.
Relacionamentos eu não utilizo a nível de código, apenas a nível de DB. Então acho que isso não seria um grande problema pra mim. Já as queries eu realmente tenho que fazer na unha, mas isso não me incomoda muito. Alguma coisa eu tenho que fazer na unha mesmo !!! O Hibernate tem uma query language para fazer queries de objetos, né ??? Deve ser legal, mas não conheço nada dela. Já SQL para fazer queries está no sangue. É quase automático!
Tem uma idéia que não é minha que é fazer um ListLoader. Basicamente quando vc quer carregar um conjunto de objetos persistentes (DBBeans) vc encapsula a sua query dentro de um ListLoader e ele te retorna um Array ou uma List de DBBeans.
Não consegui te acompanhar aqui. A idéia do mysqldbbean é que cada banco tem sua especialidade, principalmente no caso de autoincrement. (claro que vc já sabia disso! )
Logo vc pode especializar o DBBean para cada banco. DBBean usa ANSI SQL + JDBC para fazer a persistência, logo funciona em qualquer banco!
:ConnectionHandler encapsula dentro dela um pool de conexões. Assim como cada pool de conexões deve ser um singleton, cada connection handler para aquele pool tb deve ser um singleton. Mas posso estar errado!
Ou na mão.
Ou através do ListLoader. Outra idéia boa, que tb não foi minha, é do mesmo jeito que vc tem um load(conn) vc pode ter um load(rset).
Então vc pode carregar um monte de DBBeans na mesma query:
select * from profiles where city = 1;
List list = new LinkedList();
while(rset.next()) {
Profile prof = profileFactory.createProfile();
prof.load(rset);
list.add(prof);
}
Vc tem toda razão que o fw ficaria mais profissional se não se atasse ao banco de dados explicitamente, como eu fiz.
Mas isso aumentaria MUITÍSSIMO a trabalheira para implementar as entranhas desse modelo.
Focando em Banco de Dados, eu consigo fazer um framework sem bugs, simples, enxuto e eficiente.
O DBBean é apenas para Banco de Dados !!! Se vc quiser que o seu profile venha do disco, por exemplo, esse fw não te atende. Mas o Hibernate tb não, né??? O hibernate é especificamente para persistencia em DB, né?
Fico feliz por ver que as pessoas não estão simplesmente abaixando a cabeça e aceitando os hypes como soluções definitivas. Mas acho que sua solução foi uma volta ao passado em relação aos mapeadores O/R por todos os motivos que o CV (sem falar que escrever SQL dentro dó código me dá nojo!). Ok, você não gosta de escrever “heurísticas” em XML? Ótimo! Veja como é implementado o mecanismo de leitura de configurações do Hibernate (por exemplo) e proponha a utilização de alguma outra solução (DICA: Bean Shell, usado pelo DynAOP, ou Groovy podem ser soluções bem mais elegantes). Mas acho que o mundo pode dormir melhor a noite sem mais outra explosão de mecanismos O/R surgindo por aí.
[Pascoale]voce pode comecar a nao utilizar ‘a nivel de’, pq a nivel de escrever certo, eh bem errado.[/Pascoale]
Se voce nao utiliza relacionamentos, entao onde voce jogou a OO!? Se eu nao posso fazer um Estoque referenciar Produtos, voce acabou de inventar o problema, nao a solucao.
O Hibernate tem uma query language bastante flexivel e pratica. Envergonhe-se de tentar bolar uma solucao alternativa, sem conhecer seu concorrente primeiro
Tem isso no iBatis e no Spring. De uma olhada neles.
[quote=“saoj”]
:ConnectionHandler encapsula dentro dela um pool de conexões. Assim como cada pool de conexões deve ser um singleton, cada connection handler para aquele pool tb deve ser um singleton. Mas posso estar errado![/quote]
Singleton é errado, e não tem desculpa, a menos que vc esteja falando de um recurso que realmente nao pode existir mais de uma vez - por exemplo, uma porta serial. Vide inumeros posts aqui no GUJ sobre isso.
Vide injecao de dependencias, vide unit testing, vide um monte de boas praticas que o design do seu ConnectionHandler nao seguiu ao fazer isso
Existe uma linha muito tenue entre simplicidade e simploriedade. O que voce propos com os DBBeans eh simplorio: ele simplifica alguns casos, e impossibilita a maioria dos outros, enquanto o Hibernate, apesar de ser uma solucao mais complexa que a sua, eh simples: ele facilita os casos mais comuns, e mantem todos os outros nao soh mais faceis, como tambem possiveis.
Claro!!! Nunca tive a pretensão de competir com o Hibernate. Só quiz fazer o DBBean para resolver de uma maneira bem simples o problema de mapeamento Objeto => DB. O Hibernate resolve esse problema também, de maneira simples, mas não tão simples quanto o DBBean. Em compensação ele te oferece um monte de outras facilidades que o DBBean nem pensou.
O próprio livro que eu recomendei enaltace o Hibernate. Vou procurar estudar mais a fundo o Hibernate, que parece ser a melhor saída para não usar EJB em 90% dos projetos.
Outra coisa que ele fala bastante nesse livro é: “Do one thing, Do it well!”
O DBBean só serve para persistir objetos num banco de dados, de maneira intuitiva, simples e eficiente. E isso ele faz muito bem através de uma API mínima. Dependendo da complexidade do seu projeto e dos skills do seu time, ele pode ser uma opção viável.
O meu último post acabou ficando fora de foco, no meio dessa discussão sobre persistência.
O recado que eu quiz passar, e que é passado nesse livro tb, foi:
Não interessa o que vc faça, faça da maneira mais simples possível. Evite usar uma bazuca para matar uma mosca. Simplicidade é poder!
Creio que mais de um filósofo já disse: a simplicidade é de ouro (traduzindo: a simplicidade é algo muito valioso).
Por outro lado, construir um framework à medida do que seja necessário ao momento pode levar ao risco de em pouco tempo ter-se uma verdadeira colcha de retalhos, por não ter havido um planejamento desde o início considerando futuras necessidades. Além disto há a questão da padronização, cuja utilização em escala facilita ainda mais a manutenção do código que o utiliza, bem como a própria expansão do framework adotado ou desenvolvido.
Mas também creio que alguns frameworks do mercado possam ser mais complexos do que o necessário - mesmo que sejam extremamente flexíveis, será que são necessários para a grande maioria dos casos ?
Assim, será que no mercado já não exista algum framework que seja razoavelmente simples e eficiente, além de ser útil em boa parte dos problemas dentro de seu domínio? Ou, que seja simples para utilização na maioria dos casos, deixando a complexidade para os problemas já normalmente complexos?
Sei que diretamente o que vou falar não diz muito respeito a discução. Mas o SAOJ irá entendeu o que eu quero falar.
Eu trabalho com DB (entenda-se SQL) a 3 anos, sempre ouvia falar do Hibernate, mas insistia em escrever meus SQL pois achava que eu teria mais performance com isso. Foi um tempo perdido, hoje vejo isso.
Quer ter simplicidade com Hibernate, monte uma boa arquitetura de com ele e não se preocupe mais com isso, ou se preocupe mas quando surgir um caso muito especial.
É comum a gente ver consultas SQL mal feitas porque o programador nem sempre conhece bem tecnologias envolvendo base de dados. Para mim esta é uma das grandes vantagens dos mapeamentos O/R.
E quando a gente vê um cara como o Fábio que sabe tudo de Oracle dizendo que é melhor usar Hibernate então não dá mais para ter dúvida. Hibernate neles!
Simplicidade importa muito mesmo e em alguns momentos Java peca nisso se comparada a outras coisas. Por exemplo, como fazer o Apache ter suporte a Java? Se for comparado a coisas como Perl, PHP, Python fica bem pra tras em termos de facilidade de comparação. Lembro que, quando comecei a aprender patterns, queria aplica-los em tudo quanto era canto porque, enfim, eu acreditava que era a coisa certa. Hoje é Do The Simplest Thing That Could Possibly Work e pronto! Nada de 10 camadas para escrever um HelloWorld.
Quanto ao Hibernate, ele é simples mesmo e boas ide’s já têm algum tipo de suporte para xdoclet. Assim vc não tem que escrever os seus XML na marra. Vale uma olhada no HiberClipse tambem.