segunda-feira, 22 de agosto de 2016

27/08 - Unijorge

Encontro JavaBahia - 27 de Agosto 2016 - Auditório Unijorge Comércio

Retomando o ciclo de atividades de 2016, teremos nossa reunião presencial agora em Agosto, que vai acontecer no Auditório da Unijorge no Comércio, na Rua Miguel Calmon, 42, Edf. São Paulo. Mas não é só isso: Preparamos conteúdos super interessantes pra você!!! Dá uma conferida:
  • Java User Group – O que é e como eu posso participar? - Mário Jorge Pereira
  • Comunidade Java no mundo - A experiência de um membro do nosso JUG - Otávio Santana
  • Carreira do desenvolvedor Java: O que eu preciso saber? - Antônio Lázaro
  • JPA de A à Z: Porque conhecer a JPA? - Mateus Malaquias
  • Encerramento - Neste momento temos um espaço aberto para você contribuir e falar o que quiser!!!
Ok, mas como eu faço pra participar?

As inscrições estão sendo feitas pelo formulário no link https://goo.gl/forms/MSH6Tjx9PEk9oabl1, então corre lá e garante sua vaga, porque são limitadas!!!



Ah, já ia me esquecendo: Através da parceria com os cursos tecnológicos da Unijorge, poderemos emitir certificado. Já dá uma força na carga horária!

