SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
Linguagem dinâmica         •  Groovy

                                               Arquitetura            •  MVC

                                       Mapeamento Objeto Relacional   •  Hibernate

                                                Convenção             •  Sobre configuração

Grails                                             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
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
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
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
Testando o Código
    target/test-reports




                               grails runApp   grails runApp
Porta em Conflito???



                                                            Iniciando Grails
grails –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
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
grails createDomainClass Musica                           Again...
package projeto

class Musica {

         static constraints = {
         }
}




    grails createDomainClass Musica                       Scaffolding
package projeto

class 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
}
grails createController
                                                                     Musica
                                         package projeto

                                         class MusicaController {

                                             def index = {
                                             }
                                         }




                           Habilitando
            o Scaffolding dinâmico
package jcTunes

class MusicaController {


    def scaffold = Musica
}
Vamos testar...            Relacionamentos com classes
                          1 para 1
                          1 para muitos
                          Muitos para 1
                          Muitos para muitos
                          ...




        Nova classe



*   1
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
                                                  ...
                                             }
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 junto

Scaffolding Estático           Ponto de partida para adicionar
                               para casos de uso que precisam de
                               uma lógica além CRUD
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
Em tempo de execução




                  Repita o processo
               para a classe MUsica
Gere o controlador de Musica novamente

grails generateController projeto.Musica


       Gere as visões novamente

 grails generateViews projeto.Musica
Relacionamentos
                                       class Carro {
                                           Motor motor
                                       }

                                       class Motor {
  Relacionamentos                          Carro carro
                                       }
                                       Não há relação de pertença




                  Relacionamentos                                   Outra forma
class Carro {                          class Carro {
    Motor motor                            Motor motor
}                                      }

class Motor {                          class Motor {
    static belongsTo = [carro:Carro]       static belongsTo = Carro
}                                      }
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
Classe Album                                  Musica
class Album {                                    class Musica{
    String titulo
                                                     String titulo
                                                     Integer duracao
    static hasMany = [musicas:Musica]
                                                     Date lancamento
    static belongsTo = [artista:Artista]
}                                                    static belongsTo = Album
                                                 }




                            Classe Artista
class Artista {
    String nome

    static hasMany =                                         Classes de Domínio
      [albuns:Album, instrumentos:Instrumento]
}
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                                                             Constraints
class 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
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 exemplo
class Pessoa {
  BigDecimal saldo
  BigDecimal limiteEspecial

    BigDecimal getSaldoDisponivel () {
        saldo+limiteEspecial                           mockDomain()
     }                                                 Testando a classe de domínio
    static transients = [‘saldoDisponivel’]
    ...
}
Testando uma classe de domínio
                                           mockDomain

void 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
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 default
class 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
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ção
class   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
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ção




Acessando 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
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 redirect
class 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
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
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 absoluto

class MusicaController {
  def show = {
              render(view:"/outrapasta/exibir",
                     model:[musica: Musica.get(params.id)])
     }
}

             grails-app/views/outrapasta/exibir.gsp
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()
                                                         }
                                                     }
Alterando as propriedades com                                        DataBinding
                           dataBinding                               de objetos múltiplos
class 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ída
class 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 Álbum

def album       = new Album(params)
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
read()                                                             list()
                                                             4 atributos
                                                                   max
def 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
Classe Album
                                         class Album {
                                             String titulo

                                             Date lancamento

                                             static hasMany = [musicas:Musica]

                                             static belongsTo = [artista:Artista]
                                         }



                                                                       save()
                        listOrderBy*()             Inserir uma nova instância
def tudoPorLancamento =
Album.listOrderByLancamento()            def album = new Album(params)
                                         album.save()
def tudoPorTitulo =
Album.listOrderByTitulo()
save()                           save()
                 Alterar uma instância                         Variação

def album = Album.get(1)

album.titulo = “Titulo Alterado“           album.save(insert:true)

album.save()




                                delete()
                       Excluir do banco




             album.delete()
findBy                                            findBy
    Retorna uma única instância                           Retorna uma única instância



      Album.findByTituloAndGenero(                            Album.findByTituloOrGenero(
            “RATM”, “Rock”)                                        “RATM”, “Rock”)




                                    Mais findBy                                           Mais findBy
Album.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")
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
                                                            }

Mais conteúdo relacionado

Mais procurados

Criando uma grid para execução de testes paralelo com Appium
Criando uma grid para execução de testes paralelo com AppiumCriando uma grid para execução de testes paralelo com Appium
Criando uma grid para execução de testes paralelo com AppiumElias Nogueira
 
Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlDiego Tremper
 
