datos - obtener nombre columna resultset java
JDBC ResultSet obtiene columnas con alias de tabla (7)
Imagina que tengo una consulta como
SELECT * from table1 a, table2 b where (WHATEVER)
Quizás ambas tablas tengan el mismo nombre de columna. Así que pensé que sería bueno acceder a los datos a través de
resultSet.getString("a.columnName");
resultSet.getString("b.columnName");
Pero esto me falla y no consigo nada. Leí la API, pero realmente no hablan sobre este caso. ¿Es dependiente de tal característica del vendedor?
JDBC simplemente nombrará las columnas por lo que se especifica en la consulta, no sabe sobre los nombres de las tablas, etc.
Tienes dos opciones:
Opción 1: nombre las columnas de manera diferente en la consulta, es decir,
SELECT
a.columnName as columnNameA,
b.columnName as columnNameB,
...
from table1 a, table2 b where (WHATEVER)
luego, en su código java, consulte los alias de la columna:
resultSet.getString("columnNameA");
resultSet.getString("columnNameB");
Opción 2: consulte la posición de la columna en su llamada a la API de JDBC:
resultSet.getString(1);
resultSet.getString(2);
Tenga en cuenta que la API de JDBC utiliza índices basados en uno , es decir, cuentan desde 1
(no desde 0
como los índices de Java), así que use 1
para la primera columna, 2
para la segunda columna, etc.
Recomendaría la opción 1, porque es más seguro referirse a columnas con nombre: alguien puede cambiar el orden de las columnas en la consulta y rompería su código en silencio (estaría accediendo a la columna incorrecta pero no lo sabría), pero si cambie los nombres de las columnas, al menos obtendrá la excepción "no dicha columna" en el tiempo de ejecución.
Ok, parece que no hay un método como resultSet.getString("a.columnName");
y tiene que aliar sus columnas en el nivel sql, pero como hay un getTableName(iCol)
, espero que los chicos de java.sql.ResultSet
agreguen esa función.
Puede usar alias en el nivel de SQL. Luego recuperas datos por índices. (Pero este enfoque hará que el mantenimiento sea una verdadera pesadilla)
SELECT a.column, b.column FROM table1 a, table2 b
String value = rs.getString(1);
ResultSetMetadata.getColumnLabel () es lo que necesita
(edit) Ejemplo de muestra, como lo dice bharal en el comentario
SELECT * from table1 a, table2 b where (WHATEVER)
ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);
Si está utilizando MySQL simplemente agregue
&useOldAliasMetadataBehavior=true
a su connectionString.
Después puedes usar este pequeño Ayudante:
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ResultSetHelper {
private final Map<String, Integer> columnMap;
public ResultSetHelper(ResultSet rs) throws SQLException {
this.columnMap = new HashMap<>();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
for (int index = 1; index <= columnCount; index++) {
String columnName = md.getColumnLabel(index);
if (!columnMap.containsKey(columnName)) {
columnMap.put(columnName, index);
}
String tableAlias = md.getTableName(index);
if (tableAlias != null && !tableAlias.trim().isEmpty()) {
columnMap.put(tableAlias + "." + columnName, index);
}
}
}
public Integer getColumnIndex(String columnName) {
return columnMap.get(columnName);
}
public Integer getColumnIndex(String tableAlias, String columnName) {
return columnMap.get(tableAlias + "." + columnName);
}
}
Una idea que tuve fue usar getTableName(iCol)
para tomar los nombres de las tablas para las columnas con nombres duplicados, luego ajustar un hash de tus propias claves (con el prefijo del nombre de la tabla) que te indicaría el índice correcto de la columna, y referencia sus valores de columna de esa manera. Esto requeriría un ciclo inicial a través de los metadatos al comienzo de la configuración. El único problema que veo con esto es que también está aliasing los nombres de la tabla. Todavía tengo que encontrar una manera de obtener esos alias de nombre de tabla de jdbc sin administrarlo usted mismo cuando construye la instrucción sql. Esta solución dependería de lo que le pagaría la ganancia sintáctica.
Use alias de columna como:
SELECT A.ID ''A_ID'', B.ID ''B_ID'' FROM TABLE1 AS A, TABLE2 AS B...
Y especifique todas las columnas que está recuperando (es una buena práctica).