Encontro JavaBahia - Agosto/2016
Local: Auditório da Unijorge Comércio Prédio IV - Rua Miguel Calmon, 42, Edf. São Paulo - Comércio Salvador-BA CEP: 40.015-060 71 (https://goo.gl/maps/oFTN5rpo3YU2)
Data: 27/08/2016 (sábado), das 09:00 às 12:00



quarta-feira, 3 de agosto de 2016

JPA de A à Z - Vantagens e Desvantagens

No post anterior tentei instigar você a conhecer a JPA e a entender o motivo dessa especificação ser tão utilizada atualmente. No post de hoje vamos analisar as vantagens e desvantagens dessa especificação, a ideia é que com o pouco da minha experiência passemos a entender que toda solução pode se torna um fardo se utilizada incorretamente. Sinta-se convidado a compartilhar suas experiências nos comentários.

  • VANTAGENS:
  1. Indepêndencia: Utilizando JPQL ou Criteria conseguimos ter uma indepêndencia com os bancos de dados porque agora fica a cargo da implementação da JPA em converter sua consulta em SQL nativo. Agora as ações básicas de insert, update e delete também ficam por conta da implementação. Com isso podemos criar uma única aplicação que vai se comunicar com diversos bancos de dados.
  2. Reduz a necessidade de conhecer SQL: Não me leve a mal, ainda penso que conhecer pelo menos o básico de SQL é fundamental para qualquer programador. Todavia você consegue trabalhar com a JPA sem esse conhecimento.
  3. Dê adeus a conversão de querys em objetos: No post anterior você teve um gostinho do trabalho que braçal necessário para se obter um objeto com o JDBC. Justamente para não perdemos mais tempo com isso nasceram as implementações da JPA que são capazes de realizar esse trabalho para gente.
  4. Otimização automática: Nem sempre temos o trabalho de otimizar uma consulta, mas esse é um ponto que considero critico porque muda de implementação para implementação e nem sempre temos o resultado desejado. Caso você precise ter um sistema em que as consultas sejam sempre otimizadas recomendo que utilize o Batoo no lugar do Hibernate por exemplo.
  5. Cache de dados: Cache de dados é muito util para diminuir a quantidade de requisição ao banco de dados, o chace de dados também faz com que o desempenho da sua aplicação melhore caso você tenha cuidado com o custo de RAM necessário.

Não me leve a mal a JPA é uma ferramenta muito poderosa e muitas vezes pensamos que ela é a solução para tudo, também não é incomum querer resolver todos os problemas do mundo com ela. Não vejo nada de errado nisso, desde que sempre se preocupe com os pontos abaixo:

  • DESVANTAGENS:
  1. Base de dados legada: Nem sempre foi possível executar triggers, functions e procedures direto no banco de dados. Atualmente podemos fazer isso, todavia temos que ter cuidado com o impacto que isso pode gerar ao modelo objeto-relacional e a indepêndencia a respeito dos bancos de dados. Hoje em dia por exemplo passo boa parte da minha atividade migrando e otimizando procedures no Java justamente por isso.
  2. Chaves compostas: AH! Que raiva tenho de utilizar @embedded, trabalhar com chaves compostas na JPA significa aumentar drasticamente a complexidade de nossas entidades. Em determinadas situações para executar um update ou insert por exemplo precisamos gerar muito mais código.
  3. Curva de aprendizado para além do básico: Fazer o feijão com arroz utilizando JPA é fácil e muito pratico, isso é bom porque atrai sempre novas pessoas. Mas quando passamos para um nível mais avançado como por exemplo utilizar chaves compostas, chace, criteria e relacionamentos bidirecionais as pessoas começam a encontrar diversas dificuldades. Esse aqui é justamente um dos motivos de existir a serie JPA de A à Z aqui no blog.
  4. Indepêndencia facilmente quebrada: Quebrar a indepência de banco não é difícil. Alguma vezes não tem jeito e precisamos apelar para o SQL nativo seja porque a otimização com a especificação não ficou suficientemente boa ou ate mesmo quando precisamos fazer uma união de consultas.
  5. Unir consultas: Esse pra mim é o defeito mais grave na especificação, simplesmente não conseguimos realizar união de consultas. Claro que podemos utilizar alguns artifícios para simular uma união, mas na grande maioria das vezes é necessários optar pelo SQL nativo e ai vai embora a independência de banco de dados.

Enfim, hoje quis apresentar a vocês o meu ponto de vista sobre a JPA de uma forma mais detalhada por meio das minhas experiências com a especificação. Claro que a JPA não deixa de ser uma arma poderosa mesmo tendo essas desvantagens, por isso fica aqui o meu apelo para que ocorra um planejamento ao utilizar a JPA.

segunda-feira, 25 de julho de 2016

JPA de A à Z - Por que usar JPA?

Não dá pra negar que o Java é uma linguagem bastante verbosa e quando falávamos em juntar o Java com um banco de dados ai sim dava pra ver o tamanho do problema. Se não tivéssemos cuidado era muito fácil perder o controle da complexidade de nossas entidades e consultas.
Antes de entendermos sobre a  JPA, é necessário entender que costumávamos utilizar em nossos projetos o JDBC (Java Database Connectivity) que é uma API presente no Java desde a versão 1.1 da plataforma. Mesmo sendo uma API bem antiga ela ainda continua sendo atualizada e modificada pela comunidade e pela Oracle. Resumidamente o JDBC é o antecessor da JPA porque ela era a principal forma de executar nossas querys SQL de select, update, delete, insert e até mesmo executar funções presentes no banco de dados. Um detalhe interessante sobre o JDBC são seus Drivers de conexão, sendo cada banco de dados é responsável por desenvolver e atualizar o seu Driver. Isso facilitava muito a vida do desenvolvedor porque esses Drivers visam encapsular boa parte do código necessário para se conseguir uma conexão, então era uma preocupação a menos que tínhamos que ter.
Mas nem tudo eram flores quando usávamos o JDBC, porque além de ter que escrever códigos SQL direto no Java, tínhamos também que instanciar uma conexão, buscar a conexão com o banco de dados. Dai era preciso preparar um outro objeto para poder manipular a consulta informando os valores dos parâmetros e só então executávamos a consulta.
Acabávamos tendo um trabalho tedioso só para executar uma consulta, todavia o ciclo não acabava nisso, depois era preciso fazer um casting do retorno da consulta para com objeto que queríamos manipular e como se não fosse suficiente também era necessário lembrar de fechar as conexões com o banco de dados.  É preciso entender que estamos falando de muito tempo atrás, um tempo em que as facilidades da JPA ainda não existiam e que muita especificação que existe hoje nasceu das dificuldades do passado.

public class MovimentacaoDAO {
 
 private Movimentacao buscaMovimentacaoPorId(int id) throws SQLException {
  String sql = "SELECT valor, tipoMovimentacao FROM Movimentacao WHERE id = ?";
  PreparedStatement preparedStatement = null;
  Connection conexao = null;
  Movimentacao objMovimentacao = null;
  try {
   //aqui buscamos uma conexão
  conexao = FabricaDeConexao.getUmaConexaoComBanco();
   //aqui preparamos o objeto da conexão
   preparedStatement = (PreparedStatement) conexao.prepareStatement(sql);
   preparedStatement.setInt(1, id);
   //então executamos a consulta
   ResultSet rs = preparedStatement.executeQuery();
   objMovimentacao = new Movimentacao();
   //aqui estamos fazendo casting de valores
   while (rs.next()) {
    objMovimentacao.setValor(new BigDecimal(rs.getString("valor")));
          objMovimentacao.setTipoMovimentacao(rs.getString("tipoMovimentacao"));
   }
  } finally {
   //aparti daqui lembramos que temos que fechar as conexões
   if (preparedStatement != null) {
    preparedStatement.close();
   }
   if (conexao != null) {
    conexao.close();
   }
  }
  return objMovimentacao;
 }
}

Olhando pra esse código podemos passar um baita sufoco se por acaso algum dia o analista de requisitos resolva mexer nos atributos da entidade Movimentação. Nessa DAO de exemplo só foi criada uma única consulta, mas vamos usar nossa criatividade e imaginar que na verdade existem 10 e o analista resolveu mudar o nome da coluna tipoMovimentacao para tipo. Uma pequena mudança de nomenclatura já é suficiente para que perdêssemos tempo refatorando boa parte de nossas consultas que estivessem usando a coluna tipoMovimentacao.
Foi para evitar todo esse trabalho que surgiu o conceito ORM (Object Relational Mapping) que traduzindo livremente de acordo com a minha vontade quer dizer: “Estou salvando a sua alma transformando os dados de um banco de dados que estão no paradigma relacional para o paradigma orientado a objetos que você tanto precisa”.
Junto com a ORM também surgiu o Hibernate que é o framework JPA mais famoso e utilizado no momento. Só por curiosidade saiba que a JPA surgiu por causa dele, viram que a ideia era tão boa que resolveram transformar a implementação do Hibernate em uma especificação e até hoje muita coisa que é implementada no framework posteriormente vira especificação na JPA.
Mas o que é JPA?
JPA significa Java Persistence API e como já falei ela é uma especificação que nasceu de uma JSR (Java Specification Requests) que basicamente são pedidos para mudanças na linguagem, entenda a JPA como um contrato, normas, regras ou interface e que todos os Frameworks Java que trabalham com persistência de dados devem implementa-la. Além do Hibernate também temos outros Framworks como por exemplo o OpenJPA, o Batoo e o EclipseLink.
Então basicamente a JPA é uma especificação que regulamenta ferramentas muito poderosas que utilizamos no nosso dia a dia para automatizar e economizar tempo de desenvolvimento. Essa especificação nos ajuda em todos os processos quando precisamos trabalhar com um banco de dados, sendo assim podemos usa-la para executar consultas, inserts, updates e deletes.
Lembra daquele código verboso? Como sera que ele ficaria se fosse escrito utilizando a JPA?

EntityManager manager = new JPAUtil().getEntityManager();  
Movimentacao movimentacao = manager.find(Movimentacao.class, 1);
System.out.println(movimentacao.getTipoMovimentacao());

Repare que não foi necessário criar uma única query SQL para executar a consulta por ID, também não foi preciso fazer nenhum casting. A JPA se encarregou de fazer tudo isso e ela pode fazer muito mais.
Por fim espero que você nos acompanhe nos proximos posts porque vamos aprender mais sobre essa ferramenta poderosa junto com boas práticas. A ideia é de que os posts não sejam muito longos e também não sejam tutorias de JPA ou Hibernate. Aqui iremos explorar os conceitos de forma que você consiga compreender o momento exato de usar cada recurso da especificação.

segunda-feira, 25 de janeiro de 2016

Palestras confirmadas [Linguagil 2016]



Você já viu a grade de palestras do LinguÁgil 2016? Como sempre, ela está bem misturada, trazendo diversos assuntos ligados a linguagens de programação, frameworks, agilidade, comportamento e carreira.

Além da participação da comunidade através das apresentações submetidas e selecionadas, mais uma vez, teremos "keynotes", com palestrantes de referência. Outro fato importante é que pelo menos um terço das apresentações será feito por mulheres, numa ação para demonstrar como a participação feminina é necessária e muito bem-vinda.


Sexta, 18/03/16:



  • 08:50 às 09:35 - O trabalho de FDP do PO: fatiar, descartar e priorizar! (Mila Orrico)
  • 10:15 às 10:35 - SBTM - Testes exploratórios guiados à sessão (Lorena Caldas)
  • 10:45 às 11:30 - Construindo aplicativos móveis com Ionic Framework (Isaque Dias)
  • 11:30 às 12:15 - DevOps é uma prática, cultura ou um cargo? (Carlos Felippe Cardoso)
  • 13:45 às 14:30 - Programação Reactiva (Osvaldo "Tupy" Matos)
  • 14:50 às 15:35 - Como empreender tendo um emprego? (Paula Antunes)
  • 16:05 às 16:50 - Dobro do Resultado na Metade do Tempo (Rafael Miranda)
  • 16:50 às 17:35 - Histórias de Usuário - Por que e como escrever requisitos de forma ágil? (Rafael Helm)



Sábado, 19/03/16:



  • 08:50 às 09:35 - Controlefobia (Juliano Ribeiro)
  • 09:35 às 09:55 - Hackeando Representatividade: Mulheres Empreendedoras (Ana Paula Vargas Maia)
  • 10:15 às 10:35 - Quero ser um certificado Scrum! Porque ter e o que devo fazer para ter? (Adriana de Melo Fontes)
  • 10:45 às 11:30 - Resiliência, a competência que nos leva a excelência (Anneliese Gripp)
  • 11:30 às 12:15 - Computação Ubíqua, o que isso tem a ver com Android Wear. (Ramon Mota)
  • 13:45 às 14:30 - Empreendendo com Software Livre. (Francine Grando)
  • 14:50 às 15:35 - Programação funcional com Java 8 (Otávio Santana)



Visite a página do evento, veja mais informações e se inscreva: http://linguagil.com.br

quarta-feira, 30 de dezembro de 2015

Abertas as inscrições para o Linguagil 2016




Está aberta as inscrições do LinguÁgil 2016 com o preço de 2015.
Os mini-cursos já estão confirmados:

  • Lego4Scrum
  • Novidades do PHP 7
  • Olá Mundo Ágil - A sua Porta de Entrada no Mundo Ágil!
  • REST APIs em Python e Django
  • Práticas Jedi eXtreme Programming


Para mais informações e inscrição,

Inscreva-se: http://buff.ly/1ZAjQzK

quarta-feira, 11 de novembro de 2015

Divulgação C4P do Linguágil 2016




A sétima edição do "LinguÁgil" será realizada no primeiro semestre de 2016 entre os dias 16-19 de março na UniJorge, em Salvador/BA, e a chamada para trabalhos (Call for Papers) está aberta. O evento abrange diversas linguagens de programação, agilidade e outros temas.
O evento é promovido pelo Grupo LinguÁgil, formado por membros de diversas comunidades de tecnologia. Este é um evento sem fins lucrativos que tem como principal objetivo promover a divulgação, o debate e a troca de experiências entre especialistas, profissionais e estudantes. O encerramento do C4P será no dia 30 de novembro.


quinta-feira, 11 de junho de 2015

Trabalhando com Clipboard (área de transferência)


Ampliando o poder do CTRL+C / CTRL+V e tirando Printscreens da tela.


A maioria das vezes que utilizamos o CTRL+C, estamos com algum texto selecionado, mas
quando selecionamos um conjunto de arquivos, diretórios ou alguma imagem ou parte dela?

O Java nos fornece o objeto Clipboard, onde conseguimos acessar essa área de transferência.
Em conjunto com DataFlavor, conseguimos determinar quais tipos de dados estão na área.

Para obter uma instância do Clipboard, pedimos ao Toolkit:

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

Uma vez com o objeto clipboard em mãos, basta saber o que está na área de transferência:

try {
 if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
  clipboard.getData(DataFlavor.stringFlavor).toString();
  
 } else if (clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor)) {
  List<File> files = (List<File>) clipboard.getData(DataFlavor.javaFileListFlavor);
  
 } else if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) {
  BufferedImage image = (BufferedImage) clipboard.getData(DataFlavor.imageFlavor);
 }
 
} catch (UnsupportedFlavorException | IOException ufe) {
 Logger.getLogger(getClass().getName()).log(null, null, ufe);
}

