quinta-feira, 29 de novembro de 2012

Trabalhando com XML e DOM Parser

Você provavelmente já deve saber o que é XML não é?

A wikipédia tem um artigo bastante completo sobre o assunto e o no site do W3C você vai achar muita informação interessante.

O XML é um sigla que vem de "eXtensible Markup Language". É uma linguagem de marcação recomendada pela W3C para a criação de documentos com dados organizados hierarquicamente, tais como textos, banco de dados ou desenhos vetoriais. Ele possui uma semântica própria. A questão do extensível ocorre porque o criador de um arquivo XML define os seus próprios elementos de marcação.

As principais características de um arquivo XML são:
  • todos os elementos devem ter um tag de fechamento. Veja no exemplo abaixo que a tag id é terminada com />

  • as tags são sensíveis ao caso, assim <nome> é diferente de <nOme>
  • as tags devem estar apropriadamente aninhadas. O exemplo abaixo está errado, pois </descricao> deveria preceder <pai>.

  • os atributos devem estar entre aspas
  • alguns caracteres tem significado especial em XML e não devem ser utilizados
  • comentários em XML são escritos no formato
<-- esta é uma linha de comentário. É o mesmo formato do HTML -->
  • os espaços são preservados. Diferentemente do HTML, múltiplos espaços em branco em sequência não são truncados.
  • XML armazena os caracteres de nova linha (CR + LF) como LF
Ok. Já temos uma idéia. O que vamos fazer?

Vamos criar um pequeno programa em Java para ler o arquivo


Veja como ficará o programa


O resultado da execução é:

segunda-feira, 26 de novembro de 2012

Usando JTable para visualizar uma tabela do banco de dados

Todas as linguagens de programação que possuem uma IDE têm um exemplo onde uma tabela de um banco de dados é vinculado a uma tabela e os dados são apresentados de forma tabular.

Quer dizer que consigo fazer isto no NetBeans também? A resposta é sim.

Vamos fazer um exemplo simples... Veja o vídeo.

Resumidamente faremos:
  1. abrir o banco de dados e verificamos o acesso a tabela CUSTOMER
  2. criamos um projeto
  3. criamos uma classe JFrame
  4. colocamos na JFrame uma classe JTable
  5. vinculamos a tabela ao banco de dados
  6. selecionamos as colunas que desejamos
  7. testamos a vinculação do JTextFied

sexta-feira, 23 de novembro de 2012

Trabalhando com Matrizes - Parte I

Existe uma outra forma de trabalhar com matrizes em Java que consiste em utilizar uma das diversas APIs que permitem trabalhar com recursos matemáticos avançados. No nosso caso vamos utilizar uma API  JAMA que é uma API de domínio público. Mais informações podem ser encontradas no site JAMA: A Java Matrix Package.

JAMA é um pacote básico de álgebra linear para Java. Ele fornece classes  para a construção e manipulação de matrizes. O pacote é composto por seis classes que manipulam matrizes e realizam cálculos de decomposição bastante complexos. São elas: Matrix, CholeskyDecomposition, LUDecomposition, QRDecomposition, SingularValueDecomposition e EigenvalueDecomposition.
A classe de matrizes (Matrix) fornece as operações fundamentais para realização de operações de álgebra linear. A classe possui um construtor que cria matrizes bidimensionais a partir de um array bidimensional de números em ponto flutuando. Por exemplo:

double[][] array = {{1,2,3},{4,5,6},{7,8,10}};
Matrix A = new Matrix(array);


A classe inclui ainda as principais operações como adição e subtração de matrizes, multiplicação de matrizes, multiplicação por escalar, matriz transposta, normas e seleções de elementos.

Para podemos usar em nosso ambiente Netbeans temos que baixar o arquivo JAR e incluir na biblioteca. Após realizar o download da API, crie um novo projeto e adicione o JAMA em sua lista de bibliotecas da seguinte forma:
  1. clique no botão direito em cima do projeto
  2. propriedades
  3. bibliotecas
  4. adicionar Jar

Veja no meu exemplo como ficou:

Vamos ver agora um exemplo da utilização desta biblioteca. Vamos tentar realizar as principais operações básicas de matrizes.

A saída para este programa é:
Fácil ?


Note que o Jama não permite trabalhar com números complexos e outras operações mais sofisticadas, mas já é um bom começo.

