Struts2 статическое хранение / доступ к данным


Я пытаюсь найти, что такое обычный дизайн / подход для "статического / глобального"! доступ к данным / хранение в веб-приложении, я использую struts 2. Фон, у меня есть несколько таблиц, которые я хочу отобразить в своем веб-приложении.

Задача 1. Таблицы будут меняться и обновляться только один раз в день на сервере, я не хочу обращаться к базе данных или загружать файл для каждого запроса на просмотр таблицы. Я бы предпочел загружать таблицы в некоторую глобальную память/кэш один раз (в день), и каждый запрос получить таблицу из там, вместо того, чтобы обращаться к базе данных. Я полагаю, что это распространенный сценарий и есть устоявшийся подход? Но сейчас я не могу его найти. Для struts 2, является ли ActionContext правильным местом для этих данных. Если да, то любая ссылка на учебник будет действительно оценена.

Задача 2. Таблицы хранились в XML-файле, который я разомкнул с JAXB, чтобы получить объекты таблиц, и таким образом списки для таблиц. Для небольшого приложения это было нормально, но я думаю, что для веб-приложения, его hacky хранить xml как ресурсы и читать в файле как контекст сервлета и анализировать, или это? Я понимаю, что мне могут сказать хранить таблицы в базе данных, доступ к которой осуществляется с помощью dao, и использовать hibernate для получения объектов. Мне просто любопытно, каков обычный подход к данным, уже хранящимся в XML-файле? Учитывая, что я буду иметь новые XML-файлы ежедневно.

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

3 3

3 ответа:

Это вообще не относится к Struts2. Вы определенно не хотите пытаться хранить эту информацию в ActionContext - это объект для каждого запроса.

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

Не посмотрев на параметры кэширования, я бы сам извлек данные из БД, но только после того, как прошел интервал.

Обычно вы работаете в области действия, следующий уровень-это сессия, а самый глобальный-приложение. Простой способ проверить это-создать класс действий, который реализует ApplicationAware. Затем вы можете получить значения, помещенные туда из любого jsp / действия... везде, где вы можете добраться до ActionContext (который находится почти в любом месте) смотрите: http://struts.apache.org/2.0.14/docs/what-is-the-actioncontext.html

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

Этот метод увеличивает сложность, так как вы отвечаете за управление некоторыми структурами данных и их взаимодействие. с Ормом.

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

Как упоминалось ранее, наилучшим подходом было бы использование EHCache или другого доверенного менеджера кэша.

Другой подход заключается в использовании фабрики для доступа к информации. Например, что-то вроде:
public class MyCache {
  private static MyCache cache = new MyCache();

  public static MyCache getCache() {
    return cache;
  }

  (data members) 

  private MyCache() {
    (update data members)
  }

  public synchronized getXXX() {
    ...
  }

  public synchronized setXXX(SomeType data) {
    ...
  }
}

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

synchronized (MyCache.getCahce()) { 
  MyCahce.getCache().getXXX();
  MyCache.getCache().getTwo();
  ...
} 

Etc

Опять же, лучше использовать EHCache или что-то другое под ключ, так как это, вероятно, будет непостоянны без хорошего понимания механизмов. Этот тип кэша также имеет проблемы с производительностью, так как он позволяет только одному потоку читать/записывать в кэш одновременно. (Возможные способы ускорения-использовать локальные потоки и блокировки чтения / записи , но такие вещи уже встроены во многие установленные менеджеры кэша)