Исследование в этой статье в основном фокусируется на механизме гибернатного кэша, следующим образом.
Студент. Ява:
студент открытого класса {/*идентификатор студента*/private int id;/*Имя студента*/private String name;/*Отношения между учениками и классом*/Занятые классы классов; // Опустить сеттер и методы Getter}Classes.java:
Общедоступные классы классов {/*идентификатор класса*/private int id;/*Имя класса*/private String name;/*Отношения между классом и студентами*/private <tlpated> Студенты; // Опумивание методами и методами Getter}}Студент.hbm.xml:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.lixue.bean"> <class name="Student" TABLE = "T_STUDENT"> <ID NAME = "ID"> <Generator // ID> <!-MAP нормальные свойства-> <name = "name"/> <!-сопоставление много-одно-одному, добавьте внешний ключ в многократный конец-> <много-одно имя = "classest =" classid "/> </class> </hibernate-mapping>
Classes.hbm.xml:
<? xml version = "1.0"?> <! Doctype Hibernate Mapping Public "-// Hibernate/Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package = "com.lixue.bean"-ravecue. name="Classes" table="t_classes" lazy="false"> <id name="id"> <generator/generator/> </id> <property name="name"/> <!-- One-to-many mapping, inverse="true" means to hand over the relationship to the peer--> <set name="students" inverse="true"> <key column="classesid"/> <one-to-many/> </set> </class> </hibernate-mapping>
Период объявления кэша первого уровня очень короткий, а жизненный цикл сеанса согласован. Кэш первого уровня также называется кэшем на уровне сеанса или кэше на уровне. Кэш первого уровня является объектом кэша и не может кэшировать атрибуты.
Метод испытаний (используйте запрос load () дважды в одном сеансе):
/*После того, как он вынес его, он будет помещен в кеш, а во второй раз он будет извлекать его непосредственно из сессии кэша*/ студент = (студент). Загрузка (Student.class, 1); System.out.println ("Student.name =" + study.getName ()); /*Оператор запроса не выдан, загрузка использует кэш*/ student = (студент) Session.load (Student.class, 1); System.out.println ("Student.name =" + study.getName ());Примечание. Мы обнаружим, что когда мы впервые запросите, найденные результаты будут размещены в сеансе, кэше и кэше первого уровня. Когда я получаю значение во времени после загрузки () во второй раз, я не выпустил оператор, чтобы запросить его в базе данных, но непосредственно извлекал значение из кэша (оно должно быть в том же сеансе).
Метод испытания два (в том же сеансе):
Студент = новый студент (); Student.SetName ("Zhang San"); Serializable id = session.save (студент); Студент = (Студент) SESSION.LOAD (Student.Class, id); // Заявление запроса не будет выпущено, потому что сохранение поддерживает Cache System.out.println ("student.name =" + study.getName ());ПРИМЕЧАНИЕ. Метод сохранения () вызывается, и загрузка () используется для загрузки объекта, и затем атрибут имени фактически получен, но никаких операций не выдается для запроса базы данных. Потому что метод сохранения () также поддерживает кэш.
Проверьте добавление больших партий данных:
public void testCache7 () {Session Session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); for (int i = 0; i <100; i ++) {Студент Студент = новый студент (); Student.SetName ("Zhang San" + I); Session.save (студент); // обновлять каждые 20 элементов, если (i % 20 == 0) {// очистить кэш, и после вызова промывки данные будут сохранены в сеансе базы данных.flush (); // Очистить кэшированное содержимое сеанс.clear (); }} session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }} Примечание:
1. Поскольку метод сохранения () поддерживает кэш, есть проблема. Если я хочу сэкономить 10 миллионов данных одновременно, то в кэше есть 10 миллионов объектов кэша, что может вызвать переполнение. Следовательно, Hibernate не поддерживает работу обновления крупномасштабных данных, но мы также можем решить эту проблему очень гибко, например, очистка кэша каждые 20 частей данных с использованием цикла.
2. Сохранить, обновить, сохранить, загрузить, получить, список, итерация, методы блокировки будут помещать объекты в кэше первого уровня. Кэш первого уровня не может контролировать количество кэшей, поэтому вы должны обратить внимание на возможность переполнения памяти при использовании данных в больших партиях; Вы можете использовать метод выселения и очистки для очистки контента в кэше.
Вторичный кэш также называется кэшем на уровне процесса или кэше на уровне SessionFactory, а вторичный кэш может использоваться всеми кэшами сеансов. Жизненный цикл вторичного кэша такой же, как и у сеансафакторизации. SessionFactory может управлять вторичным кэшем. Принцип вторичного кэша используется, когда чтение намного больше, чем написание. Вторичный кэш в основном используется для кэширования объектов объекта.
1. Скопируйте файл ehcahe.xml в каталог SRC.
2. Добавьте поставщик продуктов кэша в файл hibernate.cfg.xml следующим образом:
<name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property>
3. Включить кэш уровня 2 (невозможно отобразить запуск, потому что по умолчанию включено), следующим образом:
<имя свойства = "hibernate.cache.use_second_level_cache"> true </property>
4. Укажите, какие классы объектов используют кэш уровня 2.
5. Импортируйте пакет JAR интерфейса, используемый кэшем: lib/optional/ehcache/ehcache-core-2.4.3.jar
Содержание файла ehcache.xml:
<defaultcache maxelementsinmemory = "10000" eternal = "false" dimeToidLeseconds = "120" timetoliveseconds = "120" OupFlowToDisk = "true" />
Примечание:
1.MaxElementsInMemory представляет наиболее хранимых объектов в кеше.
2. Вернал указывает, не истечет ли это (установление его на ложь более практично. Если это правда, это никогда не истекает, то следующие атрибуты бессмысленны).
3.timetoidlesecods указывает, как долго объект не был доступен после того, как он был очищен.
4. Timetolivesecods представляет время инвентаризации объекта.
5. Overflowtodisk верно, что означает, что число в кэше превышает число, указанное MaxelementsInmemory, и хранится на диске.
Укажите путь диска, сохраненный на переполнении:
<diskstore path = "java.io.tmpdir"/>
Примечание: этот путь может быть изменен.
Метод испытаний (предпосылка кэша уровня 1 заключается в том, что он должен быть в одном сеансе. Теперь мы используем кэш уровня 2, чтобы увидеть, есть ли кэш в двух разных сеансах):
public void testCache1 () {session session = null; try {session = hibernateutils.getsession (); session.begintransaction (); студент студента = (студент) session.load (student.class, 1); System.out.println ("student.name =" + student.getName ();); {e.printstacktrace (); session.getTransaction (). rolback ();} наконец {hibernateUtils.closesession (session);} try {session = hibernateutils.getsession (); session.begintransaction (); студент -студент = Session.load (студент. Поделитесь данными во вторичном кэше .///me вторичный кэш-это система кэша на уровне процесса. {Hibernateutils.closesession (session);}}ПРИМЕЧАНИЕ. Если настраивается вторичный кэш, мы обнаружим, что даже если первое сеанс будет закрыт, а другой сеанс будет включен для загрузки данных, он не выпустит оператор для запроса данных в базе данных, поскольку вторичный кэш настроен, он обменивается всем сеансом.
Отключить кеш 2 -го уровня для реализации добавления больших партий данных:
public void testCache5 () {Session Session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); // Кэш-линии и вторичный кэш взаимодействие являются запрещенными session.setCacheMode (cachemode.ignore); for (int i = 0; i <100; i ++) {Студент Студент = новый студент (); Student.SetName ("Zhang San" + I); Session.save (студент); // обновлять каждые 20 элементов, если (i % 20 == 0) {session.flush (); // Очистить кэшированное содержимое Session.clear (); }} session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Примечание: session.flush () означает очистку кэша первого уровня, но мы снова запустили кэш второго уровня, и после сохранения () он также сохраняет его в кэше второго уровня, но все еще существует переполнение, вызванное чрезмерным кешем. Таким образом, в этом случае мы должны отключить вторичный кэш: session.setcachemode (cachemode.ignore);
Кэш запроса: как кэш первого уровня, так и кэш кэша кеша второго уровня как объекта кэша, но иногда мы надеемся получить определенные атрибуты и не часто получаем доступ к базе данных, но получаем ее из кэша. В настоящее время мы можем использовать кэш запросов. Кроме того, наборы результатов кэша запросов для объектов объектов будут кэшировать идентификатор. Жизненный цикл кеша запросов изменен. Когда связанная таблица изменяется, цикл объявления кэша запросов заканчивается, что не имеет ничего общего с жизненным циклом сеанса.
1. Измените файл hibernate.cfg.xml, чтобы включить кэш запроса. Если false по умолчанию, он не включен. Это должно быть установлено следующим образом:
<имя свойства = "hibernate.cache.use_query_cache"> true </property>
2. Должен быть включен в программе, например:
Query.SetCachable (True)
Метод испытаний:
public void testCache2 () {session session = null; try {session = hibernateUtils.getSession (); session.beginTransaction (); списки имена = session.createquery («select s.name from supdent s") .setcachable (true) .list (); для (int i = 0; i <name.size (); i ++). (String) names.get (i); System.out.println (name);} session.getTransaction (). Commit ();} catch (Exception e) {e.printStackTrace (); session.getTransaction (). Rollack ();} наконец -то {HibernateUtils.closeSession(session);}System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .list (); for (int i = 0; i <names.size (); i ++) {string name = (string) names.get (i); System.out.println (name);} session.getTransaction (). Commit ();} catch (Exception E) {e.printStacktrace (); session.getTransaction (). {Hibernateutils.closesession (session);}}Примечание. В приведенном выше коде мы отключаем вторичный кэш, включаем кэш запросов, а затем запрашиваем нормальные свойства. Запустите тестовый код, и мы можем обнаружить, что в первом сеансе первый запрос выдает заявление, затем закрывает сеанс, а затем запрос во втором сеансе. Мы обнаружим, что запрос во второй сессии не выдает заявление, что означает, что кэш запроса не имеет ничего общего с жизненным циклом сеанса.
Конфигурация кэша hibernate.cfg.xml:
<!-Установите интерфейс реализации для указания вторичного кэша-> <name = "hibernate.cache.region.factory_class"> org.hibernate.cache.ehcacheregionfactory </properation> <!-Установите файл конфигурации, используемый для вторичного Cache-> name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property> <!-- Set the cache using QUERY--> <property name="hibernate.cache.use_query_cache">true</property> <!-- Load the object relationship mapping file --> <mapping resource="com/lixue/bean/Classes.hbm.xml" /> <mapping resource = "com/lixue/bean/study.hbm.xml"/> <!-Файл отображения ресурсов (то есть файл сопоставления объектов) должен быть введен перед настройкой класса объектов с использованием кэша уровня 2-> <class-cache usage = "intyly"/>>>
Выше приведено все содержание этой статьи об анализе кода примера механизма склонного кеша, я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!