Вопрос о подходах к проектированию БД на Java

#java #database #jakarta-ee

#java #База данных #джакарта-ee

Вопрос:

У меня есть данные в БД, которые имеют иерархические отношения (могут быть представлены в виде дерева).
Прямо сейчас, всякий раз, когда на сервер поступает запрос, в БД выполняется рекурсивный запрос для создания списка в памяти (который представляет собой реально существующую ветвь дерева от листа до корня) и выполнения обработки с использованием этого списка.
Это не очень эффективно, но, по крайней мере, пока это работает, и имеет то преимущество, что при изменении БД изменения сразу же становятся заметными.
В любом случае, я хочу улучшить это и ищу шаблон, чтобы:
1) Не иметь постоянного доступа к БД
2) Если в БД внесено изменение, оно немедленно отражается
3) Его можно использовать во всех местах сервера.
Существует ли стандартный шаблон проектирования, обычно используемый для подобных случаев? Или просто иметь структуру данных, поддерживаемую внутренним потоком, и при любом обновлении в БД перезагружать все в структуре данных?

Спасибо

Комментарии:

1. Извините, я не понимаю сути. Запрашиваете ли вы представление иерархии, подходящее для обработки (не создаете структуру в памяти каждый раз)?

2. Проект является старым проектом, который использует пользовательскую платформу для доступа к БД (он старше, чем Hibernate, и он не был переработан для использования более новой платформы). Итак, я ищу пользовательское решение для кэширования фактических данных в памяти и обновления их при необходимости.

3. Я полностью согласен с @iruediger. Похоже, вам нужно кэширование, которое обновляется при вставке / обновлении / удалении в базе данных.

Ответ №1:

Вместо потока вы могли бы использовать решение для кэширования. Результат запроса будет кэшироваться и возвращаться при каждом запросе, если какая-либо из таблиц в запросе будет изменена, вы аннулируете кэш, дождитесь следующего запроса, чтобы получить новые значения и загрузить их в кэш. Это решение соответствует реквизитам 1 и 2. Что вы подразумеваете под «Оно может использоваться во всех местах сервера»?

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

Если вы не используете Hibernate, вы можете внедрить свое собственное решение с Ehcache. Вам нужно будет изменить метод, который возвращает структуру для проверки кэша перед запросом к БД. Методы, которые вносят изменения в соответствующие таблицы, должны быть изменены, чтобы сделать кэш недействительным.

Ehcache также имеет интеграцию с Spring, но я никогда ее не пробовал.

Комментарии:

1. ИМХО, у Spring нет решения для кэширования. Но у них есть интерфейс с EHCache, и я слышал, что это хорошо.

2. @Rudy Вы правы, это не решение для кэширования. Я исправил свой пост.

Ответ №2:

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

 <hibernate-mapping>
   <class name="YourTreeClass" table="tree_table" dynamic-insert="true" dynamic-update="true">
   ...other properties...

      <list name="children" cascade="save-update" inverse="false" >
         <cache usage="nonstrict-read-write"/>
         <key column="parent_id"/>
         <one-to-many class="YourTreeClass" />
      </list>
    </class>
</hibernate-mapping>
  

Нет необходимости в хакерских фоновых потоках — при обновлении узла Hibernate выполняет проверку и аннулирует соответствующие кэшированные записи.

Комментарии:

1. Проект является старым проектом, который использует пользовательскую платформу для доступа к БД (он старше, чем Hibernate, и он не был переработан для использования более новой платформы). Итак, я ищу пользовательское решение

2. Ого! Вы должны были сказать это в самом начале.