terça-feira, 20 de novembro de 2012

Coleções em Java - Parte I

Uma coleção de objetos em Java é um agregado ou agrupamento de referências a objetos (não o objeto em si), em alguma estrutura de dados. Cada objeto é um elemento da coleção.

Em Java temos um framework para representar coleções, permitindo manipular os elementos da coleção e a própria coleção, independentemente dos detalhes de sua representação, reduzindo o esforço para o programador. Este framework é composto por:

  • Interfaces: que permitem que as coleções sejam manipuladas independentes de suas implementações;
  • Implementações: são as classes que implementam uma ou mais interfaces do framework;
  • Algoritmos: são métodos que realizam operações como sort, reverse, binarysearch, etc sobre as coleções.



As principais coleções (implementações) são:



1) Set: são conjuntos de objetos e portanto seu comportamento está ligado à ideia subjacente aos conjuntos, assim como em um conjunto as classes que implementam esta interface não podem ter elementos repetidos.
  • HashSet: esta classe implementa um conjunto e ao mesmo tempo um método de acesso utilizando uma tabela hash (uma instância de HashMap)
  • LinkedHashSet: é uma implementação de tabela hash com listas encadeadas. Diferente do HashSet é mantida uma lista duplamente encadeada entre os elementos, com isto temos definida a ordem da iteração que é a ordem de inserção
  • TreeSet: implementado como uma árvore rubro-negra, gerando um conjunto ordenado de acordo com a ordenação natural dos elementos. É possível implementar um Comparator que especifica qual a ordem será seguida.
  • EnumSet: utilizada para type enumerados (Enum class). Todos os elementos de um EnumSet devem ser de um único tipo enumerado que é especificado implicita ou explicitamente quando o set é criado.
2) Deque: é uma implementação linear que suporta inserção e remoção nas duas extremidades (início e fim da lista). Deque quer dizer "double ended queue". Esta interface, diferentemente de List, não fornece suporte para indexação dos elementos.
  • LinkedList: é uma coleção implementada sob a forma de uma lista duplamente encadeada. Esta implementação também realiza a interface de List.
  • ArrayDeque: é uma implementação de um Array redimensionável, crescendo de acordo com a necessidade
3) Listas (List): implementa uma sequência de objetos ordenados, permitindo que os objetos sejam acessados por um índice. Diferente dos conjuntos, as listas suportam objetos duplicados.
  • ArrayList: implementada com Array
  • LinkedList: mesma implementação vista em Deque. As diferenças ocorrem no tipo de implementação. Por exemplo, em uma implementação com lista podemos utilizar o método .add(int index, E element) que permite inserir em uma posição específica. Se estivéssemos implementando somente Deque, usaríamos .add(E element), que insere no final da lista. O mesmo vale para .get() e .remove().
4) Pilhas (Stack)
  • Stack: implementa uma pilha no formato LIFO (last in first out), estendendo a classe Vector. Possui os métodos clássicos pop() e push() para manipular os objetos.
5) Mapas (Map): esta interface realiza o mapeamento entre dois valores no formato Map<K,V> onde K é a chave de acesso para o objeto V. Um mapa não pode ter chaves K duplicadas. Em termos acadêmicos, um mapa não é realmente uma coleção, é uma interface que implementam operações de visualização de coleções.
  • HashMap: é uma implementação de uma tabela hash
  • TreeMap: é uma implementação de árvore rubro-negra, sendo a ordenação fornecida pela ordem natural dos elementos ou por um Comparator atribuído na criação do mapa
  • LinkedHashMap: é uma implementação que une tabela hash e listas encadeadas (duplamente encadeada)
  • EnumMap: é uma implementação específica para utilização de tipos enumerados como chaves do mapa. Nesta implementação, todas as chaves devem vir de um único tipo enumerado.
Em um próximo post vamos  ver alguns exemplos.

quinta-feira, 15 de novembro de 2012

Hibernate - Parte IV

Criando a classe de teste

Bom, como já temos o mapeamento do objeto, a configuração do banco de dados e nossa primeira classe a ser persistida podemos criar um pequeno programa para vermos isto tudo funcionando.