Apresentação maven
Apresentação mavenApresentação maven
Apresentação mavenAndré Justi
 
Integracao Contínua com CruiseControl e phpUnderControl
Integracao Contínua com CruiseControl e phpUnderControlIntegracao Contínua com CruiseControl e phpUnderControl
Integracao Contínua com CruiseControl e phpUnderControlDiego Tremper
 
Uma breve introdução ao Terraform
Uma breve introdução ao TerraformUma breve introdução ao Terraform
Uma breve introdução ao TerraformLeandro Silva
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introduçãoJosino Rodrigues
 
Async/Await Pattern in C#
Async/Await Pattern in C#Async/Await Pattern in C#
Async/Await Pattern in C#Leandro Silva
 
Java+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalJava+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalEduardo Bregaida
 
Paralelize seus testes web e mobile para ter feedbacks mais rápidos
Paralelize seus testes web e mobile para ter feedbacks mais rápidosParalelize seus testes web e mobile para ter feedbacks mais rápidos
Paralelize seus testes web e mobile para ter feedbacks mais rápidosElias Nogueira
 
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANTAutomação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANTelliando dias
 
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & Hudson
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & HudsonSuporte a Open Source no Oracle WebLogic 12c - Integração com Maven & Hudson
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & HudsonRicardo Ferreira
 
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)Júlio de Lima
 
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...Renato Groff
 
Integração Contínua com Cruise Control e phpUnderControl
Integração Contínua com Cruise Control e phpUnderControlIntegração Contínua com Cruise Control e phpUnderControl
Integração Contínua com Cruise Control e phpUnderControlDiego Tremper
 
True Time API Para Data e Horário NTP no Android
True Time API Para Data e Horário NTP no AndroidTrue Time API Para Data e Horário NTP no Android
True Time API Para Data e Horário NTP no AndroidVinícius Thiengo
 

Mais procurados (20)

Criando uma grid para execução de testes paralelo com Appium
Criando uma grid para execução de testes paralelo com AppiumCriando uma grid para execução de testes paralelo com Appium
Criando uma grid para execução de testes paralelo com Appium
 
Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControl
 
Aula maven
Aula   mavenAula   maven
Aula maven
 
Grails
GrailsGrails
Grails
 
Apresentação maven
Apresentação mavenApresentação maven
Apresentação maven
 
Integracao Contínua com CruiseControl e phpUnderControl
Integracao Contínua com CruiseControl e phpUnderControlIntegracao Contínua com CruiseControl e phpUnderControl
Integracao Contínua com CruiseControl e phpUnderControl
 
Uma breve introdução ao Terraform
Uma breve introdução ao TerraformUma breve introdução ao Terraform
Uma breve introdução ao Terraform
 
Grails parte 1 - introdução
Grails   parte 1 - introduçãoGrails   parte 1 - introdução
Grails parte 1 - introdução
 
Async/Await Pattern in C#
Async/Await Pattern in C#Async/Await Pattern in C#
Async/Await Pattern in C#
 
Groovy grails
Groovy grailsGroovy grails
Groovy grails
 
Java+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso TotalJava+DDD+BDD+TDD=Sucesso Total
Java+DDD+BDD+TDD=Sucesso Total
 
Java acsp
Java acspJava acsp
Java acsp
 
Paralelize seus testes web e mobile para ter feedbacks mais rápidos
Paralelize seus testes web e mobile para ter feedbacks mais rápidosParalelize seus testes web e mobile para ter feedbacks mais rápidos
Paralelize seus testes web e mobile para ter feedbacks mais rápidos
 
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANTAutomação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
Automação no ambientAutomação no ambiente de desenvolvimento com Maven e ANT
 
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & Hudson
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & HudsonSuporte a Open Source no Oracle WebLogic 12c - Integração com Maven & Hudson
Suporte a Open Source no Oracle WebLogic 12c - Integração com Maven & Hudson
 
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)
[TDC2016] Ruby in Tests: Automatizando testes de Unidade, API e GUI (Web)
 
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...
Descomplicando a montagem de ambientes de Testes com Docker - TDC 2018 - São ...
 
Integração Contínua com Cruise Control e phpUnderControl
Integração Contínua com Cruise Control e phpUnderControlIntegração Contínua com Cruise Control e phpUnderControl
Integração Contínua com Cruise Control e phpUnderControl
 
