Pregunta

Tengo una tabla que mapea String> Entero.

En lugar de crear una enumeración de forma estática, quiero poblar la enumeración con los valores de una base de datos. ¿Es esto posible?

Así que, en lugar de delcaring esta forma estática:

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 aleatorio (porque son generados automáticamente por la columna incremento automático de la base de datos).

¿Fue útil?

Solución

No. Las enumeraciones son siempre fijos en tiempo de compilación. La única forma de hacer esto sería generar el código de bytes dyamically relevante.

Una vez dicho esto, probablemente debería averiguar qué aspectos de una enumeración en realidad estás interesado en. Es de suponer que no estaban esperando para usar una switch declaración sobre ellos, ya que eso significaría código estático y usted don' sé los valores estáticamente ... así como cualesquiera otras referencias en el código.

Si realmente quieres un mapa de String a Integer, que sólo puede utilizar un Map<String, Integer> que se rellenan en tiempo de ejecución, y ya está. Si desea que las características EnumSet, serían un poco más difícil de reproducir con la misma eficacia, pero puede ser factible con un poco de esfuerzo.

Por lo tanto, antes de seguir adelante en términos de pensar acerca de la aplicación, le sugiero que trabajar con lo que sus necesidades son reales.

(EDIT:. He estado asumiendo que esta enumeración es completamente dinámico, es decir, que no conoce los nombres o incluso cuántos valores hay Si el conjunto de nombres es fijo y que solamente tendrá que obtener el ID de la base de datos, que es una cuestión muy diferente - ver Andreas' respuesta .)

Otros consejos

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

Por mucho que valoro sus respuestas, creo que Jon Skeet puede ser mal esta vez.

Tome un vistazo a 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;
    }
}

La mejora en lo hizo Andreas , puede cargar el contenido de la base de datos en un mapa de reducir el número de conexiones de bases 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); }
    }
}

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

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

Es necesario replicar en el código de lo que está en la base de datos (o viceversa). Ver este pregunta para algunos buenos consejos.

En todos los idiomas que conozco enumeraciones son estáticos. El compilador puede hacer algunas optimizaciones en ellos. Por lo tanto, la respuesta corta es no, no se puede.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top