Neste exemplo estamos verificando apenas três tipos de dados, para ver outros tipos, consulte
a documentação. Na primeira verificação, temos um texto, nada que um editor de texto básico
não aceite. Já no segundo if, verificamos se o que foi copiado são pastas ou arquivos. Por fim, se temos uma imagem, gerada pela tecla Print Screen ou uma cópia do Paint, por exemplo.

Aplicação de exemplo

Nossa aplicação consiste em “colar” texto, arquivo e imagem, conforme código de exemplo anterior, ao clicar no botão Paste. Para texto, o comportamento é o padrão de qualquer editor. Já para os arquivos, ele apenas gera quatro listagens:
  •  Caminho completo dos arquivos, separados por “;”
  •  Caminho completo separados por linha
  •  Apenas o nome dos arquivos separados por “;”
  •  Nome dos arquivos separados por linha

private void pasteFiles(List<File> files) {
  if (files.size() == 1) {
   taResult.append(files.get(0).getAbsolutePath());
   taResult.append("\n");
   taResult.append(files.get(0).getName());
  } else {
   taResult.append("Caminho completo com ';':\n");
   for (File f : files) {
   taResult.append(f.getAbsolutePath());
   taResult.append(";");
   }
 
   taResult.append("\nNomes com ';':\n");
 
   for (File f : files) {
    taResult.append(f.getName());
    taResult.append(";");
   }
 
   taResult.append("\n");
   taResult.append("\nCaminho completo:\n");
 
   for (File f : files) {
    taResult.append(f.getAbsolutePath());
    taResult.append("\n");
   }
 
   taResult.append("\nNomes:\n");
 
   for (File f : files) {
    taResult.append(f.getName());
    taResult.append("\n");
   }
  }
}
Eu, por diversas vezes, preciso do nome de diversos arquivos em uma pasta para colocar na documentação, mas você poderia por exemplo, carregar o conteúdo do(s) arquivo(s), ou outras coisas (daquele tipo de coisa que se faz com arquivos). No caso da imagem, além de exibir uma prévia, a aplicação salva a imagem no formato JPG, na mesma pasta da aplicação.

