Linguagem dinâmica         •  Groovy                                               Arquitetura            •  MVC          ...
Criando um projeto                          Instalando e testando              6 passos na linha de comando    Exige Java...
grails createController Loja                                                   Criação de 2 classes                      ...
Testando o código                                      com Grails                Escrevendo o código de testes            ...
Testando o Código    target/test-reports                               grails runApp   grails runApp
Porta em Conflito???                                                            Iniciando Grailsgrails –Dserver.port=8087 ...
Classes de Domínio                              Classes de Domínio                         Lógica do negócio             ...
grails createDomainClass Musica                           Again...package projetoclass Musica {         static constraints...
grails createController                                                                     Musica                        ...
Vamos testar...            Relacionamentos com classes                          1 para 1                          1 para...
Como definir uma relação                         1 para muitos?                                    Classe Album           ...
AlbumController                       package jctunes                       class AlbumController {                       ...
Scaffolding estático                                     3 targets básicos              grails           •  Gera as visões...
Em tempo de execução                  Repita o processo               para a classe MUsicaGere o controlador de Musica nov...
Relacionamentos                                       class Carro {                                           Motor motor ...
Qual a diferença?                                                    belongsTo    static belongsTo = [carro:Carro]       ...
Classe Album                                  Musicaclass Album {                                    class Musica{    Stri...
Classes de Domínio                      Validando classes de domínio    Por default, todos os campos de uma classe de    ...
Propriedades Transientes                                         Exemplos    Por default, toda propriedade de uma classe ...
Testando uma classe de domínio                                           mockDomainvoid testDuracaoMinima() {       mockDo...
Definindo um controle                                            Ações de um controle    Localização                     ...
Controle                                                           Controle                 Tem apenas 1 ação          Pos...
Escopos dos controles                                     Escopos dos controle                                    request...
Redirect                        Redirecionando a requisição                  Redirecionando a requisição                  ...
Criando um modelo                                                       Uma das atividades fundamentais do controle      ...
Renderizando                                             E se eu quiser                                                   ...
Ligando dados                                Ligando dados                                 primeira forma    Controles ta...
Alterando as propriedades com                                        DataBinding                           dataBinding    ...
Uma variação dos cenários<input type="text” name="songs[0].title" value="The Bucket" /><input type="text name="songs[1].ti...
read()                                                             list()                                                 ...
Classe Album                                         class Album {                                             String titu...
save()                           save()                 Alterar uma instância                         Variaçãodef album = ...
findBy                                            findBy    Retorna uma única instância                           Retorn...
Métodos “primos”                                                Criteria    findAllBy*                                   ...
Upcoming SlideShare
Loading in …5
×

Grails

956 views
853 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
956
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
39
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Grails

  1. 1. Linguagem dinâmica •  Groovy Arquitetura •  MVC Mapeamento Objeto Relacional •  Hibernate Convenção •  Sobre configuraçãoGrails DRY •  Dont Repeat Yourself YAGNI •  You aint gonna need it KISS •  Keep It Simple, Stupid Simplicidade e Poder Plataforma   Não apenas um framework   Um ambiente full-stack   Servidor web   Banco de dados
  2. 2. Criando um projeto Instalando e testando 6 passos na linha de comando  Exige Java 5.0 ou superior   grails createApp nomeProjeto Comando para criar o projeto Download Grails:      cd nomeProjeto   http://grails.org/Download   Navegar até o diretório da nova aplicação  Descompacte   grails createController nomeControlador   Criar nosso primeiro controlador  Cria uma variável de ambiente   GRAILS_HOME   Escrever algum código no melhor estilo hello...   grails testApp  Adicione GRAILS_HOMEbin ao seu PATH   Escrever o código de teste e executar os testes  Valide a instalação   grails runApp   Comando para executar a aplicação   grails Acessar a pasta do projeto cd projeto
  3. 3. grails createController Loja   Criação de 2 classes   Loja Controller.groovy   No diretório controllers/jctunes   Classe de teste render Exibindo uma mensagem Um dos métodos implícitos  Para todo controlador, por default package projeto   Grails cria uma ação chamada index class LojaController { package projeto def index = { render "Seja benvindo a Loja" class LojaController { } def index = { } } }  Por convenção tenta renderizar   grails-app/views/loja/index.gsp
  4. 4. Testando o código com Grails Escrevendo o código de testes package projeto Testes de import grails.test.* Testes unitários integração class LojaControllerTests extends ControllerUnitTestCase { protected void setUp() { super.setUp() Para todo o ambiente }desenvolvido incluindo a protected void tearDown() { base de dados Rápidos super.tearDown() } void testPaginaPrincipal() {Geralmente, mais lentos controller.index() assertEquals "Seja benvindo a Loja", controller.response.contentAsString Fazem uso }Aplicação deve possuir de mocks e stubs } alguma completude grails test-app
  5. 5. Testando o Código  target/test-reports grails runApp grails runApp
  6. 6. Porta em Conflito??? Iniciando Grailsgrails –Dserver.port=8087 runApp CRUD, Scaffolding e Domínio Scaffolding Permite gerar rapidamente interfaces de CRUD para classes de domínio Facilita o entendimento de como a Visão e o Controle interagem no Grails
  7. 7. Classes de Domínio Classes de Domínio   Lógica do negócio   São persistidas   Mapeadas automaticamente para tabelas de banco de dados   Hibernate   Localização   grails-appdomainnomeDoProjeto   Criação   grails createDomainClass grails createDomainClass Musica
  8. 8. grails createDomainClass Musica Again...package projetoclass Musica { static constraints = { }} grails createDomainClass Musica Scaffoldingpackage projetoclass Musica { Dinâmicos Estáticos String titulo • Lógica do • Criação de String artista controle e templates Integer duracao visões são Date lancamento geradas em static constraints = { tempo de } execução}
  9. 9. grails createController Musica package projeto class MusicaController { def index = { } } Habilitando o Scaffolding dinâmicopackage jcTunesclass MusicaController { def scaffold = Musica}
  10. 10. Vamos testar... Relacionamentos com classes   1 para 1   1 para muitos   Muitos para 1   Muitos para muitos   ... Nova classe* 1
  11. 11. Como definir uma relação 1 para muitos? Classe Album package projeto class Album { String titulo  static hasMany = [musicas: Musica] static hasMany = [musica: Musica] static constraints = { } } Altere a classe Musica static hasMany = [musica: Musica] para tornar a relação bi-direcional package jctunes  Esta relação é unidirecional class Musica {  Para torná-la bidirecional inclua uma ... referência de Album na classe Musica Album album ... }
  12. 12. AlbumController package jctunes class AlbumController { def scaffold = Album } Scaffolding estático Geração do código das visões e dos controles Pode ajudar na familiarização com o Grails e como o todo trabalha juntoScaffolding Estático Ponto de partida para adicionar para casos de uso que precisam de uma lógica além CRUD
  13. 13. Scaffolding estático 3 targets básicos grails •  Gera as visões para uma generateViews classe de domínio específico grails •  Gera o controle para uma generateController classe de domínio específico grails •  Gera ambos controle e generateAll visões associados Vamos examinar Grails fará 2 perguntas o código gerado  Como o controle já existe   ele pergunta se você deseja sobrescrever a classe Milhares de linhas? AlbumController e sua classe de teste -> responda Y (yes) 10 camadas??? •  DAO •  Controle •  Classe de Negócio •  TO •  POJO
  14. 14. Em tempo de execução Repita o processo para a classe MUsicaGere o controlador de Musica novamentegrails generateController projeto.Musica Gere as visões novamente grails generateViews projeto.Musica
  15. 15. Relacionamentos class Carro { Motor motor } class Motor { Relacionamentos Carro carro } Não há relação de pertença Relacionamentos Outra formaclass Carro { class Carro { Motor motor Motor motor} }class Motor { class Motor { static belongsTo = [carro:Carro] static belongsTo = Carro} }
  16. 16. Qual a diferença? belongsTo  static belongsTo = [carro:Carro]   A propriedade que pertence sofrerá   A classe Motor tem sua própria referência para exclusões em cascata carro   Grails saberá que o Motor pertence a um  static belongsTo = Carro Carro   A classe Motor não possui referência para carro   então sempre que um Carro for excluído do banco, o Motor será excluído em conjunto Outra classe Classe Artista  Artista class Artista {   Propriedades String nome   nome   albuns static hasMany = [albuns:Album]  Album pertencerá a um Artista   Com referência }  Música pertencerá a um Album   Sem referencia
  17. 17. Classe Album Musicaclass Album { class Musica{ String titulo String titulo Integer duracao static hasMany = [musicas:Musica] Date lancamento static belongsTo = [artista:Artista]} static belongsTo = Album } Classe Artistaclass Artista { String nome static hasMany = Classes de Domínio [albuns:Album, instrumentos:Instrumento]}
  18. 18. Classes de Domínio Validando classes de domínio  Por default, todos os campos de uma classe de   Toda aplicação tem regras de negócios que domínio são persistidas no banco de dados restringem os valores válidos de uma  Para tipos simples como Strings e Integers, propriedade de classe cada propriedade da classe será mapeada para   Idade não pode ser < 0 uma coluna de uma tabela   Email deve possuir @ e .  Para tipos complexos serão necessários tabelas   O número de um cartão de crédito deve seguir  Toda classe mapeada para uma tabela receberá um padrão um campo adicional, o id, que será a chave   Regras como estas deve estar em um local primária específico Validando as propriedades da Musica Constraintsclass Musica {   blank   notEqual String titulo   creditCard   nullable String artista Integer duracao   email   range Date lancamento   inList   scale   matches   size static constraints = {   max   unique titulo(blank: false,minSize:2)   maxSize   url artista(blank: false)   min   validator duracao(min:1) }   minSize} OBS: A validação ocorre quando o método save de um objeto é chamadov
  19. 19. Propriedades Transientes Exemplos  Por default, toda propriedade de uma classe package projeto de domínio é persistida no banco de dados class Album { String titulo  E quando existirem propriedades que não necessitam ser persistidas? String nomeFalso static transients = [‘nomeFalso’]  static transients ... } Outro exemploclass Pessoa { BigDecimal saldo BigDecimal limiteEspecial BigDecimal getSaldoDisponivel () { saldo+limiteEspecial mockDomain() } Testando a classe de domínio static transients = [‘saldoDisponivel’] ...}
  20. 20. Testando uma classe de domínio mockDomainvoid testDuracaoMinima() { mockDomain(Musica) Entendendo def musica = new Musica(duracao: 0) os Controles assertFalse Validacao deve falhar, musica.validate() assertEquals "min", musica.errors.duracao} Introdução Introdução  Os controles são classes responsáveis por   Existe um controle para cada requisição manipular requisições que chegam à aplicação   O controle recebe a requisição   Não precisam herdar ou implementar uma   Geralmente, realiza alguma tarefa com a interface específica requisição   E finalmente decide o que deve acontecer em seguida   Executar uma outra ação dele ou de outro controle   Renderizar uma visão   Renderizar informações diretamente para uma visão
  21. 21. Definindo um controle Ações de um controle  Localização class   Ações são definidas SampleController { como um campo   grails-app/controllers def first = {...}   Cada campo é atribuído  Convenção def second = {...} a bloco de código   O nome da classe deve terminar com “Controller” def third = {...} utilizando uma closure def fourth = {...} Groovy }   Controller pode definir um número qualquer de ações Mapeamentos, urls no Grails Configurando a ação defaultclass SampleController {   Se o controle def first = {...}   Tem apenas 1 ação ...   Tal ação torna-se a default}   A primeira parte de uma url representa qual controle   Possui uma ação chamada index está sendo acessado   A ação index será a default   A segunda parte representa a ação a ser executada   Define uma propriedade defaultAction nomeAplicacao/sample/first   Seu valor será a ação default
  22. 22. Controle Controle Tem apenas 1 ação Possui uma ação chamada index class SampleController {class SampleController { def list = {} def list = {} def index = {}} } Controle com propriedade defaultAction Objetos implícitos no controle actionName •  Nome da ação que está sendo executada actionUri •  Uri relativa a ação em execução controllerName •  Nome do atual controle em execuçãoclass SampleController { controllerUri •  Uri do controle em execução def defaultAction = list flash •  Objeto para acessar o escopo flash log •  Instância de org.apache.commons.logging.Log def list = {} params •  Mapa de parâmetros de requisição def index = {} request •  O objeto HttpServletRequest} response •  O objeto HttpServletResponse session •  O objeto HttpSession object servletContext •  O objeto ServletContext
  23. 23. Escopos dos controles Escopos dos controle   request   Objetos colocados dentro de request estarão disponíveis durante a execução da requisição corrente   flash   Objetos colocados dentro de flash estarão disponíveis para a requisição atual e para a próxima   session   Objetos colocados no session serão mantidos até que a sessão do usuário seja invalidada, ou manualmente ou por expiração   servletContext   Objetos colocados no servletContext são compartilhados por toda a aplicação e mantidos durante todo o tempo de vida da aplicaçãoAcessando parâmetros da Acessando parâmetros da requisição requisição   Via propriedade params do Grails def userName = params.userName log.info("User Name: ${userName}") Valores da página => parâmetros do request
  24. 24. Redirect Redirecionando a requisição Redirecionando a requisição class SampleController { def first = { // redireciona para a acao “second” Todo controle tem redirect(action: "second")Às vezes é necessário acesso a um método } redirecionar o chamado redirect, controle para outra def second = { que recebe um mapa ação de controle // ... como argumento } } Redirecionando para outro controle Argumentos do redirectclass SampleController { def first = { action controller id //redirecionar para a acao list de Loja •  O nome da ação •  O nome do controle •  Valor do parâmetro redirect(action: "list", controller: "Loja") para para id para ser enviado redirecionamento redirecionamento no redirecionamento }} params uri url •  Um mapa de •  Um endereço •  Um endereço parâmetros relativo para absoluto redirecionar
  25. 25. Criando um modelo   Uma das atividades fundamentais do controle   Reunir dados para serem renderizados na visão   O controle pode realizar esta tarefa   Ou delegar para uma classe de serviço ou Informações que chegam às visões outros componentes O Model Criando um modelo Retornando dados  Quando o controle faz esta tarefa, os dados class MusicaController { são disponibilizados diretamente para as def show = { visões através de um mapa, o MODEL [ musica: Musica.get(params.id) ] }  O mapa é retornado pelas ações de um } controle   return é opcional   Como a última expressão avaliada pela ação foi um mapa, então o mapa é o valor retornado desta ação   O mapa pode ter qualquer quantidade de valores
  26. 26. Renderizando E se eu quiser a Visão alterar a View de destino?  O controle MusicaController   Utilize o método render   1 método chamado show   Retorna um modelo contendo uma chave e um objeto class MusicaController { def show = { render(view:"exibir",  Onde está a referência para qual visão ele irá model:[musica: Musica.get(params.id)]) despachar o fluxo? } }   Por convenção  Por convenção   grails-app/views/musica/exibir.gsp   grails-app/views/musica/show.gsp Ligando dados da visão E para mudar o diretório? para o controle  Utilize um caminho absolutoclass MusicaController { def show = { render(view:"/outrapasta/exibir", model:[musica: Musica.get(params.id)]) }}   grails-app/views/outrapasta/exibir.gsp
  27. 27. Ligando dados Ligando dados primeira forma  Controles também precisam class AlbumController {   Criar novos objetos de domínio def save = {   Popular as propriedades destes objetos com def album = new Album() valores recebidos como parâmetros na requisição album.genero = params.genero album.titulo = params.titulo album.save() } } class AlbumController { def save = { def album = new Album(params) album.save() } }
  28. 28. Alterando as propriedades com DataBinding dataBinding de objetos múltiplosclass AlbumController { def update= { def album = Album.get(params.id) album.properties = params def album = new Album( params["album"] ) def artist = new Artista( params["artista"] ) album.save() }} DataBinding e Associações 2 cenários na visão  Na classe de domínio   <input type="text" name="artista.name" />   Uma nova instância de artista é criada e atribuídaclass Album { à instância do Álbum Artista artista   <input type="text" ... name="artista.id" value="1" />,}   Recupera uma instância de um artista existente e  Na classe de controle atribui à classe do Álbumdef album = new Album(params)
  29. 29. Uma variação dos cenários<input type="text” name="songs[0].title" value="The Bucket" /><input type="text name="songs[1].title" value="Milk" /><input type="text" name="songs[0].id" GORM value="23" /> Grails Object Relational Mapping<input type="text" name="songs[1].id" value="47" /> get() getAll()def album = Album.get(params.id) def album = Album.getAll(1,2,3)  Get recebe um id e retorna   Recebe   Ou a instância do objeto correspondente ao id   Vários identificadores   Ou null caso não exista   Retorna   Uma lista de instâncias
  30. 30. read() list()   4 atributos maxdef album = Album.read(params.id)     Número máximo de instâncias a serem retornadas   offset  Recebe   Qual o 0 relativo da consulta   Um identificador   sort  Retorna   Nome da propriedade para utilizar no ORDER BY   Um objeto em estado somente leitura   order   Se a ordenação é ASC ou DESC Classe Album list()class Album {   def allAlbums = Album.list() String titulo   Recupera todos os albuns Date lancamento   def top10 = Album.list( max:10, sort:‘lancamentos, order:desc) static hasMany = [musicas:Musica]   Retorna os 10 albuns mais recentes static belongsTo = [artista:Artista]   def totalAlbums = Album.count()}   Recupera o total de albuns
  31. 31. Classe Album class Album { String titulo Date lancamento static hasMany = [musicas:Musica] static belongsTo = [artista:Artista] } save() listOrderBy*() Inserir uma nova instânciadef tudoPorLancamento =Album.listOrderByLancamento() def album = new Album(params) album.save()def tudoPorTitulo =Album.listOrderByTitulo()
  32. 32. save() save() Alterar uma instância Variaçãodef album = Album.get(1)album.titulo = “Titulo Alterado“ album.save(insert:true)album.save() delete() Excluir do banco album.delete()
  33. 33. findBy findBy  Retorna uma única instância   Retorna uma única instância Album.findByTituloAndGenero( Album.findByTituloOrGenero( “RATM”, “Rock”) “RATM”, “Rock”) Mais findBy Mais findByAlbum.findByLancamentoBetween(hoje-10,hoje) Album.findByGeneroIsNull()Album.findByTituloEquals(‘RATM) Album.findByGeneroIsNotNull() Album.findByLancamentoLessThan(ontem)Album.findByLancamentoGreaterThan(ontem) Album.findByLancamentoLessThanOrEqual(ontem)Album.findByLancamentoGreaterThanOrEqual(o ntem) Album.findByTituloLike(‘O tempo não%)Album.findByTituloInList([‘123, ‘Brasil]) Album.findByTituloNotEqual(Odelay")
  34. 34. Métodos “primos” Criteria  findAllBy* def c = Album.createCriteria()   Retorna uma lista baseado nos parâmetros def results = c.list { eq(genero, Alternativo)  countBy* between(‘lancamento, new Date()-30, new   Retorna um inteiro com o total de instância que Date()) satisfazem a consulta }

×