quinta-feira, 23 de janeiro de 2020

Gerando Script para Habilitar e Desabilitar Constraints de Tabela

Para melhor manusear tabelas de uma base de dados, de forma mais veloz, sem ter que ficar percorrendo as outras tabelas que são referenciadas na primeira, é possivel desabilitar as constraints. Atenção para não gerar dados corrompidos conforme a operação que for realizada depois disso.

Rode o script abaixo preenchendo o nome da tabela e o owner e na saída serão gerados os scripts a serem executados.




  1. SELECT 'alter table '||cons.owner||'.'||cons.table_name||' disable constraint '||cons.constraint_name||'; ' -- para habilitar so trocar o desable para enable
  2.  
  3. FROM dba_constraints      col,
  4.  
  5.    dba_constraints       cons
  6.  
  7. WHERE cons.r_owner = col.owner
  8.  
  9. AND cons.r_constraint_name = col.constraint_name
  10.  
  11. AND cons.constraint_type = 'R'
  12.  
  13. AND col.table_name IN( 'TB_CARROS') -- colocar tabelas que vai truncar aqui
  14.  
  15. AND col.owner = 'NOME_DO_ACESSO'
  16.  
  17. ORDER BY cons.table_name;



A partir deste script é possível criar um script único para habilitar ou desabilitar todas as constraints da base de dados.

Esse tipo de procedimento é interessante para iniciar uma limpeza geral na base de dados antes da subida em produção quando nem todas as tabelas devem ser limpas.



terça-feira, 6 de fevereiro de 2018

Limpeza de Cache do Chrome

Por vezes, rodamos uma aplicação e alguns problemas de carregamento de css e Javascript acontecem de forma comum. Segue uma forma de limpar o cache no Chrome. Abra duas abas do Chrome e digite no campo de url:





chrome://net-internals/#dns




Em seguida, basta clicar:



clear host cache







chrome://net-internals/#sockets



Em seguida, basta clicar:



flush socket pulls

sexta-feira, 30 de setembro de 2016

Internacionalização no Spring-Boot

Conforme prometido, vamos falar sobre I18n no Spring-Boot. Vamos utilizar o mesmo projeto das postagens anteriores:
http://toxinavirtual.blogspot.com.br/2016/09/crud-com-rest-spring-boot-e-jpa.html

Vamos criar os arquivos com as labels em Inglês, Espanhol e Português em arquivos diferentes com as diferentes traduções. Os arquivos deverão ficar dentro de uma pasta nova chamada de i18n que será criada dentro de resources. Os arquivos são de texto do tipo .properties.


No arquivo messages_en.properties, o conteúdo:
  1. field1 = My Field 1
  2. field2 = My Field 2



No arquivo messages_es.properties, o conteúdo:
  1. field1 = El Campo 1
  2. field2 = El Campo 2



No arquivo messages_pt.properties, o conteúdo:
  1. field1 = Meu Campo 1
  2. field2 = Meu Campo 2


