Pergunta

Ao usar JDBC, eu muitas vezes deparamos com construções como

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int id = rs.getInt(1);
    // Some other actions
}

Perguntei-me (e autores de código também) porque não usar rótulos para recuperar valores de coluna:

int id = rs.getInt("CUSTOMER_ID");

A melhor explicação que eu ouvi é algo sobre o desempenho. Mas, na verdade, faz o processamento extremamente rápido? Eu não acredito que sim, embora eu nunca ter realizado medições. Mesmo se recuperando pela gravadora seria um pouco mais lento, no entanto, proporcionar uma melhor legibilidade e flexibilidade, na minha opinião.
Então alguém poderia me dar uma boa explicação de evitar para recuperar valores de coluna por índice de coluna em vez de rótulo de coluna? Quais são prós e contras de ambas as abordagens (talvez, relativas a certos DBMS)?

Foi útil?

Solução

Você deve usar rótulos de cordas por padrão.

Pros:

  • Independência da ordem da coluna
  • Melhor legibilidade / manutenção

Contras:

  • Você não tem controle sobre os nomes das colunas (acesso através de procedimentos armazenados)

O que você prefere?

ints?

int i = 1;
customerId = resultSet.getInt (i ++);
customerName = ResultSet.getString (i ++);
CustomerAddress = ResultSet.getString (i ++);

ou cordas?

customerId = resultSet.getInt ( "customer_id");
customerName = ResultSet.getString ( "customer_name");
CustomerAddress = ResultSet.getString ( "customer_address");

E se há uma nova coluna inserida na posição 1? Qual o código que você prefere? Ou se a ordem das colunas é alterado, qual versão do código que você precisa mudar em tudo?

É por isso que você deve usar rótulos de cordas por padrão.

Outras dicas

Atenção: Eu estou indo para obter bombástica aqui, porque isto me deixa louco

.

99% * das vezes, é um micro-otimização ridículo que as pessoas têm uma vaga ideia torna as coisas 'melhor'. Isso ignora completamente o fato de que, a menos que você está em um loop extremamente apertado e ocupado ao longo de milhões de resultados SQL o tempo todo , que é esperançosamente rara, você nunca vai notar. Para todos que não está fazendo isso, o custo de tempo desenvolvedor maintaing, atualização e correção de bugs na indexação coluna são muito maiores do que o custo incremental de hardware para o seu infinitamente pior, desempenho da aplicação.

Não otimizações de código como este no. Código para a pessoa mantê-la. Em seguida, observar, medir, analisar e otimizar. Observe novamente, medir novamente, analisar novamente, e otimizam novamente.

Optimization é praticamente o último passo no desenvolvimento, não o primeiro.

* A figura é composta.

A resposta foi aceite, nada-a-menos, aqui estão algumas informações adicionais e experiência pessoal que eu não vi ainda apresentadas.

Use os nomes das colunas (constantes e não literais é o preferido) em geral e, se possível. Isto é tanto mais clara, é mais fácil de manter, e futuras alterações são menos propensos a quebrar o código.

Há, no entanto, um uso para índices de coluna. Em alguns casos, estes são mais rápidos, mas não suficientemente que este deve substituir as razões acima para nomes *. Estes são muito valioso no desenvolvimento de ferramentas e métodos gerais lidar com ResultSets. Finalmente, um índice pode ser necessária porque a coluna não tem um nome (como um agregado sem nome) ou existem nomes duplicados por isso não há maneira fácil de fazer referência ambos.

* Nota que eu escrevi alguns drivers JDBC e olhou para dentro algumas fontes abertas um e internamente esses índices uso de colunas para referenciar as colunas de resultados. Em todos os casos com quem trabalhei, o condutor interno primeira mapeia um nome da coluna para um índice. Assim, você pode ver facilmente que o nome da coluna, em todos os casos, seria sempre levar mais tempo. Isto pode não ser verdade pois embora todos os drivers.

A partir da documentação java:

A interface ResultSet fornece métodos getter (getBoolean, getLong, e assim sucessivamente) para a recuperação de valores de coluna a partir da linha corrente. Os valores podem ser recuperados usando o número do índice da coluna ou o nome da coluna. Em geral, utilizando o índice de coluna será mais eficiente. As colunas são numeradas a partir de 1. Para o máximo de portabilidade, colunas conjunto de resultados dentro de cada linha deve ser lido da esquerda para a direita a fim, e cada coluna deve ser lido apenas uma vez.

É claro que cada método (chamado ou indexada) tem o seu lugar. Concordo que colunas nomeadas deve ser o padrão. No entanto, nos casos em que são necessários um grande número de loops, e onde a instrução SELECT é definido e mantidos na mesma seção do código (ou classe), os índices devem estar ok - é aconselhável para listar as colunas que estão sendo selecionadas, e não apenas "SELECT * FROM ...", uma vez que qualquer mudança mesa vai quebrar o código.

