Как создать карту многократного использования - PullRequest
1 голос
/ 17 февраля 2020

Есть ли способ заполнить карту один раз данными из БД (через понедельник go хранилище) и повторно использовать ее при необходимости из нескольких классов вместо того, чтобы обращаться к базе данных через хранилище.

Ответы [ 3 ]

0 голосов
/ 17 февраля 2020

Вы можете объявить поле карты как public static, и это позволило бы доступу всего приложения для нажатия через ClassLoadingData.mapField

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


class ClassLoadingData {

  private static Map<KeyType,ValueType> memoizedValues = new HashMap<>();


  public Map<KeyType,ValueType> getMyData() {

    if (memoizedData.isEmpty()) { // you can use more complex if to handle data refresh

     populateData(memoizedData);

    } else {
      return memoizedData;
    }

  }

  private void populateData() {

    // do your query, and assign result to memoizedData

  }

}



0 голосов
/ 17 февраля 2020

Предпосылка: Я предлагаю вам использовать инструмент объектно-реляционного отображения, такой как Hibernate , в вашем проекте java, чтобы отобразить объектно-ориентированную модель предметной области в реляционную базы данных, и пусть инструмент неявно обрабатывает механизм кэширования. Hibernate специально реализует многоуровневую схему кэширования (для получения дополнительной информации перейдите по следующей ссылке: https://www.tutorialspoint.com/hibernate/hibernate_caching.htm)

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

public class MongoDBConnector {

    private static final Logger LOGGER = LoggerFactory.getLogger(MongoDBConnector.class);

    private static MongoDBConnector instance;

    //Cache period in seconds
    public static int DB_ELEMENTS_CACHE_PERIOD = 30;

    //Latest cache update time
    private DateTime latestUpdateTime;

    //The cache data layer from DB
    private Map<KType,VType> elements;

    private MongoDBConnector() {
    }

    public static synchronized MongoDBConnector getInstance() {
        if (instance == null) {
            instance = new MongoDBConnector();
        }
        return instance;
    }

}

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

1 - эти методы должны быть синхронизированы во избежание проблем при выполнении нескольких вызовов.

2- метод загрузки должен применять период кэширования logi c (возможно с настраиваемым периодом) Чтобы избежать загрузки для каждого метода, вызовите данные из БД.

Пример: Предположим, ваш период кеширования составляет 30 с. Это означает, что если в течение 30 с выполняется 10 операций чтения из разных точек кода, вы будете загружать данные из БД только при первом вызове, в то время как другие будут читать из кэшированной карты, улучшая производительность.

Примечание: Чем больше период кеширования, тем выше производительность вашего кода , но , если БД управляется, вы создадите несогласованность с кешем, если вставка выполняется извне (из другого инструмента или вручную). Поэтому выберите наилучшее значение для вас.

public synchronized Map<KType, VType> getElements() throws ConnectorException {
   final DateTime currentTime = new DateTime();
   if (latestUpdateTime == null || (Seconds.secondsBetween(latestUpdateTime, currentTime).getSeconds() > DB_ELEMENTS_CACHE_PERIOD)) {
       LOGGER.debug("Cache is expired. Reading values from DB");
       //Read from DB and update cache
       //....

       sampleTime = currentTime;
   }
  return elements;
}

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

public synchronized void storeElement(final VType object) throws ConnectorException {
  //Insert object on DB ( throws a ConnectorException if insert fails )
  //...

  //Update cache regardless the cache period
  loadElementsIgnoreCachePeriod();
}

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

Map<KType,VType> liveElements = MongoDBConnector.getElements();
0 голосов
/ 17 февраля 2020

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

Возможно, в Интернете существуют различные учебные пособия , но обычно все кэши имеют следующее поведение: 1. Они являются структурами пары ключ-значение. 2. У каждого объекта, находящегося в кеше, также есть время жизни, то есть как долго он будет считаться действительным.

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

Таким образом, в основном, когда запрос поступает на ваш уровень хранилища, проверьте его в кеше. Если там есть, проверьте время жизни. Если он все еще действителен, верните его.

Если ключ не существует или срок действия истек, вы добавляете / перезаписываете данные в кеше. Имейте в виду, что при самостоятельном обновлении модели данных вы также соответственно отменяете кэш, так что новые / fre sh данные будут извлечены из БД при следующем вызове.

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