Dicas de Grails #1 - como executar código SQL
Tags: grails, braziliandevs, tutorial, ptbr
Published: 2021-06-16 13:04:12

---
title: Dicas de Grails #1 - como executar código SQL
published: true
description: Dicas de Grails #1 - como executar código SQL
tags: grails, braziliandevs, tutorial, ptbr
cover_image: https://3.bp.blogspot.com/-aW8oYKOJnR8/Wg6pw5EzDvI/AAAAAAAAG4Y/fh5beB_YLEorGHsAwsCtxFmbUTVMfAdFQCLcBGAs/s1600/grails.jpg
---
A partir de agora iremos publicar dicas rápidas de desenvolvimento aqui no site da itexto: então vamos estreiar com uma nova série,&nbsp;<em>Dicas de Grails</em>, na qual iremos expor alguns usos pouco conhecidos do framework. E a dica de hoje é:&nbsp;<em>como executar código SQL de forma <strong>segura</strong></em>.
<h2>Rápido background: conheça o Hibernate</h2>
Se você&nbsp;usa Grails sabe que por padrão o Hibernate é usado como mecanismo de persistência do framework através do GORM. Então, por que não tirar proveito disto? Uma dica que costumo passar a todos os nossos clientes e alunos é:&nbsp;<strong>se deseja dominar o GORM, estude o Hibernate</strong>.

Este estudo nos possibilita ter um uso muito mais profundo e produtivo do GORM e, consequentemente, acaba evitando uma série de problemas que as pessoas enfrentam quando estão dando seus primeiros passos com o Grails. Quer ver um exemplo bacana? O acesso ao objeto&nbsp;<em>DataSource</em>.

Há dois caminhos para se executar código SQL: um perigoso e outro correto.
<h2>Primeiro caminho: o perigoso</h2>
Simplesmente injete o&nbsp;<em>bean</em>&nbsp;<em>DataSource</em> em sua classe de domínio, controlador, serviço ou biblioteca de tags, tal como o exemplo abaixo:

&nbsp;

<code>class LogicaService {</code>
<code>&nbsp; &nbsp;def dataSource</code>

<code>&nbsp; &nbsp;def metodoDeNegocio() {</code>

<code>&nbsp; &nbsp; &nbsp; &nbsp;def connection = dataSource.getConnection()</code>

<code>&nbsp; &nbsp; &nbsp;}</code>
<code> }</code>

&nbsp;

O&nbsp;objeto <em>dataSource</em> é uma implementação&nbsp;interface <a href="https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html">javax.sql.DataSource</a>. Ele foi&nbsp;<em>injetado</em> pelo Spring como uma dependência ao seu objeto. Portanto você poderá usar aqui tanto a API JDBC padrão do Java ou, se preferir, o suporte do Groovy a<a href="http://groovy-lang.org/databases.html"> bancos de dados relacionais</a>.

(Por trás dos panos quem domina o Grails é o Spring (seu projeto Grails é uma aplicação Spring MVC por baixo dos panos, sabia?). Sendo assim, o conhecimento deste framework lhe trará uma produtividade ordens de magnitude maior ao desenvolver com Grails!)

<strong>Qual o problema com esta abordagem?</strong>&nbsp;Ao acessarmos o&nbsp;bean&nbsp;<em>dataSource&nbsp;</em>diretamente não há garantia de que a conexão obtida esteja dentro do mesmo contexto transacional que o restante do seu código. E aí as coisas podem se complicar. Use este caminho apenas se tiver muita certeza do que está fazendo.
<h2>Segundo caminho: o&nbsp;seguro e correto</h2>
Lembra no início do post quando falei que o conhecimento do Hibernate é muito importante? Usando o método&nbsp;<em>withSession</em>, injetado em todas as classes de domínio do Grails podemos ter acesso direto à sessão do Hibernate (<a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html">JavaDoc</a>). E na sessão há um método chamado&nbsp;<em><a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html#doWork-org.hibernate.jdbc.Work-">doWork</a></em>, criado justamente para os casos nos quais precisamos executar código SQL nativo.

Este método recebe como parâmetro um objeto que implemente a interface <a href="https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/jdbc/Work.html">Work</a>&nbsp;, que possuí um único método:
<pre><code>void&nbsp;execute(<a title="class or interface in java.sql" href="http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html?is-external=true">Connection</a>&nbsp;connection)
      throws <a title="class or interface in java.sql" href="http://download.oracle.com/javase/6/docs/api/java/sql/SQLException.html?is-external=true">SQLException</a></code></pre>
Como ficaria seu código então? Primeiro uma versão com a cara do Java:

<code>ClasseDeDominio.withSession {session -&gt; // olha a sessão do Hibernate aqui!</code>

<code>&nbsp; session.doWork(</code>
<code>&nbsp; &nbsp; &nbsp; &nbsp; new org.hibernate.jdbc.Work() {</code>
<code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public void execute(Connection connection) throws SQLException {</code>
<code>&nbsp; &nbsp; &nbsp; &nbsp; // seu código SQL usando connection entra aqui</code>
<code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</code>
<code>&nbsp; &nbsp; &nbsp; }</code>
<code>&nbsp; }</code>

<code>}</code>

Ou, se preferir, pode simplesmente passar um objeto qualquer (ou mesmo um map) que contenha um método cuja assinatura seja equivalente à da interface Work ao método <strong>doWork</strong>.
<h4>PS:</h4>
Aos interessados, estamos finalizando (finalmente) a preparação para nossas novas turmas de Groovy e Grails em nosso projeto Formação itexto. Inscreva-se <a href="http://formacao.itexto.com.br">no site</a> para saber mais novidades em breve!