• Home
  • Sobre mim
Blue Orange Green Pink Purple

FlexORM – Framework ORM para persistência em AIR 1.5

Posted in AIR. on quarta-feira, janeiro 27th, 2010 by Stefan Horochovec Tags: AIR, FlexORM, ORM
jan 27

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:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<mx:Binding destination="todo.titulo" 		source="titulo.text"/>
<mx:Binding destination="todo.descricao" 	source="descricao.text"/>
 
<mx:Panel width="500" height="250" layout="absolute" title="O que tenho para fazer?" horizontalCenter="0" verticalCenter="0">
 
<mx:ViewStack id="vw" top="0" right="0" left="0" bottom="0">
	<mx:Canvas label="Grid" width="100%" height="100%">
 
		<mx:Label x="10" y="10" text="Título" fontWeight="bold"/>
		<mx:TextInput x="10" y="29" width="460" id="titulo" text="{this.todo.titulo}"/>
 
		<mx:Label x="10" y="58" text="Descrição" fontWeight="bold"/>
		<mx:TextArea x="10" y="75" width="460" height="85" id="descricao" text="{this.todo.descricao}"/>
 
		<mx:Button x="318" y="172" label="Adicionar" id="btnAdd" click="btnAddHandler(event);"/>
		<mx:Button x="252" y="172" label="Listar" id="btnListar" click="btnListarHandler(event);"/>
		<mx:Button x="189" y="172" label="Novo" id="btnNovo" click="btnNovoHandler(event);"/>
		<mx:Button x="406" y="172" label="Excluir" id="btnDel" click="btnDelHandler(event);"/>
 
	</mx:Canvas>
 
	<mx:Canvas label="Formulario" width="100%" height="100%">
		<mx:DataGrid 	top="5" right="5" left="5" bottom="30" 
						id="dg" 
						doubleClickEnabled="true" 
						doubleClick="doubleClickHandler(event);">
			<mx:columns>
				<mx:DataGridColumn dataField="titulo"/>
			</mx:columns>
		</mx:DataGrid>
		<mx:Button label="Pesquisar" id="btnPesquisar" click="btnPesquisarHandler(event);" bottom="5" right="5"/>
		<mx:Button label="Cadastrar" id="btnCadastrar" click="btnCadastrarHandler(event);" bottom="5" right="90"/>
	</mx:Canvas>
 
</mx:ViewStack>
 
</mx:Panel>

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:

?View Code ACTIONSCRIPT3
1
2
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
						creationComplete="initApp(event);">

E dentro do bloco de programação em ActionScript foi adicionado:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<mx:Script>
<![CDATA[
 
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();
}
]]>
</mx:Script>

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:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
						creationComplete="initApp(event);">
 
<mx:Script>
<![CDATA[
 
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();
}
]]>
</mx:Script>
 
<mx:Binding destination="todo.titulo" 		source="titulo.text"/>
<mx:Binding destination="todo.descricao" 	source="descricao.text"/>
 
<mx:Panel width="500" height="250" layout="absolute" title="O que tenho para fazer?" horizontalCenter="0" verticalCenter="0">
 
<mx:ViewStack id="vw" top="0" right="0" left="0" bottom="0">
	<mx:Canvas label="Grid" width="100%" height="100%">
 
		<mx:Label x="10" y="10" text="Título" fontWeight="bold"/>
		<mx:TextInput x="10" y="29" width="460" id="titulo" text="{this.todo.titulo}"/>
 
		<mx:Label x="10" y="58" text="Descrição" fontWeight="bold"/>
		<mx:TextArea x="10" y="75" width="460" height="85" id="descricao" text="{this.todo.descricao}"/>
 
		<mx:Button x="318" y="172" label="Adicionar" id="btnAdd" click="btnAddHandler(event);"/>
		<mx:Button x="252" y="172" label="Listar" id="btnListar" click="btnListarHandler(event);"/>
		<mx:Button x="189" y="172" label="Novo" id="btnNovo" click="btnNovoHandler(event);"/>
		<mx:Button x="406" y="172" label="Excluir" id="btnDel" click="btnDelHandler(event);"/>
 
	</mx:Canvas>
 
	<mx:Canvas label="Formulario" width="100%" height="100%">
		<mx:DataGrid 	top="5" right="5" left="5" bottom="30" 
						id="dg" 
						doubleClickEnabled="true" 
						doubleClick="doubleClickHandler(event);">
			<mx:columns>
				<mx:DataGridColumn dataField="titulo"/>
			</mx:columns>
		</mx:DataGrid>
		<mx:Button label="Pesquisar" id="btnPesquisar" click="btnPesquisarHandler(event);" bottom="5" right="5"/>
		<mx:Button label="Cadastrar" id="btnCadastrar" click="btnCadastrarHandler(event);" bottom="5" right="90"/>
	</mx:Canvas>
 
</mx:ViewStack>
 
</mx:Panel>
 
