Gerenciando a linha atual

Escrevemos o primeiro programa e funcionou perfeitamente. Escrevemos uma consulta, executamos e, como resultado, o método executeQuery() nos retornou um objetoconjunto de resultadosUm que contém todos os resultados da consulta. E agora vamos tentar descobrir como obter esses resultados.

O resultado da consulta pode conter milhares de linhas e centenas de colunas de vários tipos, portanto, essa não é uma tarefa tão trivial quanto você pode imaginar. Por exemplo, as imagens podem ser armazenadas no banco de dados, então você pode obter uma imagem como um conjunto de bytes ou um InputStream para baixá-lo.

Mas vamos começar com o mais simples - com o conceito de “ linha de resultado atual ”. Como o resultado geralmente tem muitas linhas, o objetoconjunto de resultadostem um ponteiro para a linha atual dentro. E alterna sequencialmente as linhas para lê-las usando o método next() .

Essa abordagem é feita principalmente para otimização. O driver JDBC pode não carregar strings do banco de dados até que você consiga lê-los sequencialmente. Você também leu FileInputStream sequencialmente do começo ao fim. Portanto, essa abordagem deve ser familiar e compreensível para você.

No entanto, se você realmente precisar, os arquivos podem ser lidos em qualquer lugar usando a classe RandomAccessFile .

A classe ResultSet também permite algo semelhante e permite que você mova a linha atual ao longo do resultado para qualquer lugar. Para fazer isso, ele tem os seguintes métodos:

Método Descrição
1 próximo() Alternar para a próxima linha
2 anterior() Alternar para a linha anterior
3 é primeiro() Linha atual primeiro?
4 isBeforeFirst() Estamos na frente da primeira linha?
5 isLast() A linha atual é a última?
6 isAfterLast() Estamos após o prazo?
7 absoluto(int n) Torna a linha Nth atual
8 relativo(int n) Move a linha atual N posições para frente. N pode ser <0
9 getRow() Retorna o número da linha

Os métodos são bastante simples, mas duas explicações precisam ser feitas. Os resultados são, por assim dizer, emoldurados por linhas vazias em ambos os lados. Portanto, inicialmente a linha atual está antes da primeira linha do resultado. E para obter a primeira linha, você precisa chamar o método next() pelo menos uma vez .

Se você chamou o método next() na última linha , então você moveu para a linha após a última . Você não pode ler os dados dele, mas nenhum erro ocorrerá. Aqui o método isAfterLast() irá declarar true como resultado.

Exemplo:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");

System.out.println( results.getRow() );        	// 0
System.out.println( results.isBeforeFirst() );  // true
System.out.println( results.isFirst() );          	// false

results.next();

System.out.println( results.getRow() );        	// 1
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// true

results.next();

System.out.println( results.getRow() );        	// 2
System.out.println( results.isBeforeFirst() );  // false
System.out.println( results.isFirst() );          	// false

Obtendo dados da linha atual

Você aprendeu a gerenciar com maestria a linha atual. Agora vamos descobrir como obter dados dele. Para isso, o objetoconjunto de resultadosexistem métodos especiais que podem ser todos descritos por um modelo:

getType(numberColumns)

No entanto, se a coluna tiver um nome, você também poderá obter pelo nome da coluna:

getType(nameColumns)

Exemplo:

while (results.next()) {
        	Integer id = results.getInt(“id”);
        	String name = results.getString(“name”);
        	System.out.println(results.getRow() + ". " + id + "\t"+ name);
}

Abaixo vou fornecer uma tabela que irá ajudá-lo a associar tipos de dados SQL e métodos ResultSet:

Tipo de dados SQL Métodos getXXX()
CARACTERES getString()
VARCHAR getString()
INT getInt()
FLUTUADOR getDouble()
CLOB getClob()
BLOB getBlob()
DATA getDate()
TEMPO consiga tempo()
TIMESTAMP getTimestamp()

O ponto, eu acho que você entendeu.

Obtendo dados diferentes sobre o ResultSet

Descobrimos como ler os dados da linha atual: tanto pelo número da coluna quanto pelo nome. A propósito, como posso descobrir o nome da coluna pelo seu número? Ou o número de colunas no resultado?

Por um lado, se você escreve um pedido, parece que precisa saber de tudo isso. Por outro lado, podemos escrever um programa que exiba na tela o resultado de uma consulta: a consulta é passada para nós e queremos apenas exibir na tela (no console, na página web) tudo o que o servidor SQL retornou para nós.

O JDBC possui um objeto especial para isso, a interface ResultSetMetaData . Obter um objeto desse tipo é bem simples:

Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM user");
ResultSetMetaData resultSetMetaData = results.getMetaData();

A interface ResultSetMetaData possui alguns métodos muito interessantes. Abaixo estão os mais populares:

1 getColumnCount() Retorna o número de colunas de resultado
2 getColumnName(int coluna) Retorna o nome da coluna
3 getColumnLabel(int coluna) Retorna a descrição da coluna
4 getColumnType() Retorna o tipo de coluna: número (código especial)
5 getColumnTypeName() Retorna o tipo de coluna: string
6 getColumnClassName() Retorna o nome da classe java para o tipo de coluna
7 getTableName() Retorna o nome da tabela
8 getCatalogName() Retorna o nome do diretório da coluna
9 getSchemaName() Retorna o nome do esquema do banco de dados
10 isAutoIncrement(coluna int) A coluna suporta AUTO INCREMENT?
onze éNullable() Uma coluna pode conter NULL?

Vamos aproveitá-la para aprender um pouco sobre nossa tabela:

ResultSetMetaData metaData = results.getMetaData();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++)
{
        	String name = metaData.getColumnName(column);
        	String className = metaData.getColumnClassName(column);
        	String typeName = metaData.getColumnTypeName(column);
        	int type = metaData.getColumnType(column);

        	System.out.println(name + "\t" + className + "\t" + typeName + "\t" + type);
}

Importante! Preste atenção que as colunas são numeradas a partir de 1. As linhas, aliás, também. Quão incomum é isso, certo?

E este é o resultado que obtive após executar o programa:

"C:\Arquivos de Programas\Java\jdk-17.0.3.1\bin\java.exe...
eu ia java.lang.Integer INT 4
nome java.lang.string VARCHAR 12
nível java.lang.Integer INT 4
Data de criação java.sql.date DATA 91
Processo finalizado com código de saída 0