Как сделать выбор таблицы базы данных статическим без использования строк

Прежде всего, этот вопрос будет довольно длинным, но чтобы полностью объяснить мою проблему, я чувствую, что должен дать вам много информации о моем проекте, поэтому, пожалуйста, потерпите меня!

Я работаю в компании, которая часто использует диаграммы, поэтому, чтобы избежать проблем, всегда приходится создавать диаграммы из scats. Я решил создать новый проект Java и создать "пакет", который я и мои коллеги могли бы использовать для их создания. графики. Вы могли бы назвать их универсальными.

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

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

Прежде всего позвольте мне показать вам классы и объяснить поток данных (я сделаю это как можно короче):

Прежде всего, это GUI (это класс, который пользователь всегда должен будет создавать сам, но он может использовать встроенный пакет для создания своей диаграммы, используя следующий код):

ChartBuilder cb = new LineChartBuilder();
                  Director d = new Director();
d.buildTypeOne(cb, "Hello", PeriodSelection.HOUR,"");

С этим директор теперь готов построить диаграмму.

PeroidSelection.Hour является перечислением, которое устанавливает стандартное время, в этом случае оно устанавливает ось категории диаграмм в соответствии с нашим начальным, и поэтому собираемые данные знают, что они должны получать данные ежечасно (с 8.00 - 19.00 в этом случае). Причина, почему Это Enum в том, что эти типы периодов являются своего рода конечной единственной вещью, которая может измениться, это наши первые дни и часы, которые мы затем сможем изменить довольно легко! вот предварительный просмотр PeriodSelection enum:

    public enum PeriodSelection{
    HOUR(new String[]{"8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00"}),
    MONTH(new String[]{"Jan", "Feb", "Marts", "April", "Maj", "Juni", "Juli", "Agu", "Sep", "Oct", "Nov", "Dec"}),
    DAYS(new String[]{"Mandag", "Tirsdag", "Onsdag","Torsdag","Fredag","Lørdag","Søndag"});

    private String[] timeIntervals;
    private PeriodSelection(String[] timeIntervals){
        this.timeIntervals = timeIntervals;
    }
    public String[] getTimeIntervals(){
        return timeIntervals;
    }
}

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

    public void buildTypeOne(ChartBuilder builder, String title, PeriodSelection selection, String queueName){
    try {
        builder.setObjectList(stat.getData(queueName, start, end));
    } catch (DopeDBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    builder.selection = selection;
    builder.initiate(title);
    builder.createSeries();
    builder.createSymbol();

    builder.createTable();
}

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

Теперь класс статистики, как показано в первой строке buildTypeOne метод расширяется и абстрактный класс называется statisticPattern это выглядит так:

public abstract class StatisticPattern {


protected ArrayList<ObjectInterface> cq = new ArrayList<>();
protected ObjectInterface contact;
protected ProviderInterface p;
/**
 * 
 * 
 * {@link Constructor}
 */
public StatisticPattern(){
    try {
        p = new Provider();
    } catch (DopeDBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
/**
 * 
 * @param name
 * @param start
 * @param end
 * @return
 * @throws SQLException
 * @throws DopeDBException
 */
protected ArrayList<ObjectInterface> getData(String name, DateTime start, DateTime end) throws SQLException, DopeDBException{
    return cq;
}
/**
 * 
 * @param contact2
 */
protected void processSingleQueueData(ObjectInterface contact2) {
}
/**
 * 
 * @param queueName
 * @throws SQLException
 */
protected void obtainNewData(String queueName) throws SQLException {

}

/**
 * 
 * @param name
 * @param start
 * @param end
 * @return
 */
protected boolean doIhaveIt(String name, DateTime start, DateTime end) {
    return false;
}
/**
 * 
 * @param start
 * @param end
 * @return
 */
protected boolean checkDatas(DateTime start, DateTime end) {
    return start.toDateMidnight().isEqual(end.toDateMidnight());
}
/**
 * 
 * @param start
 * @param end
 * @return
 */
protected Integer daysBetween(DateTime start, DateTime end) {
    return  end.dayOfYear().get()-start.dayOfYear().get();

}

Как заявил eailer, цель этого класса состоит в том, чтобы наши разработчики расширили класс и переопределили методы, чтобы директор мог найти эти методы и использовать их по своему выбору для реализации и заполнения методов в зависимости от программы.

В этой программе статистический класс выглядит так:

public class Statistics extends StatisticPattern {
private DateTime start;
private DateTime end;


/**
 *  This class checks whether the program has already collected the data
 * @Override
 */
public ArrayList<ObjectInterface> getData(String name, DateTime start, DateTime end) throws DopeDBException{
    if (this.start.equals(start) && this.end.equals(end)) {
        if (name.equalsIgnoreCase("All")) {
            return cq;
        }else if (doIhaveIt(name, start, end)) {
            return cq;
        }
    }else {
        try {
            obtainNewData(name);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return cq;
}
@Override
protected void obtainNewData(String queueName) throws SQLException {
    setDates(start, end);
    this.cq = p.obtainData(start, end, queueName);

}

Как вы можете видеть, я создал свою собственную реализацию getData Метод этот метод вызывает obtainNewData метод, который затем получает данные из p (который наш класс провайдера - также известный как соединение с базой данных).

Класс провайдера, как вы уже догадались, также реализует интерфейс и интерфейс, в котором есть только один метод. obtainData метод

public interface ProviderInterface {

public ArrayList<ObjectInterface> obtainData(DateTime start, DateTime end, String name) throws SQLException;

}

Опять же, разработчик должен реализовать этот метод, но может заполнить его так, как ему нравится. Наиболее важным здесь является то, что возвращаемый тип - это ArrayList типа ObjectInterface:

public interface ObjectInterface {

HashMap<String, Integer> data = new HashMap<String, Integer>();
String type = "";

public String getType();
public void addData(String key, Integer value);
public Integer getData(Object key);

}

По сути, он должен реализовывать хэш-карту, которая содержит все данные, которыми должна заполняться диаграмма. Эти данные будут добавлены, когда объект будет создан, а затем добавлен в список в поставщике, затем этот список будет возвращен, и директор установит его в список данных построителей диаграмм, который затем заполнит диаграммы.

в этом случае конечный объект, который должен заполнить диаграммы, выглядит следующим образом:

public class ContactQueue implements ObjectInterface {

    private HashMap<String, Integer> data = new HashMap<String, Integer>();
    private String type;
    public ContactQueue(String type){
        this.type = type;
    }
    public String getType(){
        return type;
    }
    public void addData(String key, Integer value){
        if (data.containsKey(key)) {
            Integer i = data.get(key);
            data.put(key, value+i);
        }else {
            data.put(key, value);
        }

    }
    public Integer getData(Object key){
        return data.get(key);
    }
    public String toString(){
        return type;
    }
}

Теперь к вопросу!

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

Я уже пробовал с помощью следующего кода:

        if (name.equalsIgnoreCase("Besvarelse")) {
        return besvarelse25(start, end);
    }else if (name.equalsIgnoreCase("intern")) {
        return intern(start, end);
    }else if (name.equalsIgnoreCase("besvarelseProcent")) {
        return besvarelseProcent(start,end);
    }else if (name.equalsIgnoreCase("Email_data")) {
        return email_data(start, end);
    }else if (name.equalsIgnoreCase("Email_Hånd")) {
        return email_haand(start, end);
    }else if (name.equalsIgnoreCase("Email_Antal")) {
        return email_antal(start, end);
    }
    else if (name.equalsIgnoreCase("Henvendelser")) {
        return henvendelser(start, end);
    }

Однако это кажется излишним и, по меньшей мере, уродливым.

Я думал о создании Enum снова, что клиент (разработчик) должен был меняться каждый раз, когда он хотел создать новую программу, но я не уверен, что это правильный способ сделать это?

Также я хотел бы услышать, что вы думаете об общем проекте? я прибил это или потерпел неудачу?

Спасибо за чтение, и я буду с нетерпением ждать, чтобы прочитать ваши ответы

2 ответа

Решение

Мнение: поскольку вы, кажется, фильтруете в конце на основе резервной базы данных, решение простое / элегантное. Да, это избыточно и безобразно, но так же как и схема, в которой есть 5 таблиц схожей информации (если я правильно понял). Если это работает, я не думаю, что у вас есть проблемы.

Если вы обеспокоены тем, что вам нужно выбрать "правильный тип" таблицы, вы можете найти общее качество каждого из них:

Нечто подобное->

  SELECT 
    generic.specificField AS "genericKey",
    ....
  FROM
    TableOne generic

Затем вы можете создать HashMap (или объект, ваш вызов), который бы удовлетворял некоторому уровню согласованности вашего дизайна.

Опять что-то вроде ->

  for(Field f : resultSet.values())//Pseudo Code, obviously javax.sql is a bit more complex
    hashMap.put(f.getName(), f.getValue());
...
  return genericProcessing(hashMap, start, end);

Поскольку вы знаете ключи / методы (как определено вашими псевдонимами SQL), у вас есть простой обходной путь. Однако, если это общедоступный API, лучше использовать более "строгий" (интерфейс).

Если ваши данные не связаны, то я бы сказал, что ваш дизайн отражает данные. В этом нет ничего плохого.

(Второе мнение, фабричный шаблон, как предложено выше, является просто еще одной формой абстракции. Многие люди в экосистеме Java идут на это, и многие не любят это - я здесь во втором лагере). Вообще говоря, я бы сначала попытался абстрагировать вашу проблему, и если вы не можете абстрагироваться от нее, это, вероятно, достаточно просто. В вашем случае, я думаю, вы можете абстрагироваться с помощью метода / запроса. Если вы не можете перейти к типу (фабрики - способ сделать это), вероятно, ваш лучший ответ.

Если честно, я не прочитал ОП полностью и сразу перешел к вопросу. Извиняюсь...
Каждый раз, когда у вас есть такой код:

if (name.equalsIgnoreCase("Besvarelse")) {
        return besvarelse25(start, end);
    }else if (name.equalsIgnoreCase("intern")) {
        return intern(start, end);
    }else if (name.equalsIgnoreCase("besvarelseProcent")) {
        return besvarelseProcent(start,end);
    }else if (name.equalsIgnoreCase("Email_data")) {
        return email_data(start, end);
    }else if (name.equalsIgnoreCase("Email_Hånd")) {
        return email_haand(start, end);
    }else if (name.equalsIgnoreCase("Email_Antal")) {
        return email_antal(start, end);
    }  

рассмотрите возможность использования фабричного шаблона. Фабричный шаблон является стандартным способом для этого случая (читайте также на Абстрактной Фабрике)

Другие вопросы по тегам