سؤال

ولدي الجدول التي تقوم بتعيين STRING-> صحيح.

وبدلا من خلق التعداد بشكل ثابت، وأريد لملء التعداد مع القيم من قاعدة البيانات. هل هذا ممكن؟

وهكذا، بدلا من delcaring هذا ثابت:

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

وأريد أن إنشاء هذا التعداد حيوي منذ الأرقام {0،1،2،3} بشكل عشوائي في الأساس (لأنها تم تكوينها بواسطة عمود AUTOINCREMENT قاعدة البيانات).

هل كانت مفيدة؟

المحلول

ولا. يتم إصلاح تتضمن التعدادات دائما في الترجمة من الوقت. إن الطريقة الوحيدة التي يمكن أن تفعل هذا سيكون لتوليد dyamically بايت كود ذات الصلة.

وأما وقد قلت ذلك، ربما يجب عليك العمل على الجوانب التي من التعداد كنت ترغب فعلا في. ومن المفترض أنك لم تكن ترغب في استخدام عبارة switch عليها، لأن ذلك يعني كود ثابت وكنت لا أعرف قيم ثابت ... وبالمثل أية مراجع أخرى في التعليمات البرمجية.

إذا كنت حقا تريد مجرد خريطة من String إلى Integer، يمكنك فقط استخدام Map<String, Integer> الذي نشر في وقت التنفيذ، والانتهاء من ذلك. إذا كنت تريد ميزات EnumSet، فإنها ستكون اصعب بعض الشيء لإنتاج بنفس الكفاءة، ولكن قد يكون ممكنا مع بعض الجهد.

وهكذا، قبل أن يذهب إلى أبعد من ذلك من حيث التفكير في التنفيذ، وأقترح عليك العمل على ما هي متطلباتك الحقيقية.

و(تحرير: لقد تم افتراض أن هذا التعداد هو دينامية تماما، أي أن كنت لا تعرف أسماء أو حتى عدد القيم هناك إذا تم إصلاح مجموعة من الأسماء وكنت <م> فقط بحاجة إلى جلب ID من قاعدة البيانات، وهذا أمر مختلف جدا - راجع <لأ href = "https://stackoverflow.com/questions/851466/populate-an-enum-with-values-from-database/851506 # 851506 "> أندرياس" الجواب ).

نصائح أخرى

وهذه هي صعبة بعض الشيء، لأن سكان تلك القيم يحدث في وقت الدرجة الحمل. لذلك سوف تحتاج إلى الوصول ثابت إلى اتصال قاعدة البيانات.

وبقدر ما أقدر إجاباته، وأعتقد أن جون السكيت قد أكون مخطئا هذه المرة.

ونلقي نظرة على هذا:

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

وتحسين على ما فعله أندرياس ، كنت يمكن تحميل محتويات قاعدة البيانات لرسم خريطة للحد من عدد الاتصالات قاعدة البيانات المطلوبة.

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

وتتضمن التعدادات ليست ديناميكية، وبالتالي فإن الجواب القصير هو أنك لا تستطيع أن تفعل ذلك.

وأيضا لديها نظرة على مسألة تجاوز المكدس <م> التعداد الحيوي في C # .

وتحتاج إلى تكرار في التعليمات البرمجية ما هو موجود في قاعدة البيانات (أو العكس بالعكس). انظر هذا السؤال للحصول على بعض النصائح الجيدة.

في جميع اللغات أعرف تتضمن التعدادات هي ثابتة. المترجم يمكن أن تجعل بعض التحسينات عليها. وبالتالي فإن الجواب القصير هو لا، لا يمكنك.

والسؤال هو لماذا تريد استخدام التعداد بهذه الطريقة. ماذا تتوقع؟ أو بعبارة أخرى لماذا لا تستخدم مجموعة بدلا من ذلك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top