Как сделать выбор таблицы базы данных статическим без использования строк
Прежде всего, этот вопрос будет довольно длинным, но чтобы полностью объяснить мою проблему, я чувствую, что должен дать вам много информации о моем проекте, поэтому, пожалуйста, потерпите меня!
Я работаю в компании, которая часто использует диаграммы, поэтому, чтобы избежать проблем, всегда приходится создавать диаграммы из 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);
}
рассмотрите возможность использования фабричного шаблона. Фабричный шаблон является стандартным способом для этого случая (читайте также на Абстрактной Фабрике)