Olá pessoal,
Neste artigo, irei comentar um pouco sobre o FlexORM. Este framework tem como objetivo o mapeamento objeto-relacional em projetos que utilizem AIR e base de dados embarcada (SQLite).
O FlexORM é uma criação de Mark Moloney, e é hospedado pela RIAForge.
O FlexORM tem suporte a versão 1.5 do AIR e abaixo, podemos listar algumas de suas vantagens para seu uso:
* Não há necessidade de criação e atualização de tabelas. O FlexORM se encarrega da criação da estrutura do banco, através de um mapeamento feito dentro do próprio objeto a ser persistido;
* Possui suporte as operações CRUD;
* Suporta associações 1:N, N:M, N:1 e 1:1;
* Suporte a atributos transientes;
* Suporte a constraints para consistência de chaves-estrangeiras, através de triggers do SQLite;
* Transações;
* Criação automática de índices;
* Lazy Loading;
* Dentre outras;
Para exemplificar o uso do FlexORM, irei criar um projeto chamado DuckToDo e o objetivo do projeto é que eu possa cadastrar algumas tarefas que eu precise realizar. A aplicação é bem simples no quesito visual, uma vez que o intuito do artigo é o conhecimento do FlexORM.
Para iniciar, iremos criar um projeto no FlexBuilder chamado DuckToDo, conforme a tela abaixo:

Em seguida, vá as propriedades do projeto, e na opção Flex Compiler, adicione a seguinte linha de comando “ -keep-as3-metadata+=Table,Id,Column,ManyToOne,OneToMany,ManyToMany,Transient”, para que o compilador interprete as Metadatas adicionadas ao mapeamento dos Beans, conforme tela abaixo:

