Как загрузить данные из базы данных во время загрузки класса с помощью JVM и сохранить ее в списке или карте для дальнейшего использования?

82
13

Я использую приложение весны и спящего режима. В моем требовании мне приходится загружать данные из базы данных во время развертывания проекта и хранить данные в Map или List для дальнейшего использования в целом приложении. У меня много googled, но не найдено никакого решения.

спросил(а) 2014-08-13T09:50:00+04:00 5 лет, 7 месяцев назад
1
Решение
81

Вы можете использовать

<prop key="hibernate.cache.use_query_cache">true</prop>

В hibernate configuration.xml для кэширования данных, которые вы получаете из базы данных и хранения в объекте... теперь, если вы используете один и тот же объект в любом месте приложения, он будет использовать один и тот же кеш и снова не ударит по базе данных.

Другой способ

вы можете настроить кеш с помощью xml файла, см. справочное руководство по весне:

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/cache.html#cache-declarative-xml

<!-- the service we want to make cacheable -->
<bean id="service" class="x.y.service.MyService"/>

<!-- cache definitions -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
<cache:caching cache="books">
<cache:cacheable method="getData" key="#id"/>
<cache:cache-evict method="loadData" all-entries="true"/>
</cache:caching>
</cache:advice>

<!-- apply the cacheable behaviour to all dataService interfaces -->
<aop:config>
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.myService.*(..))"/>
</aop:config>

ответил(а) 2014-08-13T10:27:00+04:00 5 лет, 7 месяцев назад
36

Если вам нужно загрузить коллекцию во время загрузки класса, вы можете использовать стратегию быстрой загрузки или поиска в Hibernate. В соответствии с интенсивной загрузкой, когда вы делаете любую коллекцию с нетерпением загруженной, давайте suppose-->

Если Foo имеет коллекцию, и вы настроили ее на ленивость, тогда только тогда, когда вам нужно содержимое для этой коллекции, выбрано, загружено и т.д., Тогда как если она будет интересной, она загрузит бары в момент загрузки Foo. Это может быть проблематичным, если вы с нетерпением загружаете коллекцию объектов, которые с нетерпением загружают коллекцию объектов и т.д. Но я полагаю, что в вашем случае будет работать стратегия Fetch Type = eager, и она будет загружаться во время загрузки класса.


Пример: @OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn (name = "countryId") private Set states;

ответил(а) 2014-08-13T12:49:00+04:00 5 лет, 7 месяцев назад
37

Прежде всего, вы не можете использовать какой-либо список или карту в качестве замены кэша. Вы можете использовать Hibernate Second Level Cache или даже внешнее кэширование, если ваши данные не будут изменены, что может вызвать проблемы с согласованностью.

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

ответил(а) 2014-08-13T12:08:00+04:00 5 лет, 7 месяцев назад
36

Better approach is to use Hibernate, In hibernate we have First Level cache.
First-level cache always Associates with the Session object. Hibernate uses this cache by default. Here, it processes one transaction after another one, means wont process one transaction many times. Mainly it reduces the number of SQL queries it needs to generate within a given transaction. That is instead of updating after every modification done in the transaction, it updates the transaction only at the end of the transaction.

First level cache retrieval example

In this example, I am retrieving DepartmentEntity object from database using hibernate session. I will retrieve it multiple times, and will observe the sql logs to see the differences.

//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());

//fetch the department entity again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());

session.getTransaction().commit();
HibernateUtil.shutdown();

Output:

Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
As you can see that second "session.load()" statement does not execute select query again and load the department entity directly.

ответил(а) 2014-08-13T11:23:00+04:00 5 лет, 7 месяцев назад
36

попробуйте использовать ServletContainerInitializer

https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/API_Documentation/files/javadoc/javax/servlet/ServletContainerInitializer.html

Если этот ServletContainerInitializer поставляется в JAR файле внутри каталога WEB-INF/lib приложения, его метод onStartup будет вызываться только один раз во время запуска приложения для объединения.

ответил(а) 2014-08-13T09:59:00+04:00 5 лет, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема