terça-feira, 14 de abril de 2009

Tagged under: , , ,

Persistência orientada a objetos com db4o (parte 3)

Demorei um pouco mas consegui arranjar mais um tempinho para continuar a escrever sobre o DB4O. No post anterior vimos, dentre outras coisas, uma das formas de consultar dados no banco de dados, o modo Query By Example (QBE). Agora vamos ver como recuperar os objetos através da SODA API Query.

Para entender o funcionamento da SODA API, tenha em mente um grafo que será construído com os métodos da API a partir de um nó raiz. Primeiro, obtemos a raiz do grafo assim:

Query queryRoot = db.query();

Os demais nós do grafo são as restrições (constraints) de nossa consulta. Os demais métodos da SODA API servirão para criar caminhos da raiz a estes nós. Na linha abaixo, o que está sendo criado é uma restrição na consulta para todos as instâncias da classe Contrato.

queryRoot.constrain(Contrato.class);

Para facilitar a visualização, o grafo da consulta nesse ponto seria parecido com a imagem abaixo.


Algumas vezes é necessário restringir a consulta por algum dos atributos do objeto; para isso, existe um método que "desce" na hierarquia de associações e cria outro nó no grafo da consulta. Crie uma classe chamada Passo5 com o código a seguir. O que faremos nesse código é "descer" até o atributo numero do objeto Contrato e restringi-lo a uma instância de Integer com valor 1000.


package javabahia.app;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Query;
import javabahia.entidade.Contrato;

/**
* Quinto passo de execução do teste com o db4o.
* @author Alexandre
*/

public class Passo5 {

public static void main(String[] args) {
// abrindo o arquivo db4o
ObjectContainer db = Db4o.openFile("javabahia.dbo");
try {
// criando uma consulta via SODA API
Query queryRoot = db.query();
queryRoot.constrain(Contrato.class);
queryRoot.descend("numero").constrain(1000);
// invocando a consulta
ObjectSet<Contrato> result = queryRoot.execute();
// listando os objetos encontrados
System.out.println(result.size() + " objetos foram encontrados.");
for (Contrato ctr : result) {
System.out.println("Contrato número " + ctr.getNumero());
}
} finally {
// fechando o arquivo db4o
db.close();
}
}
}


O código do Passo5 é equivalente ao código que executamos na classe Passo2, e deve retornar o mesmo resultado quando for executado. Se tivéssemos que visualizá-lo na forma de um grafo, seria parecido com a imagem abaixo.


Alguns tipos de consulta não são possíveis de serem feitas com a forma QBE, somente com a SODA API. Por exemplo, como seria o código para filtrar os contratos que foram assinados neste mês de Abril? E mais ainda, ordenar esses resultados pelo número do contrato. A solução está na classe Passo6 abaixo:


package javabahia.app;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Constraint;
import com.db4o.query.Query;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javabahia.entidade.Contrato;

/**
* Sexto passo de execução do teste com o db4o.
* @author Alexandre
*/

public class Passo6 {

public static void main(String[] args) {
// abrindo o arquivo db4o
ObjectContainer db = Db4o.openFile("javabahia.dbo");
try {
Date inicio = (new GregorianCalendar(2009, Calendar.APRIL, 1)).getTime();
Date fim = (new GregorianCalendar(2009, Calendar.APRIL, 30)).getTime();

// criando uma consulta via SODA API
Query queryRoot = db.query();
queryRoot.constrain(Contrato.class);
Constraint c1 = queryRoot.descend("dataAssinatura").constrain(inicio).greater();
Constraint c2 = queryRoot.descend("dataAssinatura").constrain(fim).smaller();
c1.and(c2);
queryRoot.descend("numero").orderAscending();

// invocando a consulta
ObjectSet<Contrato> result = queryRoot.execute();
// listando os objetos encontrados
System.out.println(result.size() + " objetos foram encontrados.");
for (Contrato ctr : result) {
System.out.println("Contrato número " + ctr.getNumero());
}
} finally {
// fechando o arquivo db4o
db.close();
}
}
}


Dessa vez guardamos as restrições nos objetos chamados c1 e c2, e depois os unimos através do método and(). A SODA API permite fazermos qualquer coisa que conseguiríamos fazer usando SQL num banco de dados relacional.

Hoje vou ficando por aqui. Espero em breve retornar trazendo mais códigos de exemplos de funcionalidades do DB4O. Até lá!

2 comentários:

Hellen disse...

Olá, boa tarde.
Trabalho na AIESEC Salvador e estamos com o processo seletivo aberto para Intercâmbio Profissional na área de tecnologia da Informação. Se possivel me passe o email de vocês para que eu possa mandar os releases e as peças de divulgação. Agradeço desde ja, Hellen Boaventura (hellen.aiesec@gmail.com)

Bruno disse...

Excelente explicação.
Obrigado