Precisamos falar sobre Gradle
Precisamos falar sobre GradlePrecisamos falar sobre Gradle
Precisamos falar sobre Gradle
 
True Time API Para Data e Horário NTP no Android
True Time API Para Data e Horário NTP no AndroidTrue Time API Para Data e Horário NTP no Android
True Time API Para Data e Horário NTP no Android
 

Destaque

Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineOtávio Calaça Xavier
 
Conhecendo Java
Conhecendo JavaConhecendo Java
Conhecendo JavaTI Infnet
 
Fundamentos de Java
Fundamentos de Java Fundamentos de Java
Fundamentos de Java jmosorio777
 
Web Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLWeb Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLOtávio Calaça Xavier
 
Fundamentos de java herbert schildt
Fundamentos de java   herbert schildtFundamentos de java   herbert schildt
Fundamentos de java herbert schildtRicardo Ramos
 
Introdução ao JPA com Hibernate
Introdução ao JPA com HibernateIntrodução ao JPA com Hibernate
Introdução ao JPA com HibernateDanilo Braga
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Claudio Martins
 
Turbinando o desenvolvimento com Eclipse
Turbinando o desenvolvimento com EclipseTurbinando o desenvolvimento com Eclipse
Turbinando o desenvolvimento com EclipseMarcos Sousa
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBCEduardo Mendes
 
The Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupThe Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupTaufan Erfiyanto
 
Java Web 4 - Servlets e JSP 2
Java Web 4 - Servlets e JSP 2Java Web 4 - Servlets e JSP 2
Java Web 4 - Servlets e JSP 2Eduardo Mendes
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Eduardo Mendes
 
Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Eduardo Mendes
 
TDD - Prática com RSpec
TDD - Prática com RSpecTDD - Prática com RSpec
TDD - Prática com RSpecEduardo Mendes
 

Destaque (20)

Adote OpenJDK
Adote OpenJDKAdote OpenJDK
Adote OpenJDK
 
GWT revista espirito
GWT revista espiritoGWT revista espirito
GWT revista espirito
 
Abstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP DoctrineAbstração do banco de dados com PHP Doctrine
Abstração do banco de dados com PHP Doctrine
 
Conhecendo Java
Conhecendo JavaConhecendo Java
Conhecendo Java
 
Fundamentos de Java
Fundamentos de Java Fundamentos de Java
Fundamentos de Java
 
Web Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQLWeb Semântica e bancos de dados NoSQL
Web Semântica e bancos de dados NoSQL
 
Fundamentos de java herbert schildt
Fundamentos de java   herbert schildtFundamentos de java   herbert schildt
Fundamentos de java herbert schildt
 
Java - Aprenda rápido
Java - Aprenda rápidoJava - Aprenda rápido
Java - Aprenda rápido
 
Java para Leigos
Java para LeigosJava para Leigos
Java para Leigos
 
Introdução ao JPA com Hibernate
Introdução ao JPA com HibernateIntrodução ao JPA com Hibernate
Introdução ao JPA com Hibernate
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7
 
Turbinando o desenvolvimento com Eclipse
Turbinando o desenvolvimento com EclipseTurbinando o desenvolvimento com Eclipse
Turbinando o desenvolvimento com Eclipse
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
 
The Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupThe Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own Startup
 
Java Web 4 - Servlets e JSP 2
Java Web 4 - Servlets e JSP 2Java Web 4 - Servlets e JSP 2
Java Web 4 - Servlets e JSP 2
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7
 
Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4
 
RSpec com doubles
RSpec com doublesRSpec com doubles
RSpec com doubles
 
Jquery
JqueryJquery
Jquery
 
TDD - Prática com RSpec
TDD - Prática com RSpecTDD - Prática com RSpec
TDD - Prática com RSpec
 

Semelhante a Grails

Produtividade na web_com_groovy_e_grails_pt2
Produtividade na web_com_groovy_e_grails_pt2Produtividade na web_com_groovy_e_grails_pt2
Produtividade na web_com_groovy_e_grails_pt2Lucas Aquiles
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Alex Guido
 
Como criar e executar testes paralelos web usando Selenium e containers
Como criar e executar testes paralelos web usando Selenium e containersComo criar e executar testes paralelos web usando Selenium e containers
Como criar e executar testes paralelos web usando Selenium e containersElias Nogueira
 
Testes Funcionais com Selenium
Testes Funcionais com Selenium Testes Funcionais com Selenium
Testes Funcionais com Selenium Mayron Cachina
 