Claro, usando nomes de coluna aumenta a legibilidade e facilita a manutenção. Mas o uso de nomes de colunas tem um efeito colateral. Como você sabe, SQL permite que vários nomes de coluna com o mesmo nome, não há nenhuma garantia de que o nome da coluna que você digitou no método getter de resultSet realmente aponta para o nome da coluna que pretende acesso. Em teoria, usando números de índice em vez de nomes de coluna é preffered, mas reduz a legibilidade ...

Graças

Eu não acho que usando o desempenho etiquetas impactos por muito. Mas há outra razão para não usar Strings. Ou ints, para essa matéria.

Considere o uso de constantes. Usando uma constante int torna o código mais legível, mas também menos propensos a ter erros.

Além de ser mais legível, a constante também impede você de fazer typo de nos nomes de rótulo - o compilador irá lançar um erro se o fizer. E qualquer valor IDE nada vai buscá-lo. Este não é o caso, se você usar Strings ou ints.

Eu fiz algumas desempenho profiling sobre este assunto exato em um banco de dados Oracle. Em nosso código, temos um ResultSet com inúmeras colums e um enorme número de linhas. Dos 20 segundos (!) O pedido leva para executar método oracle.jdbc.driver.ScrollableResultSet.findColumn (String name) leva cerca de 4 segundos.

Obviamente há algo de errado com o design geral, mas usando índices em vez dos nomes de coluna provavelmente levaria este 4 segundos de distância.

Você pode ter o melhor de ambos! A velocidade do uso de índices com a manutenção e segurança do uso de nomes de coluna.

Primeiro -. A menos que você está looping através de um conjunto de resultados apenas usar nomes de coluna

  1. Defina um conjunto de variáveis ??inteiras, um para cada coluna que você vai acessar. Os nomes das variáveis ??podem incluir o nome da coluna: por exemplo, iLast_Name.

  2. Antes do laço conjunto de resultados iteração através da coluna de metadados e definir o valor de cada variável número inteiro para o índice do nome da coluna correspondente da coluna. Se o índice de coluna 'Last_Name' é 3, em seguida, definir o valor de 'iLast_Name' para 3.

  3. No loop conjunto de resultados usar os nomes de variáveis ??inteiro nos métodos GET / SET. O nome da variável é uma pista visual para o desenvolvedor / mantenedor quanto ao nome da coluna real que está sendo acessada, mas o valor é o índice da coluna e vai dar o melhor desempenho.

. NOTA: o mapeamento inicial (isto é, o nome da coluna para o mapeamento de índice) é feito apenas uma vez antes de o ciclo, em vez de para cada ficha e coluna no loop

O driver JDBC cuida para a coluna para o índice do look-up. Então, se você extrair valores pelo nome da coluna cada vez que o motorista faz um look-up (geralmente no mapa de hash) para verificar o índice correspondente para o nome da coluna.

Eu concordo com respostas anteriores que o desempenho não é algo que pode nos forçar para selecionar qualquer uma das abordagens. Seria bom considerar as seguintes coisas em vez disso:

  • Código legibilidade:. Para cada desenvolvedor de ler as etiquetas de código têm muito mais sentido do que os índices
  • Manutenção: pensar a consulta SQL ea forma como ela é mantida. O que é mais provável de acontecer no seu caso depois da fixação melhorar consulta SQL / / refatoração: alterar a ordem das colunas extraídos ou alterar os nomes das colunas de resultados. Parece para mim que alterar a ordem das colunas extraídos (como os resultados de inclusão / exclusão de novas colunas no conjunto de resultados) tem maior probabilidade de acontecer.
  • encapsulamento: apesar da maneira que você escolher tentar isolar o código onde você executar a consulta SQL e conjunto de resultados de análise no mesmo componente e fazer apenas este componente ciente sobre os nomes das colunas e seu mapeamento para os índices (se você decidiu usá-los).

Usando o índice é uma tentativa de otimização.

O tempo poupado por isso é desperdiçado pelo esforço extra que leva o desenvolvedor de olhar para cima os dados necessários para verificar se o seu código irá funcionar corretamente após as alterações.

Eu acho que é a nossa built-in instinto de usar números em vez de texto.

Além do olhar-se no mapa para etiquetas Ela também leva a uma criação de Cordas extra. Mas isso vai acontecer na pilha, mas ainda cárie um custo com ele.

Tudo depende da escolha individual e até agora eu tenho usado apenas índices: -)

Como é apontado por outros cartazes, eu iria ficar com os nomes das colunas a menos que tenha uma razão muito poderosa para não fazê-lo. O impacto no desempenho é insignificante em comparação com, por exemplo, a otimização da consulta. Neste caso, a manutenção é muito mais importante do que uma pequena Otimização.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top