Os passos para podermos gravar os dados são basicamente:

  1. Criamos uma sessão utilizando um SessionFactory
  2. Criamos uma transação nesta sessão, onde iremos gerar as manipulações
  3. Criamos o(s) objeto(s) a serem persistidos
  4. Chamamos Session.save() para cada objeto criado (não precisa ser como fiz, poderia ter chamado cada session.save logo depois terminar as atribuições em cada objeto
  5. terminamos a transação com Transaction.commit()
  6. fechamos a sessão com Session.close()

Conseguimos ... nossa primeira persistência com Hibernate.


quarta-feira, 14 de novembro de 2012

Hibernate - Parte III

Classe a ser persistida


Para o mapeamento em tabelas em um banco de dados o Hibernate utiliza classes consideradas POJO (Plain Old Java Objects). É necessário criar um arquivo de configuração que relacionamos em hibernate.cfg.xml para a classe Contato.java.

Primeiro vamos ver nossa classe simples:
Estamos criando uma classe simples com 4 campos encapsulados por getters e setters apropriados.

Criando o mapeamento da classe em XML

E agora vamos criar um arquivo de configuração para mapear a nossa classe de contatos:

Note que criamos uma entrada para com a tag <id>  que irá mapear a chave primária da tabela. Como sou muito criativo, o atributo do objeto e a coluna da tabela também chamam id.

Criei ainda 3 outras entradas utilizando a tag <property>, cada uma mapeando um dos atributos do objeto.

Por fim perceba que estas entradas estão todas dentro de uma tag <class> e esta tag tem uma propriedade denominada name que faz a relação com o objeto que criamos acima. Percebam que é necessário colocar o nome do pacote também.

terça-feira, 13 de novembro de 2012

Hibernate - Parte II

Configurando o arquivo de persistência do Hibernate

Na nossa aplicação de teste utilizaremos o Hibernate para gerenciamento de transações e conexões. Teremos que criar um arquivo de configuração que chamaremos de hibernate.cfg.xml. Neste arquivo criamos as configurações de conexão. Note que identificamos o driver, a URL que indica onde está o banco de dados, o usuário e a senha de acesso ao banco de dados. Além disto temos o mapeamento da classe que será persistida. No nosso caso é a classe Contato.

O modelo do arquivo XML de persistência é:



Para nosso exemplo utilizaremos o banco de dados Derby que é instalado juntamente com o NetBeans. Note nas primeiras linhas os parâmetros de conexão:
  • dialeto
  • driver_class
  • url
  • username
  • password

Podemos utilizar o Hibernate com diversos bancos de dados, os dialetos devem refletir o banco de dados correto, bem como a URL da conexão:
  • DB2 - org.hibernate.dialect.DB2Dialect
  • FrontBase - org.hibernate.dialect.FrontbaseDialect
  • HypersonicSQL - org.hibernate.dialect.HSQLDialect
  • Informix - org.hibernate.dialect.InformixDialect
  • Ingres - org.hibernate.dialect.IngresDialect
  • Interbase - org.hibernate.dialect.InterbaseDialect
  • Mckoi SQL - org.hibernate.dialect.MckoiDialect
  • Microsoft SQL Server - org.hibernate.dialect.SQLServerDialect
  • MySQL - org.hibernate.dialect.MySQLDialect
  • Oracle (any version) - org.hibernate.dialect.OracleDialect
  • Oracle 9 - org.hibernate.dialect.Oracle9Dialect
  • Pointbase - org.hibernate.dialect.PointbaseDialect
  • PostgreSQL - org.hibernate.dialect.PostgreSQLDialect
  • Progress - org.hibernate.dialect.ProgressDialect
  • SAP DB - org.hibernate.dialect.SAPDBDialect
  • Sybase - org.hibernate.dialect.SybaseDialect
  • Sybase Anywhere - org.hibernate.dialect.SybaseAnywhereDialect
No final do arquivo existe uma propriedade definida como:

     <property name="hibernate.show_sql">true</property>

Esta propriedade define que ao ser executado o programa o hibernate irá mostra os comandos SQL que está utilizando. Se este fosse um programa em produção, normalmente esta opção estaria com false ou o resultado seria gerado para um arquivo de log.

A última propriedade definida no arquivo é

<property name="hibernate.hbm2ddl.auto">create</property>

Isto garante de que o Hibernate irá automaticamente validar e exportar o esquema DDL (a estrutura das tabelas) para o banco de dados. Com a propriedade em create, ao tentar conectar no banco de dados, se as tabelas não existirem, elas serão criadas.

Mais informações sobre as configurações de sessões podem ser achadas neste site.

    segunda-feira, 12 de novembro de 2012

    Hibernate - Parte I

    Nós sempre precisamos guardar os dados que manipulamos em nossos programas. Algumas vezes basta utilizar um arquivo, como por exemplo para guardar as configurações de um programa ou o escore de um jogo, mas para a maioria das aplicações empresariais, guardar dados significa: acessar um banco de dados, inserir, editar, apagar e manipular informações.

    Uma forma de realizar esta tarefa é acessando diretamente o banco de dados, controlar cada atividade utilizando comandos SQL. Já vimos em um post anterior como criar uma conexão com um banco de dados.

    Outra forma é realizar a persistência usando a biblioteca Hibernate. Este pacote realiza um mapeamento tipo objeto-relacional fornecendo um framework para mapear os objetos na linguagem Java para um banco de dados relacional tradicional (como SQL Server, MySQL, Oracle, Apache Derby ou outros).

    Hibernate irá mapear classes Java para tabelas do banco de dados e mapeara os tipos de dados Java em tipos SQL, além de fornecer métodos de pesquisa de dados (realização de Query) e outros métodos de acesso a dados, gerando as chamadas SQL para nós e também manipulando os resultadores retornados pelo banco de dados utilizando estruturas de classes. Com isto as aplicações são portáveis para diferentes bancos de dados, bastando trabalhar as configurações de persistência, pois as operações são sempre iguais. O impacto em performance é pequeno em relação ao ganhos obtidos em facilidade de programação e portabilidade.

    O mapeamento das classes Java em tabelas é feito por meio de configurações em arquivos XML ou utilizando Annotations. Eu particularmente prefiro Annottations, pois a indicação no código é bastante esclarecedora e nos economiza a necessidade de ter que criar arquivos XML para o esquema de persistência.

    Hibernate ainda permite a criação de relacionamentos 1-para-muitos e muitos-para-muitos. Também permite criar relacionamentos reflexivos onde um objeto que possuir uma relação um-para-muitos com outras instâncias de sua classe. Temos suporte para herança, polimorfismo, composição e Java Collection. Com Hibernate temos condições de suporte a geraçao automática da chave primária.

    O Hibernate é tão flexível que permite que criemos mapeamentos para tipos customizados, do tipo:
    • sobrepor um tipo SQL quando mapeamos uma coluna a uma propriedade da classe;
    • mapear um tipo Enum Java para colunas com se elas fossem propriedades regulares;
    • mapear uma propriedade para múltiplas colunas em uma tabela.
    Hibernate provê três mecanismos de pesquisa:
    1. Hibernate Query Language (HQL) 
    2. Hibernate Criteria Query API e
    3. suporte para pesquisas em formato SQL nativo do banco de dados.
    A arquitetura do Hibernate pode ser representada pelo diagrama abaixo:
    Existem 3 principais componentes no Hibernate:
    • Connection Management
    Hibernate Connection fornece uma forma fácil de administrar as conexões com o banco de dados. Esta normalmente é a parte mais dispendiosa na interação com o BD utilizando muitos recursos para abertura e fechamento de conexões.
    • Transaction management
    O Transaction management fornece a capacidade do usuário executar mais de uma chamada ao banco de dados ao mesmo tempo.
    • Object relational mapping
    O mapeamento Objeto-Relacional é uma técnica que mapeia (traduz) da representação dos dados no modelo de objeto (os objetos e suas propriedades) em um modelo de dados relacionais (as tabelas e colunas). Este mapeamento é utilizado para selecionar, inserir, atualizar e apagar registros em uma tabela.

    Quando enviamos um objeto para o método Session.save() do Hibernate, este lê o estado das variáveis deste objeto e executa a query necessária.
    Chega de falação...leia no próximo post o nosso primeiro exemplo de Hibernate.
    Nos próximos posts, vamos ver como criar o arquivo de configuração de persistência, vamos criar uma classe a ser persistida utilizando o mapeamento por XML e usando Annottations.

    sábado, 10 de novembro de 2012

    Uso de generics em Java

    Afinal o que é Generics?

    Generics é uma facilidade de programação que foi adicionada à linguagem de  Java como parte do J2SE 5.0 em 2004. Este recurso permite que um tipo ou método para operar com objetos de vários tipos e ao mesmo tempo que fornece, em tempo de compilação, validação do tipo. Não entendeu?

    Vamos imaginar uma pilha ... lembra de pilha? É aquela estrutura de dados que você vai colocando as coisas dentro dela e a sequência de retirada destas coisa é da última para a primeira (LIFO).



    Vamos ver o teste.


    Criamos duas pilhas uma de Strings denominada sg e outra de Inteiros denominada ig. Se você tentar inserir uma String, por exemplo, em ig com ig.push(new Integer(1)) vai dar erro de compilação. O Java não deixa você nem mesmo executar o programa.



    PS: para quem que conhecer um pouco mais de estrutura de dados, dê um clique para o site da Professora Anita Lopes.

    Gerando um número reverso e MDC

    Dois números naturais (1,2,3,4,...) tem sempre um divisor comum, isto é, um número que divide ambos os números e resta zero (mesmo que este número seja 1). O maior divisor comum destes dois números é chamado de máximo divisor comum destes números, e é abreviado por MDC.

    Para representar uma fração normalmente fazemos com que o numerador e denominador sejam números primos, isto é, o MDC entre eles é 1. Assim se consideramos 2 números quaisquer a e b, uma fração a/b pode ser simplificada para c/d onde c e d são primos realizando a seguinte operação. Achamos os MDC(a,b) = m e achamos a = m * c e b = m * d.

    Podemos achar o MDC por fatoração dos 2 números ou pelo método das divisões sucessivas. Eu acho melhor implementar o segundo método, portanto:

    Vamos agora fazer uma classe bem simples - só para a gente treinar um pouco mais esta parte de manipulação matemática de inteiros. O que vamos fazer? Uma classe que passamos um número inteiro abcdef e a classe retorna outro número na ordem invertida. Temos diversos métodos de resolver este problema, os mais comuns são:
    •  transformar o inteiro em uma String e ler as posições da string na ordem inversa, gerando uma segunda String. Ao terminar convertemos esta segunda String em inteiro;
    • usamos restos sucessivos;
    • etc
    Acho que este segundo método tenha uma performance pior, porém ele permite a gente ver mais matemática.


    Notem a linha 28, vocês se lembram do último post? Dá para reescrever como
    numero /= 10

    segunda-feira, 5 de novembro de 2012

    Operando com frações

    Pode-se dizer que uma fração, representada de modo genérico como \frac{a}{b}, designa o inteiro dividido em b partes iguais ao qual se toma o número a de partes.

    Neste caso,  a corresponde ao numerador, enquanto b corresponde ao denominador, que não pode ser igual a zero.

    O denominador corresponde ao número de partes que um todo será dividido e o numerador corresponde ao número de partes que serão consideradas.



    Você já pensou em trabalhar com esta definição em Java? Para quê você vai me perguntar? Por diversão? Para permitir um estudante resolver os exercícios de casa sem ter que pensar muito? Sei não...

    Basicamente estou utilizando uma classe que denominei Fracoes para criar, somar e subtrair as frações.

    Notem que uma vez que o denominador não pode ser zero, eu gero uma exceção java.lang.IllegalArgumentException. A gente poderia mandar uma ArithmeticExpection como o erro vem de um parâmetro, achei mais interessante esta exceção.



    Para quem é novato: vejam as divisões nas linhas 65 e 66.

    Criei uma classe de teste que basicamente instancia 3 frações. Apresento abaixo a soma e a subtração dos valores.

    Vejam a saída do programa:
    • Na primeira linha temos f, seguido de f2 e f3.
    • Na quarta linha temos f + f2 e
    • Na quinta linha temos f - f3

    Tem bastante coisa para melhorar ainda. Como por exemplo dá para criar uma fração 1/-2 que deveria ser representada por -1/2. Dá para acrescentar a multiplicação e divisão. Mas isto fica para um próximo post.

    Se vocês notarem atentamente no código vão ver que tem uma classe que eu não coloquei... MDC que quer dizer máximo divisor comum. Para que eu uso ela? Para garantir que minhas frações fiquem sempre simplificadas. Como assim? Vejam que criei f3 como sendo 10/4 (linha 19 do código) mas na saída do programa ela já foi apresentada como 5/2.

    Vou deixar vocês pensarem um pouco com fiz isto e no próximo post coloco para vocês a solução.