DDD + BDD + TDD - RF 2015
DDD + BDD + TDD - RF 2015 DDD + BDD + TDD - RF 2015
DDD + BDD + TDD - RF 2015 Eduardo Bregaida
 
Integração continua sem traumas
Integração continua sem traumasIntegração continua sem traumas
Integração continua sem traumassabrinajn
 
Construindo pipelines com Azure DevOps
Construindo pipelines com Azure DevOpsConstruindo pipelines com Azure DevOps
Construindo pipelines com Azure DevOpsCamila Carrera
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAThiago Cifani
 
Chega de lendas! JavaFX em Android
Chega de lendas! JavaFX em AndroidChega de lendas! JavaFX em Android
Chega de lendas! JavaFX em AndroidBruno Oliveira
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no KubernetesKelvin Silva
 
UOL Tech Day: Testes de Integração com OpenEJB
UOL Tech Day: Testes de Integração com OpenEJBUOL Tech Day: Testes de Integração com OpenEJB
UOL Tech Day: Testes de Integração com OpenEJBGabriel Ozeas
 
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como Código
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como CódigoCurso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como Código
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como CódigoGuilhermeJorgeAragod
 
Introdução-a-Docker-compactado.pdf
Introdução-a-Docker-compactado.pdfIntrodução-a-Docker-compactado.pdf
Introdução-a-Docker-compactado.pdfdadalt1
 
Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlManuel Lemos
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-ptPedro Sousa
 

Semelhante a Grails (20)

Produtividade na web_com_groovy_e_grails_pt2
Produtividade na web_com_groovy_e_grails_pt2Produtividade na web_com_groovy_e_grails_pt2
Produtividade na web_com_groovy_e_grails_pt2
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.
 
Grails
GrailsGrails
Grails
 
Como criar e executar testes paralelos web usando Selenium e containers
Como criar e executar testes paralelos web usando Selenium e containersComo criar e executar testes paralelos web usando Selenium e containers
Como criar e executar testes paralelos web usando Selenium e containers
 
Testes Funcionais com Selenium
Testes Funcionais com Selenium Testes Funcionais com Selenium
Testes Funcionais com Selenium
 
DDD + BDD + TDD - RF 2015
DDD + BDD + TDD - RF 2015 DDD + BDD + TDD - RF 2015
DDD + BDD + TDD - RF 2015
 
Ruby On Rails Regis
Ruby On Rails RegisRuby On Rails Regis
Ruby On Rails Regis
 
Integração continua sem traumas
Integração continua sem traumasIntegração continua sem traumas
Integração continua sem traumas
 
Construindo pipelines com Azure DevOps
Construindo pipelines com Azure DevOpsConstruindo pipelines com Azure DevOps
Construindo pipelines com Azure DevOps
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVA
 
Chega de lendas! JavaFX em Android
Chega de lendas! JavaFX em AndroidChega de lendas! JavaFX em Android
Chega de lendas! JavaFX em Android
 
Iniciando com kubernetes
Iniciando com kubernetesIniciando com kubernetes
Iniciando com kubernetes
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
 
UOL Tech Day: Testes de Integração com OpenEJB
UOL Tech Day: Testes de Integração com OpenEJBUOL Tech Day: Testes de Integração com OpenEJB
UOL Tech Day: Testes de Integração com OpenEJB
 
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como Código
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como CódigoCurso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como Código
Curso de Verão - Aula 03 - Introdução ao CI-CD e Infraestrutura como Código
 
Iniciando com realm
Iniciando com realmIniciando com realm
Iniciando com realm
 
Java 01
Java 01Java 01
Java 01
 
Introdução-a-Docker-compactado.pdf
Introdução-a-Docker-compactado.pdfIntrodução-a-Docker-compactado.pdf
Introdução-a-Docker-compactado.pdf
 
Integração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControlIntegração Contínua com CruiseControl e phpUnderControl
Integração Contínua com CruiseControl e phpUnderControl
 
Workshop Ruby on Rails dia 2 ruby-pt
Workshop Ruby on Rails dia 2  ruby-ptWorkshop Ruby on Rails dia 2  ruby-pt
Workshop Ruby on Rails dia 2 ruby-pt
 

Mais de Eduardo Mendes

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosEduardo Mendes
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - FundamentosEduardo Mendes
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de ProjetoEduardo Mendes
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTMLEduardo Mendes
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEduardo Mendes
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Eduardo Mendes
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails Eduardo Mendes
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Eduardo Mendes
 

