Frage

Ich habe eine Tabelle, die Karten String-> Integer.

Anstatt eine ENUM statisch schaffen, mag ich die Enum mit Werten aus einer Datenbank füllen. Ist das möglich?

Also, anstatt delcaring dies statisch:

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

Ich mag diese Enum dynamisch erstellen, da die Zahlen {0,1,2,3} im Grunde zufällig sind (weil sie durch die Datenbank der AUTOINCREMENT-Spalte automatisch generiert werden).

War es hilfreich?

Lösung

Nein. Aufzählungen sind immer zur Compile-Zeit festgelegt. Die einzige Möglichkeit, dies tun könnte, wäre zu dyamically den entsprechenden Bytecode zu erzeugen.

Having said that, sollten Sie wahrscheinlich herausarbeiten, welche Aspekte eines ENUM sind Sie tatsächlich interessiert an. Vermutlich wollen Sie wurden nicht switch Aussage über sie verwenden, da die statische Code bedeuten würde, und Sie wissen nicht, die Werte statisch ... ebenfalls andere Referenzen im Code.

Wenn Sie wirklich nur eine Karte von String Integer möchten, können Sie einfach einen Map<String, Integer> verwenden, die Sie bei der Ausführung zu füllen, und du bist fertig. Wenn Sie die EnumSet Funktionen nutzen möchten, würden sie etwas schwieriger sein, mit der gleichen Effizienz zu reproduzieren, aber es kann mit einigem Aufwand möglich sein.

Also, bevor darüber nachzudenken Umsetzung in Bezug auf es weiter gehen kann, schlage ich vor, Sie arbeiten heraus, was Ihre tatsächlichen Anforderungen sind.

(EDIT:. Ich habe unter der Annahme, dass diese Aufzählung vollständig dynamisch, dh, dass Sie nicht wissen, die Namen oder sogar, wie viele Werte gibt es Wenn der Satz von Namen festgelegt ist und Sie nur muß die ID aus der Datenbank holen, das ist eine ganz andere Sache - siehe Andreas' Antwort .)

Andere Tipps

Das ist ein bisschen schwierig, da die Bevölkerung dieser Werte bei Klasse-Ladezeit geschieht. So benötigen Sie einen statischen Zugriff auf eine Datenbankverbindung.

So viel wie ich seine Antworten schätzen, ich glaube, Jon Skeet diesmal falsch sein kann.

Werfen Sie einen Blick auf diese:

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;
    }
}

zur Verbesserung der was Andreas tat , Sie laden Sie den Inhalt der Datenbank in eine Karte, um die Anzahl der Datenbankverbindungen reduzieren erforderlich.

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); }
    }
}

Aufzählungen sind nicht dynamisch, so die kurze Antwort ist, dass Sie es nicht tun können.

auch einen Blick auf Stack-Überlauf Frage Dynamische Enum in C # .

Sie müssen in Code replizieren, was in der Datenbank (oder umgekehrt) ist. Sehen Sie diese Frage für einige gute Ratschläge.

In allen Sprachen, die ich kenne Aufzählungen statisch sind. Der Compiler kann einige Optimierungen auf sie machen. Deshalb ist die kurze Antwort ist nein, man kann es nicht.

Die Frage ist, warum Sie eine ENUM auf diese Weise verwenden möchten. Was erwartest du? Oder mit anderen Worten, warum eine Sammlung nicht stattdessen verwenden?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top