As imagens são salvas em sequência, que é útil quando se está fazendo um tutorial.

private void pasteImage(BufferedImage image) {
 BufferedImage resizeImage = new BufferedImage(lblImage.getWidth(), lblImage.getHeight(), BufferedImage.TYPE_INT_RGB);
 Graphics g = resizeImage.createGraphics();

 g.drawImage(image, 0, 0, lblImage.getWidth(),lblImage.getHeight(), null);
 g.dispose();
 lblImage.setIcon(new ImageIcon(resizeImage));

 File fImg = new File("imagem_" + count + ".jpg");
 try {
 ImageIO.write(image, "jpg", fImg);
 count++;
 taResult.append("\nImagem salva em: " + fImg.getAbsolutePath());
 } catch (IOException ex) {
 Logger.getLogger(Window.class.getName()).log(Level.SEVERE, null, ex);
 }
}

Print Screen + Paste


Já sabemos como trabalhar com uma imagem no clipboard, mas dependemos de alguém ter clicado na tecla Print Screen antes, sendo que já vi teclados sem essa tecla. Mas o Java nos permite simular esse clique utilizando o método createScreenCapture da classe Robot, projetada inicialmente com o propósito de facilitar testes automáticos.

...
try {
 robo = new Robot();
} catch (AWTException ex) {
 Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
...

private void print() throws HeadlessException {
 if (robo != null) {
 Dimension screenSize = toolkit.getScreenSize();
 BufferedImage print = robo.createScreenCapture(new Rectangle(screenSize));
 pasteImage(print);
 }
}

Nó tiramos um print da tela inteira (toolkit.getScreenSize()) e depois salvamos a imagem utilizando o mesmo método pasteImage, visto anteriormente. Tudo isso ao clicar no botão Print and Save.
Para deixar as coisas mais interessantes, utilizamos a classe javax.swing.Timer para capturar a tela automaticamente a cada meio segundo, isso se o checkbox Auto Print estiver marcado.

timer = new Timer(500, new ActionListener() {
 @Override
 public void actionPerformed(ActionEvent e) {
 if (cbAutoPrint.isSelected()) {
 print();
 }
 }
});

Por fim

Com Java é fácil saber e obter o que o SO colocou na área de transferência e trabalhar com o que foi colocado lá, já saber o que fazer com isso, nem tanto. Em todo caso, qualquer editor de texto / imagem que se preze, precisa saber trabalhar com o clipboard. Vimos o objeto Robot superficialmente, mas com o que já vimos, criamos um programa para gravar a tela, facilitando a criação de tutoriais passo-a-passo (ou espionagem, vai saber...).

Você pode baixar a aplicação em https://sourceforge.net/projects/mvbostools.

PDF: https://drive.google.com/file/d/0B1rjzjT1KgoTanlfQ2dqRGNhNkk/view

Feito no NetBeans 8, o código fonte direto do SVN: https://sourceforge.net/p/mvbostools/code/HEAD/tree/Mlipboard

Java Doc:
http://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html
https://docs.oracle.com/javase/8/docs/api/java/awt/datatransfer/DataFlavor.html

Marcus Becker
meumundojava@gmail.com