Vamos criar agora o template hello.html dentro da pasta resources/template. O arquivo dever[a conter o seguinte:
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
  3. <head lang="en">
  4.     <meta charset="UTF-8" />
  5.     <title>HELLO</title>
  6. </head>
  7. <body>
  8.     <div>
  9.         <label for="field1" th:text="#{field1}"></label>
  10.         <input type="text" id="field1" name="field1" />
  11.     </div>
  12.     <div>
  13.         <label for="field2" th:text="#{field2}"></label>
  14.         <input type="text" id="field2" name="field2" />
  15.     </div>
  16.     <div>
  17.         <button type="submit">Save</button>
  18.     </div>
  19. </body>
  20. </html>

Repare que no template temos os campos em variáveis delimitadas por "#{}". O texto com o nome da variável deverá ser substituído pelas traduções dos arquivos properties.

O arquivo de template está usando um gerenciador de templates para que o Spring-Boot consiga interpretar o arquivo. Será necessário adicionar a dependência dentro do arquivo pom.xml.


  1.         <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4.         </dependency>



O template também depende de um controlador que determine a rota de acesso.

  1. package com.example.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. @Controller
  6. public class Hello {
  7.     @RequestMapping("/hello")
  8.     public String gohome(Model model){
  9.         return "hello";
  10.     }
  11.    
  12. }


A classe mapeada para o endereço /hello deverá retornar o nome do template sem a necessidade a da extensão .html. O conteúdo do arquivo será exibido, mas por enquanto sem a tradução.



Para implementar a tradução precisaremos extender o arquivo de inicialização para a classe WebMvcConfigurerAdapter. Como o arquivo de inicialização está extendendo o deploy criaremos um novo arquivo de configuração que funcionará paralelamente.


Com as anotations @Configuration, @EnableAutoConfiguration e @ComponentScan o Spring-Boot já saberá que se trata de um arquivo de configuração que possui componentes de configuração.


Primeiramente, criaremos um Locale. O Locale determina a linguagem através da região em que o site é acessado, assim como ajuda na configuração da tradução. O Locale geralmente fica armazenado na sessão do sistema.

  1.     //I18n do pacote web.servlet
  2.     @Bean
  3.     public LocaleResolver localeResolver() {
  4.         SessionLocaleResolver slr = new SessionLocaleResolver();
  5.         slr.setDefaultLocale(Locale.US);
  6.         return slr;
  7.     }

Agora criamos um interceptador do parâmetro de linguagem.
  1.     @Bean
  2.     public LocaleChangeInterceptor localeChangeInterceptor() {
  3.         LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
  4.         lci.setParamName("lang");
  5.         return lci;
  6.     }
  7.     //I18n
  8.     @Override
  9.     public void addInterceptors(InterceptorRegistry registry) {
  10.         registry.addInterceptor(localeChangeInterceptor());
  11.     }


Em seguida criamos um MessageSource e definimos o arquivo de origem da mensagem. O Validator vai executar a troca.

  1.     @Bean
  2.     public MessageSource messageSource() {
  3.         final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  4.         messageSource.setBasename("classpath:/i18n/messages");
  5.         messageSource.setUseCodeAsDefaultMessage(true);
  6.         messageSource.setDefaultEncoding("UTF-8");
  7.         return messageSource;
  8.     }
  9.    
  10.     @Override
  11.     public Validator getValidator() {
  12.         LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
  13.         validator.setValidationMessageSource(messageSource() );
  14.         return validator;
  15.     }
  16. }

Segue o arquivo na integra:
  1. package com.example.config;
  2. import java.util.Locale;
  3. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  4. import org.springframework.context.MessageSource;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.ComponentScan;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.support.ReloadableResourceBundleMessageSource;
  9. import org.springframework.validation.Validator;
  10. import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
  11. import org.springframework.web.servlet.LocaleResolver;
  12. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  13. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  14. import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
  15. import org.springframework.web.servlet.i18n.SessionLocaleResolver;
  16. @Configuration
  17. @EnableAutoConfiguration
  18. @ComponentScan
  19. class ApplicationConfig extends WebMvcConfigurerAdapter  {
  20.    
  21.     //I18n do pacote web.servlet
  22.     @Bean
  23.     public LocaleResolver localeResolver() {
  24.         SessionLocaleResolver slr = new SessionLocaleResolver();
  25.         slr.setDefaultLocale(Locale.US);
  26.         return slr;
  27.     }
  28.    
  29.     //I18n
  30.     @Bean
  31.     public LocaleChangeInterceptor localeChangeInterceptor() {
  32.         LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
  33.         lci.setParamName("lang");
  34.         return lci;
  35.     }
  36.     //I18n
  37.     @Override
  38.     public void addInterceptors(InterceptorRegistry registry) {
  39.         registry.addInterceptor(localeChangeInterceptor());
  40.     }
  41.     @Bean
  42.     public MessageSource messageSource() {
  43.         final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  44.         messageSource.setBasename("classpath:/i18n/messages");
  45.         messageSource.setUseCodeAsDefaultMessage(true);
  46.         messageSource.setDefaultEncoding("UTF-8");
  47.         return messageSource;
  48.     }
  49.    
  50.     @Override
  51.     public Validator getValidator() {
  52.         LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
  53.         validator.setValidationMessageSource(messageSource() );
  54.         return validator;
  55.     }
  56. }

Segue a imagem da label funcionando.





 É possível ainda melhorar o projeto de várias formas, como definir a liguagem na sessão antes do login.

Mais tarde atualizo o post com o código do github.