Mais de Eduardo Mendes (20)

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a Objetos
 
AngularJS - Rotas
AngularJS - RotasAngularJS - Rotas
AngularJS - Rotas
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - Fundamentos
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de Projeto
 
Layout Fluido
Layout FluidoLayout Fluido
Layout Fluido
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 
Html - Aula 4
Html - Aula 4Html - Aula 4
Html - Aula 4
 
Html - Aula 3
Html - Aula 3Html - Aula 3
Html - Aula 3
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTML
 
ExtJS-4
ExtJS-4ExtJS-4
ExtJS-4
 
Jquery 2
Jquery 2Jquery 2
Jquery 2
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de Software
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails
 
Padrão Iterator
Padrão IteratorPadrão Iterator
Padrão Iterator
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)
 
Padrão Command
Padrão CommandPadrão Command
Padrão Command
 
Padrão Fachada
Padrão FachadaPadrão Fachada
Padrão Fachada
 
Padrão Adapter
Padrão AdapterPadrão Adapter
Padrão Adapter
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 

Grails

  • 1. Linguagem dinâmica •  Groovy Arquitetura •  MVC Mapeamento Objeto Relacional •  Hibernate Convenção •  Sobre configuração Grails 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. 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. 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. 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. Testando o Código   target/test-reports grails runApp grails runApp
  • 6. Porta em Conflito??? Iniciando Grails grails –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. 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. grails createDomainClass Musica Again... package projeto class Musica { static constraints = { } } grails createDomainClass Musica Scaffolding package projeto class 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. grails createController Musica package projeto class MusicaController { def index = { } } Habilitando o Scaffolding dinâmico package jcTunes class MusicaController { def scaffold = Musica }
  • 10. Vamos testar... Relacionamentos com classes   1 para 1   1 para muitos   Muitos para 1   Muitos para muitos   ... Nova classe * 1
  • 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. 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 junto Scaffolding Estático Ponto de partida para adicionar para casos de uso que precisam de uma lógica além CRUD
  • 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. Em tempo de execução Repita o processo para a classe MUsica Gere o controlador de Musica novamente grails generateController projeto.Musica Gere as visões novamente grails generateViews projeto.Musica
  • 15. Relacionamentos class Carro { Motor motor } class Motor { Relacionamentos Carro carro } Não há relação de pertença Relacionamentos Outra forma class Carro { class Carro { Motor motor Motor motor } } class Motor { class Motor { static belongsTo = [carro:Carro] static belongsTo = Carro } }
  • 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. Classe Album Musica class Album { class Musica{ String titulo String titulo Integer duracao static hasMany = [musicas:Musica] Date lancamento static belongsTo = [artista:Artista] } static belongsTo = Album } Classe Artista class Artista { String nome static hasMany = Classes de Domínio [albuns:Album, instrumentos:Instrumento] }
  • 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 Constraints class 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. 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 exemplo class Pessoa { BigDecimal saldo BigDecimal limiteEspecial BigDecimal getSaldoDisponivel () { saldo+limiteEspecial mockDomain() } Testando a classe de domínio static transients = [‘saldoDisponivel’] ... }
  • 20. Testando uma classe de domínio mockDomain void 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. 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 default class 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. 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ção class 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. 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ção Acessando 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. 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 redirect class 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. 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. 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 absoluto class MusicaController { def show = { render(view:"/outrapasta/exibir", model:[musica: Musica.get(params.id)]) } }   grails-app/views/outrapasta/exibir.gsp
  • 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. Alterando as propriedades com DataBinding dataBinding de objetos múltiplos class 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ída class 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 Álbum def album = new Album(params)
  • 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. read() list()   4 atributos max def 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. Classe Album class Album { String titulo Date lancamento static hasMany = [musicas:Musica] static belongsTo = [artista:Artista] } save() listOrderBy*() Inserir uma nova instância def tudoPorLancamento = Album.listOrderByLancamento() def album = new Album(params) album.save() def tudoPorTitulo = Album.listOrderByTitulo()
  • 32. save() save() Alterar uma instância Variação def album = Album.get(1) album.titulo = “Titulo Alterado“ album.save(insert:true) album.save() delete() Excluir do banco album.delete()
  • 33. findBy findBy   Retorna uma única instância   Retorna uma única instância Album.findByTituloAndGenero( Album.findByTituloOrGenero( “RATM”, “Rock”) “RATM”, “Rock”) Mais findBy Mais findBy Album.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. 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 }