studio metodos example espaƱol elementos ejemplo cargar adicionar hashmap enumeration java

hashmap - metodos - map string string java



Rellenar una enumeraciĆ³n con valores de la base de datos (6)

Tengo una tabla que mapea String-> Integer.

En lugar de crear una enumeración estática, quiero rellenar la enumeración con valores de una base de datos. Es posible ?

Entonces, en lugar de descifrar esto estáticamente:

public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };

Quiero crear esta enumeración dinámicamente ya que los números {0,1,2,3} son básicamente aleatorios (porque son generados automáticamente por la columna AUTOINCREMENT de la base de datos).


En todos los idiomas que conozco, las enumeraciones son estáticas. El compilador puede hacer algunas optimizaciones sobre ellos. Por lo tanto la respuesta corta es no, no puedes.

La pregunta es por qué quieres usar una enumeración de esta manera. ¿Qué esperas? O en otras palabras, ¿por qué no usar una colección en su lugar?


Esto es un poco complicado, ya que la población de esos valores ocurre en el tiempo de carga de clase. Por lo tanto, necesitará un acceso estático a una conexión de base de datos.

Por mucho que valoro sus respuestas, creo que Jon Skeet puede estar equivocado esta vez.

Mira esto:

public enum DbEnum { FIRST(getFromDb("FIRST")), SECOND(getFromDb("second")); private static int getFromDb(String s) { PreparedStatement statement = null; ResultSet rs = null; try { Connection c = ConnectionFactory.getInstance().getConnection(); statement = c.prepareStatement("select id from Test where name=?"); statement.setString(1, s); rs = statement.executeQuery(); return rs.getInt(1); } catch (SQLException e) { throw new RuntimeException("error loading enum value for "+s,e); } finally { try { rs.close(); statement.close(); } catch (SQLException e) { //ignore } } throw new IllegalStateException("have no database"); } final int value; DbEnum(int value) { this.value = value; } }


Las enumeraciones no son dinámicas, por lo que la respuesta corta es que no puedes hacerlo.

También eche un vistazo a la pregunta de desbordamiento de pila enumeración dinámica en C # .


Mejorando lo que hizo Andreas , puede cargar el contenido de la base de datos en un mapa para reducir el número de conexiones de base de datos necesarias.

public enum DbEnum { FIRST(getFromDb("FIRST")), SECOND(getFromDb("second")); private Map<String,Integer> map; private static int getFromDB(String s) { if (map == null) { map = new HashMap<String,Integer>(); // Continue with database code but get everything and // then populate the map with key-value pairs. return map.get(s); } else { return map.get(s); } } }


Necesita replicar en el código lo que está en la base de datos (o viceversa). Vea esta question para algunos buenos consejos.


No. Las enumeraciones siempre se fijan en tiempo de compilación. La única forma en que podría hacer esto sería generar dinámicamente el bytecode relevante.

Habiendo dicho eso, probablemente deberías averiguar qué aspectos de una enumeración te interesan. Probablemente no quisieras usar una instrucción de switch sobre ellos, ya que eso significaría un código estático y no conoces los valores de forma estática ... Igualmente cualquier otra referencia en el código.

Si realmente solo desea un mapa de String a Integer , puede usar un Map<String, Integer> que rellena en el momento de la ejecución, y listo. Si desea las características de EnumSet , serían algo más EnumSet de reproducir con la misma eficiencia, pero puede ser factible con cierto esfuerzo.

Por lo tanto, antes de seguir adelante en términos de pensar en la implementación, le sugiero que averigüe cuáles son sus requisitos reales.

(EDITAR: He estado asumiendo que esta enumeración es completamente dinámica, es decir, que no conoce los nombres o incluso cuántos valores hay. Si el conjunto de nombres es fijo y solo necesita obtener el ID de la base de datos , eso es un asunto muy diferente - vea la respuesta de Andreas .)