Перечисление с постоянными, а также динамическими значениями из базы данных - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть текущее состояние, где enum MyType представляет таблицу типов со столбцами в виде:

ID
Name

И он используется для идентификации типа с помощью параметра ID с методом byId:

public enum MyType {

FIRST_TYPE("First Type", 10),
SECOND_TYPE("Second Type", 20);
public static class Holder {
    static Map<Integer, MyType > idMap = new HashMap<>();
    private Holder() { }
}

private MyType(String name, Integer id) {
    this.name = name;
    this.id = id;
    Holder.idMap.put(id, this);
}

public String getName() {
    return name;
}

public static MyType byId(Integer id) {
    return Holder.idMap.get(id);
}

Мое новое требование заключается в поддержке также значений, существующих в таблице типов, я нашел ответов для динамического перечисления, но принять ответ не для этого

Нет.Перечисления всегда фиксируются во время компиляции.Единственный способ сделать это - сгенерировать соответствующий байт-код динамически.

Что будет лучшим решением для поиска также значений (в основном идентификаторов) из базы данных (например, ID 30)

 select ID from TYPE

Могу ли я расширяет существующее состояние вместо его изменения?я могу добавить дополнительный IDS из базы данных, используя метод?

EDIT

Даже если я обновлю, как @StefanFischer предложил интерфейс, который заполняет карту классом enum и новым классом базы данных,Я все еще ожидаю в коде возвращаемое перечисление методом byId,

public interface MyType {
    public static class Holder {
        static Map<Integer, MyType> idMap = new HashMap<>();
        private Holder() { }
    }

    public default void add(MyType myType, Integer id) {
        Holder.idMap.put(id, myType);
    }


    public static MyType byId(Integer id) {
        return Holder.idMap.get(id);
    }
}

Ответы [ 3 ]

0 голосов
/ 19 июня 2019

enum представляет группу констант (неизменяемые переменные, такие как конечные переменные).Вы не можете определить его во время выполнения.

0 голосов
/ 21 июня 2019

Четкий не ответ: вы пытаетесь заставить себя не в том кроличьей норе.

Пункт Enums целом дает вам определенные преимущества при compile раз.Во время выполнения JVM не будет иметь значения, если у вас есть класс с некоторыми полями final static Whatever или Enum с другими константами.Или, если вы используете EnumSet вместо обычного Set.

Вы используете перечисления, потому что они позволяют записывать код source более элегантными способами.

Поэтому подход генерация перечислений в время выполнения не имеет смысла.

Идея перечислений заключается в том, что вы пишете исходный код, используя их.Но когда ваши перечисления сгенерированы для вас, как именно вы будете писать исходный код, используя их ?!Как уже упоминалось, перечисленные классы являются окончательными по умолчанию.Вы не можете расширять или улучшать их отдельно.Все, что вы хотели бы иметь, должно быть создано для вас.Что снова поднимает вопрос: как бы вы использовали что-то во время компиляции, которое генерируется во время выполнения?

Следовательно, с концептуальной точки зрения подход описан в другом ответе (использовать карту) - гораздо лучшая точка проектирования, чем пытаться превратить перечисления в нечто, чем они не должны быть.

0 голосов
/ 17 июня 2019

Если я правильно понимаю, требования следующие:

  • с методом MyType.byId (Integer id), который доставляет некоторые предопределенные значения
  • , его также следует динамически расширять изТаблица Type из базы данных

Таким образом, перечисление не может быть динамически расширено, но мы можем переключиться на класс.

Поэтому, оставаясь близко к вашему коду, можно написать что-то вроде:

import java.util.HashMap;
import java.util.Map;

public class MyType {

    static Map<Integer, MyType> idMap = new HashMap<>();
    static {
        idMap.put(10, new MyType("First Type"));
        idMap.put(20, new MyType("Second Type"));
    }

    private final String name;

    private MyType(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public static MyType byId(Integer id) {
        return idMap.get(id);
    }

    public static void addType(String name, Integer id) {
        MyType lookup = byId(id);
        if(lookup != null) {
            if(!lookup.getName().equals(name)) {
                System.out.println("conflicting redefinition for id " + id + ": '" + name + "' vs '" + lookup.name + "'");
                //handle...
            }
        }
        idMap.put(id, new MyType(name));
    }
}

Тестовые данные

Давайте предположим, что в базе данных есть следующее:

stephan=# select * from Type;
 id |    name     
----+-------------
 30 | Third Type
 10 | First Type
 20 | Second Type
(3 rows)

Итак, в базе данных у нас есть предопределенные типы с id = 10 и id = 20, а также тип с id = 30, который не известен по умолчанию для приложения.Но мы можем заполнить типы из базы данных.

Контрольный пример

public static void main(String[] args) {
    try {
        Connection connection = createConnection();
        try (connection) {
            populateTypes(connection);
        }

        MyType type;

        type = MyType.byId(10);
        System.out.println(type.getName());

        type = MyType.byId(20);
        System.out.println(type.getName());

        type = MyType.byId(30);
        System.out.println(type.getName());

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Пример JDBC

Это не 'Неважно, какая технология базы данных используется для получения значений.Вот пример для JDBC:

private static void populateTypes(Connection connection)
        throws SQLException {

    String sql = "SELECT * FROM type";
    try (Statement st = connection.createStatement()) {
        try (ResultSet rs = st.executeQuery(sql)) {
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                MyType.addType(name, id);
            }
        }
    }
}

Демонстрационный вывод

First Type
Second Type
Third Type

Это то, что вы ищете?

...