</mx:WindowedApplication>

Basta exportar sua aplicação, e tudo deverá funcionar perfeitamente.

Forte abraço e até a próxima!

12 Comments

  1. Robson Fernandes on janeiro 27th, 2010

    Boa noite Stefan

    Excelente artigo! Eu havia feitos alguns testes no FlexORM e realmente ele é fantástico, muito similar ao JPA.
    Gostaria muito que a Adobe fizesse algo similar ao Hibernate no Air, com a possibilidade de conexão para vários banco de dados, não só ao SqlLite.
    Mas estou feliz como Air 2.0!!! rsrs.

    Grande Abraço, e parabéns pelo Blog.

    Robson Fernandes

  2. Jonathan C. on janeiro 27th, 2010

    Muito bom o seu artigo, só uma opinião de leitor, tente colocar ao final da página um print de como vai ficar o projeto finalizado.

    vlw

  3. Stefan Horochovec on janeiro 27th, 2010

    @Robson Fernandes
    Isso seria fantástico, também gostaria de novas versões de bancos com suporte.

    Com relação ao AIR 2.0 é só aguardar que a próxima release será muito boa e já está chegando :D

    Obrigado por prestigiar o blog ;)

  4. Stefan Horochovec on janeiro 27th, 2010

    @Jonathan C.
    Obrigado por prestigiar o blog e também pela dica, vou colocar alguns printscreens do projeto e também vou disponibilizá-lo para download a noite.

  5. Carlos Lima on janeiro 27th, 2010

    E isso ae Stefan muito bom o artigo. Parabéns!

  6. Stefan Horochovec on janeiro 27th, 2010

    @Carlos Lima
    Obrigado por visitar o blog

  7. jandersonfc on janeiro 27th, 2010

    Muito Obrigado pelo artigo Stefan… muito útil ;) é muito bom ver esses recurso dos Metadatas ser utilizados com mais frequencia nos frameworks para AS3, além disso um ORM é indispensavel hoje em dia, injeção de sql é um poerre, cada vez mais me sinto no ActionScript3 como se estivesse no java…hehe

    Cumps.

  8. Stefan Horochovec on janeiro 27th, 2010

    @jandersonfc
    Valeu Janderson, e obrigado pela visita!

  9. Ricardo on abril 14th, 2010

    Tenho as seguintes classes:
    - Cidade (id, nome)
    - Cliente (id, cidade_id, empresa, email)

    Gostaria de saber como constrói a classe Cliente recebendo o nome da cidade.
    Tem como me passar um exemplo??

  10. Guilherme Sjlender on maio 7th, 2010

    Bah tche…
    Parabéns pelo post.
    Simples e direto… não conhecia o FlexORM, gostei pela praticidade =)

    Abraços e até mais

    GuiSjlender

  11. Stefan Horochovec on maio 8th, 2010

    @Guilherme, Valeu! Obrigado por visitar o blog e comentá-lo!

  12. Octacilio Nazaré on julho 14th, 2010

    Parabéns Stefan

    Gostei muito do que vi no seu projeto parece simples, como sou iniciante gostaria de saber se tivesse um banco ja pronto com as tabelas, no lugar do “duck” o meu “banco” daria certo.? O processo crud continua o mesmo? e no flash 4 teria compatibilidade?

    agradeço qq informação.

    Octacilio



Leave a Reply

Stefan Horochovec

  • Blogosfera
    • Erko Bridee
    • Fábio da Silva
    • Igor Costa
    • Janderson FC
    • Jose Carlos Fiel
    • Mario Junior
    • Mario Santos (msdevstudio)
    • Rodrigo Fraga
    • Vedovelli
  • Links
    • Flexmania
    • Forum – FlexBrasil
    • RedeRIA
  • Pessoal
    • Blog em Inglês
    • LinkedIn Profile
    • Oreilly Blog
  • Categorias
    • AIR (14)
    • BlazeDS (4)
    • Eng. de Software (2)
    • Flash Builder (1)
    • Flash Player (1)
    • Flex (18)
    • Flex 4 (4)
    • FlexBuilder (1)
    • FlexDuck (4)
    • Flexmania (1)
    • Geral (3)
    • Java (10)
    • Palestras (1)
    • Pessoal (2)
    • Sem categoria (8)
    • Tecnologia (1)
  • Archives
    • julho 2010
    • junho 2010
    • maio 2010
    • março 2010
    • janeiro 2010
    • novembro 2009
    • outubro 2009
    • setembro 2009
    • agosto 2009
    • julho 2009
    • junho 2009
    • maio 2009
    • abril 2009
    • março 2009
    • dezembro 2008
    • outubro 2008
    • março 2008
    • fevereiro 2008
    • janeiro 2008
  • Search






  • Home
  • Sobre mim

© Copyright Stefan Horochovec. All rights reserved.
Designed by FTL Wordpress Themes brought to you by Smashing Magazine

Back to Top