A abstração da tipagem
Um desenvolvedor, normalmente, não irá se preocupar em como a suaString
"nome da empresa" está definida no banco de dados, até por que o banco de dados pode mudar dependendo do cliente, e esta forma de armazenamento normalmente recairá sobre o DBA. Entre estes dois deve existir a documentação do sistema que irá definir a forma como cada um deve trabalhar, e, para evitar dores de cabeça, entre esta documentação é recomendável que existam alguns acordos técnicos como padrão de nomenclaturas e tipos de armazenamento.Os tipos de dados SQL
Cada banco de dados possui o seu conjunto próprio de tipos de dados, maior ou menor que os concorrentes, mas a especificação JDBC define um uso baseado em um conjunto genérico de tipos de dados SQL. Nesta postagem iremos analisar este conjunto genérico, mas uma análise de mapeamentos mais detalhada de qualquer banco, se necessária, pode ser encontrado na internet.CHAR, VARCHAR e LONGVARCHAR
Estes tipos representam textos, com tamanhos variáveis ou não, e devem ser mapeados para a classeString
. São manipulados através dos métodos ResultSet.getString
e PreparedStatement.setString
.NUMERIC e DECIMAL
Estes tipos representam números reais com precisão fixa, onde a precisão é importante para os cálculos matemáticos, arredondamentos ou representação textual, como, por exemplo, uso monetário ou comparações precisas. Devem ser mapeados para a classejava.math.BigDecimal
e são manipulados através dos métodos ResultSet.getBigDecimal
e PreparedStatement.setBigDecimal
.Caso você não conheça os problemas comuns encontrados ao trabalhar com os tipos
float
e double
, entenda que estes tipos geram pequenas inconsistências nas precisões numéricas que podem gerar falhas de lógica, inicie sua pesquisa a partir daqui: http://floating-point-gui.de/. BIT e BOOLEAN
Representam valoresboolean
e devem ser mapeados para a o tipo primitivo boolean
ou a classe Boolean
. São manipulados através dos métodos ResultSet.getBoolean
e PreparedStatement.setBoolean
.Muitos bancos de dados, como o Oracle, não implementam um tipo como estes. No Oracle uma das recomendações é o uso do tipo
CHAR
com uma constraint
de domínio de valores, veja abaixo:ALTER TABLE tabela ADD coluna_boleana CHAR CHECK (coluna_boleana IN (0,1) );
Mas como dito antes, o driver JDBC abstrai esta característica e torna transparente para o desenvolvedor.TINYINT
Representam números inteiros de 0 a 255 e devem ser mapeados para o tipobyte
. São manipulados através dos métodos ResultSet.getByte
e PreparedStatement.setByte
.Este tipo sofre com falta de suporte e é recomendável preferir o uso do tipo
SMALLINT
no lugar.SMALLINT
Representam números inteiros de -32768 a 32767 e devem ser mapeados para o tiposhort
. São manipulados através dos métodos ResultSet.getShort
e PreparedStatement.setShort
.INTEGER
Representam números inteiros de -2147483648 e 2147483647 e devem ser mapeados para o tipoint
ou a classe Integer
. São manipulados através dos métodos ResultSet.getInt
e PreparedStatement.setInt
.BIGINT
Representam números inteiros de 64 bits e devem ser mapeados para o tipolong
ou a classe Long
. São manipulados através dos métodos ResultSet.getLong
e PreparedStatement.setLong
.REAL
Representam números reais de precisão simples (7 dígitos de mantissa) e devem ser mapeados para o tipofloat
ou a classe Float
. São manipulados através dos métodos ResultSet.getFloat
e PreparedStatement.setFloat
.FLOAT e DOUBLE
Representam números reais de precisão dupla (15 dígitos de mantissa) e devem ser mapeados para o tipodouble
ou a classe Double
. São manipulados através dos métodos ResultSet.getDouble
e PreparedStatement.setDouble
.Para não gerar confusões no entendimento da precisão devido ao mapeamento SQL-Java o tipo SQL
FLOAT
deve ser evitado.BINARY, VARBINARY or LONGVARBINARY
Representam conjuntos de valores binários e devem ser mapeados para um vetor do tipobyte[]
. São manipulados através dos métodos ResultSet.getBytes
e PreparedStatement.setBytes
.DATE
Representam datas que consistem no conjunto de valores para dia, mês e ano e devem ser mapeados para a classejava.sql.Date
. São manipulados através dos métodos ResultSet.getDate
e PreparedStatement.setDate
.É recomendável que os valores de hora, minutos, segundos e milissegundos da classe
java.util.Date
sejam definidos como zero ao realizar conversões.TIME
Representam horas que consistem no conjunto de valores para hora, minutos e segundos e devem ser mapeados para a classejava.sql.Time
. São manipulados através dos métodos ResultSet.getTime
e PreparedStatement.setTime
.É recomendável que os valores de dia, mês e ano da classe
java.util.Date
sejam definidos como 1º de janeiro de 1970.TIMESTAMP
Representam o equivalente aos tiposDATE
e TIME
juntos mais o valor de nanossegundos e devem ser mapeados para a classe java.sql.Timestamp
. São manipulados através dos métodos ResultSet.getTimestamp
e PreparedStatement.setTimestamp
.Normalmente o tipo
TIMESTAMP
armazenará, também, o timezone.Outros tipos SQL
Além destes tipos existem outras especificações JDBC como, por exemplo,BLOB
ou CLOB
. Em geral estes outros mapeamentos seguem a regra conforme descrito nos tipos desta postagem. Se necessário, uma pequisa mais aprofundada é recomendada.Mapeamentos cruzados
A especificação JDBC também permite o mapeamento cruzado entre os diversos tipos, ou seja, é possível utilizar o métodoResultSet.getString
em praticamente todos os tipos SQL, o driver JDBC tentará realizar a conversão da forma mais adequada possível. Mas, isto não é uma regra, algumas conversões são impossíveis ou podem gerar erros, como por exemplo tentar extrair um número de um tipo VARCHAR
.Especificidades de bancos de dados
Caso você seja o responsável pela implementação SQL é importante conhecer as especificidades do banco de dados que irá trabalhar, muitas vezes um tipo é desencorajado ou inexistente e outro é recomendado no lugar, como foi anotado no tipo SQLBIT
acima. Esta recomendação será obedecida pelo driver JDBC e não causará nenhum problema para o desenvolvedor.Referências
http://docs.oracle.com/javase/tutorial/jdbc/basics/index.htmlhttp://docs.oracle.com/cd/B19306_01/java.102/b14188/datamap.htm
http://docs.oracle.com/javase/1.5.0/docs/guide/jdbc/getstart/mapping.html
http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html
http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
Nenhum comentário:
Postar um comentário
Olá! Antes de postar seu comentário, por favor, observe que comentários técnicos, elogios e sugestões são antecipadamente agradecidos, esclarecimentos sobre os conceitos envolvidos na postagem serão respondidos da melhor forma possível, mas pedidos de ajuda técnica ou suporte individual deverão ser feitos através do formulário de contato. Grato!