Feito isso, você deve fazer o download do FlexORM e adicionar ao seu projeto. Você pode optar por fazer o download do source através de um servidor de versionamento (subversion), ou fazer o download através deste link do arquivo .SWC do projeto FlexORM.
Depois de obter o .SWC, ou por download, ou recompilando o projeto, você deve adicioná-lo a pasta lib/ de seu projeto.
Feito isso, criaremos nossa classe de objeto que será persistida pela nossa aplicação.
Crie uma nova classe actionscript na package “org.flexduck.model” chamada Todo, e adicione o código abaixo:
package org.flexduck.model
{
[Bindable]
[Table(name="TODO")]
public class Todo
{
[Id]
public var codigo : int;
[Column(name="titulo")]
public var titulo : String;
[Column(name="descricao")]
public var descricao : String;
}
}
Neste momento, quem trabalha com Java e utiliza Hibernate ou JPA já percebe uma grande semelhança. Através da Metadata [Table] no escopo da classe, definimos a qual tabela este objeto deve ser persistido.
No atributo codigo, foi adicionado a Metadata [Id] indicando que esse atributo corresponde a chave primária, ou o identificador, do objeto.
E nos atributos, titulo e descrição, adicionado a Metadata [Column] indicando que refere-se a uma coluna. Junto a Metadata também foi adicionado o nome respectivo da coluna na tabela.
Com isso, nosso bean está pronto para ser persistido. Vamos para a sua gravação.
Dentro do arquivo DuckToDo.mxml foi criada a seguinte estrutura de componentes.
id="dg"
doubleClickEnabled="true"
doubleClick="doubleClickHandler(event);">
Essa estrutura corresponde a um Panel, contendo um ViewStack com dois Canvas dentro. Para o primeiro Canvas foi adicionado um Grid para conter a lista de tarefas e no segundo Canvas, um pequeno formulário para a manutenção dos registros.
Nesse artigo não irei comentar sobre a estrutura do formulário, considerando apenas como relevante as instruções de uso do FlexORM.
Foi adicionado um evento no creationComplete da minha aplicação, para instanciar o banco de dados, conforme declaração abaixo:
creationComplete="initApp(event);">
E dentro do bloco de programação em ActionScript foi adicionado:
import org.flexduck.model.Todo;
import nz.co.codec.flexorm.EntityManager;
/**
* Objeto de persistencia
*/
private var genericDAO : EntityManager = EntityManager.instance;
/**
* Classe para listar
*/
private var todoClass : Class = Todo;
/**
* Bean
*/
[Bindable]
private var todo : Todo = new Todo();
/**
* Evento disparado no creationComplete da aplicação para fazer a conexão com o banco de dados
*/
private function initApp(event:Event) : void
{
var appDataBase : File = File.documentsDirectory.resolvePath("ducktodo.db");
var sqlConn : SQLConnection = new SQLConnection();
sqlConn.open(appDataBase);
this.genericDAO.sqlConnection = sqlConn;
}
/**
* Função disparada no click do botão de "Adicionar"
*/
private function btnAddHandler(event:MouseEvent) : void
{
this.genericDAO.save(this.todo);
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no click do botão de "Excluir"
*/
private function btnDelHandler(event:MouseEvent) : void
{
this.genericDAO.remove(this.todo);
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no duplo click no grid de pesquisa
*/
private function doubleClickHandler(event:MouseEvent) : void
{
this.todo = this.dg.selectedItem as Todo;
this.vw.selectedIndex = 0;
}
/**
* Função disparada no click do botão de "Pesquisar"
*/
private function btnPesquisarHandler(event:MouseEvent) : void
{
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no click do botão de "Cadastrar"
*/
private function btnCadastrarHandler(event:MouseEvent) : void
{
this.vw.selectedIndex = 0;
}
/**
* Função disparada no click do botão de "Listar"
*/
private function btnListarHandler(event:MouseEvent) : void
{
this.vw.selectedIndex = 1;
}
/**
* Função disparada no click do botão de "Novo"
*/
private function btnNovoHandler(event:MouseEvent) : void
{
this.todo = new Todo();
}
]]>
Alguns comentários relevantes:
Na função initApp, foi criado uma conexão SQLConnection, e a mesma foi passada para um objeto chamado genericDAO. Este objeto é uma instancia da classe EntityManager do FlexORM, responsável por executar os métodos para manipulação do banco de dados.
Na função btnAddHandler foi feita a persistencia do objeto Todo. Perceba que essa função é responsável por gravar e atualizar o objeto, não sendo necessário que o desenvolvedor se preocupe com a operação específica, apenas que em determinado momento, o objeto deve ser persistido, gravando-o ou fazendo sua atualização.
Na função btnDelHandler foi solicitado que determinado objeto fosse apagado do banco de dados.
Na função btnPesquisarHandler foi solicitado uma busca em todos os registros de determinada Classe, e não um objeto, fique atento a essa situação.
Os demais eventos servem para a navegação da tela, portanto, não serão comentados.
Se você fez corretamente a inclusão de todos os fontes, terá o resultado:
creationComplete="initApp(event);">
import org.flexduck.model.Todo;
import nz.co.codec.flexorm.EntityManager;
/**
* Objeto de persistencia
*/
private var genericDAO : EntityManager = EntityManager.instance;
/**
* Classe para listar
*/
private var todoClass : Class = Todo;
/**
* Bean
*/
[Bindable]
private var todo : Todo = new Todo();
/**
* Evento disparado no creationComplete da aplicação para fazer a conexão com o banco de dados
*/
private function initApp(event:Event) : void
{
var appDataBase : File = File.documentsDirectory.resolvePath("ducktodo.db");
var sqlConn : SQLConnection = new SQLConnection();
sqlConn.open(appDataBase);
this.genericDAO.sqlConnection = sqlConn;
}
/**
* Função disparada no click do botão de "Adicionar"
*/
private function btnAddHandler(event:MouseEvent) : void
{
this.genericDAO.save(this.todo);
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no click do botão de "Excluir"
*/
private function btnDelHandler(event:MouseEvent) : void
{
this.genericDAO.remove(this.todo);
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no duplo click no grid de pesquisa
*/
private function doubleClickHandler(event:MouseEvent) : void
{
this.todo = this.dg.selectedItem as Todo;
this.vw.selectedIndex = 0;
}
/**
* Função disparada no click do botão de "Pesquisar"
*/
private function btnPesquisarHandler(event:MouseEvent) : void
{
this.dg.dataProvider = this.genericDAO.findAll(this.todoClass);
}
/**
* Função disparada no click do botão de "Cadastrar"
*/
private function btnCadastrarHandler(event:MouseEvent) : void
{
this.vw.selectedIndex = 0;
}
/**
* Função disparada no click do botão de "Listar"
*/
private function btnListarHandler(event:MouseEvent) : void
{
this.vw.selectedIndex = 1;
}
/**
* Função disparada no click do botão de "Novo"
*/
private function btnNovoHandler(event:MouseEvent) : void
{
this.todo = new Todo();
}
]]>
id="dg"
doubleClickEnabled="true"
doubleClick="doubleClickHandler(event);">
Basta exportar sua aplicação, e tudo deverá funcionar perfeitamente.
Forte abraço e até a próxima!
Comentários