{"id":8,"date":"2008-07-26T00:55:27","date_gmt":"2008-07-26T03:55:27","guid":{"rendered":"https:\/\/devkico.itexto.com.br\/?p=8"},"modified":"2008-07-26T00:55:27","modified_gmt":"2008-07-26T03:55:27","slug":"criando-consultas-complexas-no-hibernate-de-maneira-dinamica","status":"publish","type":"post","link":"https:\/\/devkico.itexto.com.br\/?p=8","title":{"rendered":"Criando consultas complexas no Hibernate de maneira din\u00e2mica"},"content":{"rendered":"<p>Neste post pretendo expor um padr\u00e3o bastante simples a ser aplicado na cria\u00e7\u00e3o de consultas usando a API Criteria do Hibernate. A API Criteria consiste em uma ferramenta extremamente poderosa que o Hibernate nos oferece para solucionar um problema muito comum no desenvolvimento de aplica\u00e7\u00f5es que precisem fazer consultas a banco de dados: a maldita concatena\u00e7\u00e3o de strings no momento de cria\u00e7\u00e3o de nossas consultas.<\/p>\n<p>Em nosso exemplo, utilizaremos a classe Pessoa, que encontra-se descrita no c\u00f3digo abaixo:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\r\nclass\u00a0Pessoa {\r\nprivate String nome;\r\nprivate String sobrenome;\r\nprivate String endereco;\r\nprivate String observacoes;\r\n\/\/ gets e sets omitidos\r\n}\r\n\r\n<\/pre>\n<p>Para buscar valores j\u00e1 persistidos da classe Pessoa em um banco de dados, poder\u00edamos criar uma nova classe chamada FactoryPessoa, respons\u00e1vel por encapsular as consults ao banco de dados. Suponhamos que esta nossa classe possua a implementa\u00e7\u00e3o abaixo:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport org.hibernate.*;\r\nimport org.hibernate.criterion.*;\r\nimport java.util.*;\r\n\r\nclass FactoryPessoa extends FactoryBase {\r\n\r\n\/*\r\nSuponha que exista uma classe chamada FactoryBase, que j\u00e1 possua m\u00e9todos b\u00e1sicos para\r\na instancia\u00e7\u00e3o de objetos Session\r\n*\/\r\n\r\npublic List&lt;Pessoa&gt; getPessoaPorNome(String valor)\r\n{\r\nSession sessao = null;\r\ntry\r\n{\r\nsessao = getSession();\r\nCriteria busca = sessao.createCriteria(Pessoa.class);\r\nbusca.add(Expression.ilike(&quot;nome&quot;, MatchMode.ANYWHERE, valor);\r\nreturn busca.list();\r\n}\r\ncatch (Exception ex) \/\/ Exception ex apenas para fins did\u00e1ticos. N\u00e3o tentem isto em casa\r\n{\r\nreturn null; \/\/ n\u00e3o tente isto em casa tamb\u00e9m\r\n}\r\n}\r\n\r\npublic List&lt;String&gt; getPessoaPorSobreNome(String valor)\r\n{\r\ntry {\r\nSession sessao = getSession();\r\nCriteria busca = sessao.createCriteria(Pessoa.class);\r\nbusca.add(Expression.ilike(&quot;sobrenome&quot;, MatchMode.ANYWHERE, valor);\r\nreturn busca.list();\r\n} catch (Exception ex) {return null;}\r\n}\r\n\r\n}\r\n<\/pre>\n<p>Um factory simples com base em dois crit\u00e9rios de busca simples. Mas e se quisessemos buscar por nome e sobrenome ao mesmo tempo? Uma solu\u00e7\u00e3o poderia ser criar mais um m\u00e9todo. E depois, se quisessemos buscar por nome, sobrenome e alguma observa\u00e7\u00e3o? Outro m\u00e9todo, claro! E no final de pouco tempo ter\u00edamos uma classe com in\u00fameros m\u00e9todos, um para cada tipo de busca que viesse \u00e0 nossa mente. Hmm&#8230; cheira a merda, n\u00e3o acha?<\/p>\n<p>Uma solu\u00e7\u00e3o para este problema consiste em um padr\u00e3o que criei e venho aplicando a j\u00e1 algum tempo. Consiste em primeiro criar uma classe que represente uma consulta gen\u00e9rica, que chamo de CriterioBusca, cuja implementa\u00e7\u00e3o pode ser similar a abaixo:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass CriterioBusca {\r\n\r\n           private int tipoBusca;\r\n           private Object valorBusca;     \r\n    \r\n\/\/ gets e sets impl\u00edcitos\r\n\r\n}\r\n<\/pre>\n<p>O atributo tipoBusca identifica o tipo de busca que queremos fazer. Na classe respons\u00e1vel por fazer consultas ao banco de dados, deveremos criar uma s\u00e9rie de constantes est\u00e1ticas que definam os tipos de pesquisa que queremos fazer ao banco de dados. Sendo assim, poder\u00edamos modificar nossa classe FactoryPessoa para se tornar semelhante \u00e0 descrita abaixo:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass FactoryPessoa {\r\n           \/\/ Constante que identifica uma busca por nome\r\n           public static final int BUSCA_NOME = 1;\r\n          \/\/ Constante que identifica uma busca por sobrenome\r\n           public static final int BUSCA_SOBRENOME = 2;\r\n          \/\/ Constante que identifica uma busca por observa\u00e7\u00f5es\r\n           public static final int BUSCA_OBSERVACOES = 3;\r\n      \/\/ e quantas outras constantes forem necess\u00e1rias\r\n}\r\n<\/pre>\n<p>J\u00e1 o atributo valor identifica o valor que queremos utilizar em nossa pesquisa. Opta-se por Object ao inv\u00e9s de String ou qualquer outro tipo para que tenhamos a busca mais flex\u00edvel poss\u00edvel ao final de nosso projeto.<\/p>\n<p>Em seguida, nossa classe FactoryUsuario pode tamb\u00e9m ter sua interface externa simplificada ao extremo. Por que ter 234987234 m\u00e9todos de busca quando podemos ter apenas um?<\/p>\n<p>Sendo assim, podemos finalizar a implementa\u00e7\u00e3o de FactoryPessoa do seguinte modo:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass FactoryPessoa extends FactoryBase {\r\n     (...)\r\n    \/\/ as constantes encontram-se definidas acima\r\n    public List&lt;Pessoa&gt; buscarPessoas(List&lt;CriterioBusca&gt; criterios)\r\n    {\r\n            try\r\n              {\r\n                  Session sessao = getSession();\r\n                  Criteria busca = sessao.createCriteria(Pessoa.class);\r\n                  for (CriterioBusca criterio : criterios)\r\n                      {\r\n                           prepararBusca(criterio, busca);\r\n                      }\r\n                  return busca.list();\r\n               } catch (Exception ex) {return null;}\r\n    }\r\n\r\n\r\n  private void prepararBusca(CriterioBusca criterio, Criteria busca)\r\n   {\r\n         switch (criterio.getTipoBusca())\r\n          {\r\n               case BUSCA_NOME:\r\n                     busca.add(Expression.ilike(&quot;nome&quot;, MatchMode.ANYWHERE, busca.getValor().toString());\r\n                break;\r\n                case BUSCA_SOBRENOME:\r\n                      busca.add(Expression.ilike(&quot;sobrenome&quot;, MatchMode.ANYWHERE, busca.getValor().toString());\r\n                break;\r\n                \/\/ quantos outros casos de acordo com o n\u00famero de constantes definidas na classe\r\n           }\r\n    }\r\n}\r\n<\/pre>\n<p>O c\u00f3digo acima foi super simplificado, no entanto j\u00e1 \u00e9 poss\u00edvel ter uma no\u00e7\u00e3o b\u00e1sica da id\u00e9ia por tr\u00e1s do padr\u00e3o. Ao inv\u00e9s de termos uma s\u00e9rie de m\u00e9todos, um para cada tipo diferente de busca, teremos apenas um \u00fanico m\u00e9todo: e este far\u00e1 qualquer tipo de combina\u00e7\u00e3o de busca que quisermos, basta passar o n\u00famero de instancias de CriterioBusca necess\u00e1rias.<\/p>\n<p>No entanto, nem tudo s\u00e3o flores neste padr\u00e3o. H\u00e1 seus problemas: o maior que vejo consiste na implementa\u00e7\u00e3o do m\u00e9todo respons\u00e1vel por popular sua inst\u00e2ncia de Criteria. Quanto maior for o n\u00famero de tipos de busca definidos na classe, maior ser\u00e1 a sua complexidade. Outro problema consiste no fato de n\u00e3o ficar \u00f3bvio \u00e0queles que est\u00e3o tendo seu primeiro contato com o c\u00f3digo como trabalhar com o mesmo. Afinal de contas, n\u00e3o h\u00e1 mais um m\u00e9todo como <i>buscarPessoasPorNome<\/i>, que torna n\u00edtidida a sua utiliza\u00e7\u00e3o.<\/p>\n<p>Com base no exemplo exposto neste artigo, podemos pensar em mais um refinamento em nosso padr\u00e3o. E se quisermos trabalhar com operadores como maior, menor, igual ou diferente? Simples: adicionamos mais um atributo \u00e0 nossa classe CriterioBusca chamada operador. O resto, deixo por conta de voc\u00eas como exerc\u00edcio. :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste post pretendo expor um padr\u00e3o bastante simples a ser aplicado na cria\u00e7\u00e3o de consultas usando a API Criteria do Hibernate. A API Criteria consiste em uma ferramenta extremamente poderosa que o Hibernate nos oferece para solucionar um problema muito comum no desenvolvimento de aplica\u00e7\u00f5es que precisem fazer consultas a banco de dados: a maldita [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7,6,1],"tags":[],"class_list":["post-8","post","type-post","status-publish","format-standard","hentry","category-hibernate","category-java","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/devkico.itexto.com.br\/?p=8\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico\" \/>\n<meta property=\"og:description\" content=\"Neste post pretendo expor um padr\u00e3o bastante simples a ser aplicado na cria\u00e7\u00e3o de consultas usando a API Criteria do Hibernate. A API Criteria consiste em uma ferramenta extremamente poderosa que o Hibernate nos oferece para solucionar um problema muito comum no desenvolvimento de aplica\u00e7\u00f5es que precisem fazer consultas a banco de dados: a maldita [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devkico.itexto.com.br\/?p=8\" \/>\n<meta property=\"og:site_name\" content=\"\/dev\/Kico\" \/>\n<meta property=\"article:published_time\" content=\"2008-07-26T03:55:27+00:00\" \/>\n<meta name=\"author\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@loboweissmann\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=8\",\"url\":\"https:\/\/devkico.itexto.com.br\/?p=8\",\"name\":\"Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico\",\"isPartOf\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\"},\"datePublished\":\"2008-07-26T03:55:27+00:00\",\"dateModified\":\"2008-07-26T03:55:27+00:00\",\"author\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\"},\"breadcrumb\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=8#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/devkico.itexto.com.br\/?p=8\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=8#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/devkico.itexto.com.br\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Criando consultas complexas no Hibernate de maneira din\u00e2mica\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\",\"url\":\"https:\/\/devkico.itexto.com.br\/\",\"name\":\"\/dev\/Kico\",\"description\":\"Desenvolvendo software\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/devkico.itexto.com.br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\",\"name\":\"Kico (Henrique Lobo Weissmann)\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"caption\":\"Kico (Henrique Lobo Weissmann)\"},\"sameAs\":[\"https:\/\/x.com\/loboweissmann\"],\"url\":\"https:\/\/devkico.itexto.com.br\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/devkico.itexto.com.br\/?p=8","og_locale":"pt_BR","og_type":"article","og_title":"Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico","og_description":"Neste post pretendo expor um padr\u00e3o bastante simples a ser aplicado na cria\u00e7\u00e3o de consultas usando a API Criteria do Hibernate. A API Criteria consiste em uma ferramenta extremamente poderosa que o Hibernate nos oferece para solucionar um problema muito comum no desenvolvimento de aplica\u00e7\u00f5es que precisem fazer consultas a banco de dados: a maldita [&hellip;]","og_url":"https:\/\/devkico.itexto.com.br\/?p=8","og_site_name":"\/dev\/Kico","article_published_time":"2008-07-26T03:55:27+00:00","author":"Kico (Henrique Lobo Weissmann)","twitter_card":"summary_large_image","twitter_creator":"@loboweissmann","twitter_misc":{"Escrito por":"Kico (Henrique Lobo Weissmann)","Est. tempo de leitura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devkico.itexto.com.br\/?p=8","url":"https:\/\/devkico.itexto.com.br\/?p=8","name":"Criando consultas complexas no Hibernate de maneira din\u00e2mica - \/dev\/Kico","isPartOf":{"@id":"https:\/\/devkico.itexto.com.br\/#website"},"datePublished":"2008-07-26T03:55:27+00:00","dateModified":"2008-07-26T03:55:27+00:00","author":{"@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7"},"breadcrumb":{"@id":"https:\/\/devkico.itexto.com.br\/?p=8#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devkico.itexto.com.br\/?p=8"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/devkico.itexto.com.br\/?p=8#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devkico.itexto.com.br\/"},{"@type":"ListItem","position":2,"name":"Criando consultas complexas no Hibernate de maneira din\u00e2mica"}]},{"@type":"WebSite","@id":"https:\/\/devkico.itexto.com.br\/#website","url":"https:\/\/devkico.itexto.com.br\/","name":"\/dev\/Kico","description":"Desenvolvendo software","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devkico.itexto.com.br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pt-BR"},{"@type":"Person","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7","name":"Kico (Henrique Lobo Weissmann)","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","caption":"Kico (Henrique Lobo Weissmann)"},"sameAs":["https:\/\/x.com\/loboweissmann"],"url":"https:\/\/devkico.itexto.com.br\/?author=1"}]}},"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/8"}],"collection":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8"}],"version-history":[{"count":6,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/8\/revisions"}],"predecessor-version":[{"id":14,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/8\/revisions\/14"}],"wp:attachment":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}