Grails: acessando bases de dados legadas.

Então chegou o dia no qual você conheceu Grails, se apaixonou pelo bichinho mas não sabe ainda como configurá-lo para acessar sua base de dados legada. Ao primeiro contato com Grails, uma impressão que surge é que, para criarmos algo com o bichinho, precisamos partir do zero no que diz respeito a base de dados. Felizmente nada poderia ser mais distante da verdade.

Se você já possui uma base de dados legada, e gostaria de reaproveitá-la em sua aplicação feita em Grails, apresento-lhe a propriedade mapping, responsável por permitir ao desenvolvedor customizar o modo como Grails acessa suas bases de dados (leia aqui: o chato do legado). É neste bloco de código aonde definimos, por exemplo, o nome dos campos que queremos acessar em nossa aplicação.

Sendo assim, suponhamos que eu já possua em um banco de dados (não irei explicar aqui como configurar a conexão com o mesmo, pois o assunto do tópico consiste apenas em como customizar o mapeamento de nossas classes com suas respectivas tabelas) uma tabela chamada tbUsuario. Esta foi definida tal como descrito abaixo (não costumo dar estes nomes a meus campos. Irei usar aqui nomes que se afastem o máximo possível dos padrões normalmente criados pelo Grails):

create table tbUsuario (
idUsuario varchar(36) not null,
strNome varchar(128) not null,
strLogin varchar(64) not null,
strSenha varchar(128) not null,
primary key (Id)
)

Nossa tabela utiliza como chave primária o campo idUsuario que armazena valores gerados usando o algoritmo UUID, diferente do padrão definido pelo Grails quando trabalhamos com MySQL por exemplo (neste caso, Grails utiliza valores auto incrementais).

Suponhamos agora, que nossa classe de domínio possua o código definido abaixo:

class Usuario {
String nome
String login
String senha

static constraints = {
nome(maxSize: 128, nullable:false, blank:false, unique: true)
login(maxSize: 64, nullable:false, blank:false, unique: true)
senha(maxSize: 128, nullable:false, blank:false)
}
}

Se fossemos usar o padrão do Grails para a geração de tabelas no MySQL, gerariamos em nosso banco uma tabela tal como a descrita no código abaixo:

create table usuario {
id integer not null auto_increment,
version integer not null, // para versionamento do banco, o Grails cria este campo por default
nome varchar(128) not null,
login varchar(128) not null,
senha varchar(128) not null,
primary key (id),
// e algum código para a geração dos indices unicos para os campos login e nome
}

Como pode ser observado, a tabela gerada por default é muito diferente da que intencionamos usar. Para resolver este problema, iremos incluir o bloco de código mapping em nossa classe de domínio, tal como no código abaixo:

class Usuario {
String id // repare: estou redefinindo o atributo id como String.
String nome
String login
String senha

static constraints = {
nome(maxSize: 128, nullable:false, blank:false, unique: true)
login(maxSize: 64, nullable:false, blank:false, unique: true)
senha(maxSize: 128, nullable:false, blank:false)
}

static mapping = {
table 'tbUsuario'
version false
id column:'idUsuario', generator:'uuid'
nome column:'strNome'
login column:'strLogin'
senha column:'strSenha'
}
}

Vamos agora analisar o que foi feito no bloco mapping linha a linha (ou quase):

table 'tbUsuario'

Simples: defino qual o nome da tabela na qual os dados se encontram armazenados.

version false

O Grails por default cria um campo chamado version em suas tabelas para versionamento dos dados. Podemos desabilitar este padrão usando o comando acima. Dado que em nossa base de dados legada não existe campo similar, ignorar este detalhe iria travar nossa aplicação.

id column:'idUsuario', generator:'uuid'

Como não iremos usar o padrão para armazenamento de chaves primárias, que varia de acordo com o banco de dados (MySQL, por exemplo, tem por default campos incrementais no que diz respeito a chaves primárias), precisamos redefinir nossa coluna id.

No caso, primeiro definimos qual o nome da coluna na qual os dados estão armazenados. Em seguida, definimos qual o algoritmo usado na geração destes valores. Em nosso caso, o algoritmo UUID (já inclusive escrevi sobre isto aqui).

Com relação aos demais campos, apenas foi definido o nome relacionado à tabela em questão:

nome column:'strNome'
login column:'strLogin'
senha column:'strSenha'

E por incrível que pareça, basicamente é isto o que você precisa fazer caso queira lidar com bases de dados legadas. Todo o código CRUD referente a classe de domínio em questão será feito com base nestas customizações.

Caso queira se aprofundar mais sobre o assunto, sugiro que dê uma lida na própria documentação do Grails (aliás, excelente) clicando aqui.

4 thoughts on “Grails: acessando bases de dados legadas.

  1. Muito bom e providencial seu post Kico. Estou avaliando a utilização do grails numa base de um sistema legado.. O banco (sybase) tem uma parte das regras de negócio em store procedures.. Neste caso qual seria a “melhor maneira” mais elegante de executar estas procedures e se beneficiar das vantagens de validações e etc centrado na classe de dominio? Criar uma classe de dominio com as chamadas (como fazer sem que a mesma crie entidades no banco)? Bem parabens pelo excelente conteudo do blog!!! abraço!

    Responda

  2. Maneiro esse post. Isso me lembrou o ‘magic models’ do Dr. Nic. Seria uma indeia interessante pra um plugin de grails.

    *O magic models gera um modelo a partir de um banco de dados pre-existente com relacionamentos, validaçao, etc…

    Responda

  3. Esse static mapping é uma manga… salva até uma aplicação nova em uma base Oracle… o chato é que o tal do oracle tem um limite de 30 caracteres para identificador… Tem como resolver pelo mapping a nomenclatura de uma tabela ou campo que é criada por um hasMany por exemplo? ocasionalmente vira uma coisa do tipo: esse_dominio_possui_uma_lista_de_outros_dominios_id….

    Responda

Leave a Reply

Your email address will not be published. Required fields are marked *