Uso o db4o em 02 projetos pequenos, estou satisfeito com os resultados. Mas ainda espero que no futuro queries complexas nesses bancos sejam feitas de modo menos trabalhoso.
Eu uso o db4o desde a versão 5.4. Realmente a parte de queries complexas dão um pouco de trabalho, mas queries complexas no sql ansi também dão :-). Atualmente não estou mais trabalhando com ele, mas na época atendeu muito bem. A última versão 7.0 beta também está muito boa, principalmente a parte de desempenho.
Também gostaria de saber se vale a pena usar esse tipo de banco. Estou cansado de usar Hibernate. Alguém pode relatar vantagens e desvantages? Ficaria muito grato…
não há necessidade de mapear seus objetos para o paradigma relacional. Assim, vc tb não tem limitações no seu modelo de objetos de negócio. Simples cria seus objetos de negócio e manda persistir. Isto traz muita produtividade pois vc se concentra na sua lógica de negócio.
Os relacionamentos são automáticos pois são definidos nos seus objetos
Refactoring : Alguns bancos OO possuem Refactoring automático. Ou seja, vc alterou uma classe persistente, o BD se ajusta sozinho. Obviamente, algumas situações não poderam ser tratadas automaticamente e haverá necessidade de refactoring manual
Apesar de não ser uma vantagem dos BD OO, mas muitos dos BDs OO funcionam em Modo embarcado(embedded) e/ou Client/Server. O modo local permite usar o BD junto com a sua aplicação sem a necessidade de instalação de servidor. Isso pode ser uma vantagem interessante quando é necessário distribuir uma aplicação Desktop ou até para uma aplicação Web onde vc não controla o ambiente de execução.
Em modo embedded, vc consegue uma performance superior e em geral um tamanho de biblioteca inferior a 500Kb. Se vc usa Hibernate para acessar um banco relacional no minimo vc tem 3Mo de jars. Com esses BD OO (como NeoDatis) o runtime é menor que 400K. As vezes faz a diferença.
Algumas desvantagens :
Fica dificil ter uma equipe que cuida do banco e outra do desenvolvimento pois o modelo do banco de dados acaba sendo o modelo de negócio.
Bancos relacionais que estão há mais tempo no mercado devem ser mais robustos e confiáveis.
O mais importante ao meu ver é Simplicidade e Produtividade. Qdo começa a trabalhar com um BD OO como NeoDatis ODB ou DB4O e que tem que voltar a usar Hibernate para acessar um banco relacional, vc fica triste .
Já tive que migrar uma aplicação que eu tinha feito com NeoDatis ODB para Hibernate/Oracle. Muitas coisas são simples mas quando começa a ter que mapear relações 1-n e n-n, vc percebe a diferença.
No banco OO, vc não precisa usar chave para seus objetos. O próprio banco se encarrega de criar um OID (Object ID) para cada objeto.
Mas em alguns casos vc pode precisar identificar o objeto de maneira única e o seu objeto não tem chave natural (que é o caso que vc citou da transação). Neste caso, vc pode pedir ao banco o OID do(s) objeto(s).
Um caso comum para isso é numa consulta WEB onde vc mostraria todas as transações e onde o usuário poderia clicar em uma das transações para ver o seu detalhe ou alterar a mesma. Nesse caso, eu aconselho usar o OID do BD. No NeoDatis ODB vc tem um método ODB.getObjectId(Object o) que te retorna o OID do objecto no banco (uma vez que o mesmo já tinha sido persistido no BD).
Vc depois pode recuperar um objeto pelo OID a qualquer momento mesmo em outra transação usando ODB.getObjectFromId(OID oid).
Sobre Views e Stored Procedure não sei responder para todos os BD OO, Eu sei NeoDatis ODB ainda não suporta e acho que Db4O também não. NeoDatis ODB suporta triggers.
Com relação a relatórios, vai depender da ferramenta. Se não me engano, se vc usa JasperReport, vc pode passar um Model que contém os objetos (não tenho certeza disso)
Dei uma pesquisada nas páginas desses bancos, o NeoDatis não tem suporte oficial a .net ainda, o Db4O já tem…
Atualmente trabalho com .net (todos produtos MS), todos os relatorios q o pessoal do BI faz usa o Reports da MS mesmo…
Exemplo: Com a transação lá, vou fazer uma modificação na classe/tabela
class Transacao{
idTransacao
idCliente
Data
Valor
}
É possível fazer um somatório de todas as transações de um cliente em determinado periodo de maneira simples? No relacional isso é até sem graça de fazer. \o/
–Editado–
Como o banco trata esse retorno dessa função/procedure?? No relacional ele volta um datareader ou dataset e você se vira, no relaciona ele retorna um objeto?? Ele tem que carregar a coleção dessas transações para fazer a soma?
realmente BDOO não são muitos bons nesses tipos de query pois eles trabalham com objetos e a suma de um dos atributos acaba fugindo do conceito do objeto
Mas vc tem razão isso é importante.
O NeoDatis ODB tem um recurso para isso : O Trigger AfterSelect.
vc pode registrar um trigger chamando o ODB.addSelectTrigger( ISelectTrigger trigger );
Esse trigger irá receber todos os objetos selecionados e ai vc faz o que quiser em Java, por exemplo soma o valor da Transação. No nosso exemplo o trigger seria assim:
public class SumTrigger implements ISelectTrigger {
private double totalValue;
public void afterSelect(Object object, OID oid) {
Transaction t = (Transaction) object;
// Soma o valor da transação ao valor total
totalValue+=t.getValue();
}
public double getTotalValue() {
return totalValue;
}
}
Até testei para se funcionava e funcionou.
o código principal seria assim :
public void test1() throws Exception{
ODB odb = null;
try{
// abre o banco
odb = open("trigger-sum.odb");
double sum = 0;
for(int i=0;i<1000;i++){
// cria 1000 objetos de tipo Transaction
odb.store(new Transaction(10,i));
sum+=i;
}
// Fecha o banco
odb.close();
// Abre o banco
odb = open("trigger-sum.odb");
// Adiciona o Tigger AfterSelect no engine ODB
odb.addSelectTrigger(new SumTrigger());
// executa a query
Objects objects = odb.getObjects(new CriteriaQuery(Transaction.class,Where.equal("clientId", 10L)));
// Mostra o valor calculado pelo trigger
System.out.println("Valor total = " + trigger.getTotalValue() +" - " + sum);
assertEquals(String.valueOf(sum), String.valueOf(trigger.getTotalValue()));
}finally{
if(odb!=null){
odb.close();
}
}
}
Agora, vc tem razão, fazendo isso, o ODB acaba lendo todas as instâncias que atendem a query. Poderia ser otimizado para só ler o valor que está sendo somado. Provavelmente numa próxima versão terá uma otimização para isso
Muito interessante ver o desenvolvimento dos bancos de dados OO. Pretendo usar algum em um sistema pequeno somente como experiência… mas acredito que pra sistemas grandes os bancos OO ainda não atingiram um nivel de maturidade suficiente.
Espero que não demore muito para que esses bancos atinjam um nível de desempenho aceitável.
Uma coisa que não entendi é, tendo um banco de dados OO, a existência de procedures não acaba indo contra a idéia da OO? Hoje com as ferramentas O/R eu não utilizo nenhuma procedure nem triggers. O meu banco serve somente para armazenar dados.
Depende da performance que você quer… no meu sistema atual eu coloco o máximo de coisas possíveis no Banco, precisamos do processamento.
Para mapeamento O/R uso o .netTiers (www.nettiers.com) e ele mapeia para mim as procedures tb, que acesso como se fosse uma função do DataProvider. Muito produtivo. (;
Trigger eu nunca gostei porque não é tão performático no banco, então não posso usar.
Uma StoredProcedure num BDOO acaba sendo um método de uma classe Java/.Net que será executado no servidor remoto em vez do cliente.
Com relação a Trigger por exemplo, estamos usando Trigger do NeoDatis ODB para implementar uma base de dados MultiMedia onde vc grava um objeto de tipo MultiMediaFile e um trigger, de maneira transparente para vc, irá tratar o arquivo em background.
E como funciona o carregamento dos atributos do objeto? O Hibernate tem o lazy, por exemplo. Carrego um objeto e os subobjetos são carregagos somente quando invoco. Como funciona no NeoDatis?