Data Access Objects com DB4O
Implementar um sistema usando db4o eh definitivamente melhor do que usando qualquer banco relacional, usando hibernate ou não. Nao precisamos criar tabelas, configurar mapeamentos, configurar permissoes em arquivos, drivers etc...
Porem, devemos pagar um pequeno preço ao usar db4o: devemos criar as protecoes sobre violacao de campos únicos (2 produtos com mesmo codigo por exemplo), violacao de campos nao nulos, e violação de integridade ao deletar um objeto. (Também temos desvantagens em relação a falta de recursos de monitoramento e administração do banco de dados, mas discutiremos isso futuramente)
Podemos fazer isso na camada de acesso a Dados, usando o padrao DAO.
Veja como ficaria a super classe DAO (escrito em C#):
- Declaracao da classe: devemos criar uma classe abstrata generica.
public abstract class DAO<T> where T: new() - Metodos que fazem a checagem de restricoes de integridade devem ser sobrescritos pelo DAO de cada classe, caso contrario, simplesmente nao havera checagem:
protected virtual bool ChecarRestricaoChavePrimaria(T t){return true;}
protected virtual bool ChecarRestricaoCamposNaoNulos(T t){return true;}
protected virtual bool ChecarRestricaoDeDelecao(T t){return true;} - Salvando um objeto, deveremos checar se ele viola a restricao de chave primaria, e a de campos nao nulos:
public void Salvar(T obj)
{
ObjectContainer db = Server.GetServer().OpenClient();
try
{
if(!ChecarRestricaoChavePrimaria(obj)) throw new PKException(typeof(T).ToString());
if(!ChecarRestricaoCamposNaoNulos(obj))
throw new FieldNotNullException(typeof(T).ToString());
db.Set(obj);
}
finally
{
db.Close();
}
} - Metodo Recuperar Todos:
public List<T> RecuperarTodos()
{
ObjectContainer db = Server.GetServer().OpenClient();
Listlist = new List ();
try
{
T t = new T();
ObjectSet result = db.Get(t);
foreach(object item in result)
list.Add((T)item);
}
finally
{
db.Close();
}
return list;
} - Metodo Excluir: Devemos tomar cuidado com este metodo. Primeiro devemos definir se devemos operar com ou sem "Cascade". Segundo, devemos checar se, de acordo com as regras de negocio, se o objeto pode ser excluido. E por ultimo, devemos ter em mente que, para excluir o objeto desejado, devemos recuperalo antes, e passalo como parametro em db.Delete() - nao basta que seja um objeto complemente identico.
public void Excluir(T obj)
{
ObjectContainer db = Server.GetServer().OpenClient();
try
{
if(!ChecarRestricaoDeDelecao(obj))
throw new Exception("Violacao de restricao de integridade ao deletar objeto");
T found = (T)db.Get(obj).Next();
db.Delete(found);
}
finally
{
db.Close();
}
} - Eh recomendado que cada subclasse DAO implemente o metodo recuperar por ID, que nao eh generico visto que o ID pode ser composto por um atributo, dois atributos e por ai vai.
Talvez de para melhorar isso, se alguem tiver sugestoes, serao muito bem vindas!
Em breve, uma subclasse DAO e um exemplo de uso.
[]`s
Eduardo Rocha Monteiro
Um comentário:
Olá!
Eu tenho trabalhado com o bd4o utilizando também uma DAL.
A utilização do db4o desconectado (como descrito no exemplo) gera normamente algumas complicações, principalmente em objetos agregados. Os denomidados 'Transfer Objects', utilizados no padrão DAO, não podem ser simplesmente persistidos com um 'Set'. Na maioria das vezes precisa se quebrar o encapsulamento, violando assim a integridade do objeto. Acredito que isso seja um importante tema.
Obrigado, Sergio Aschar.
Postar um comentário