кеш
Сегодня мы поговорим о государстве сущности и кеше спящего склонность в Hibernate.
1) Во -первых, давайте посмотрим на статус сущности:
Существует три основных типа государств объектов: переходные, постоянные и отстраненные.
Вы, вероятно, понимаете это, читая английский.
Переход: относится к данным, которые еще не соответствуют данным в базе данных.
Постоянный: относится к данным, соответствующим данным в базе данных, и любые изменения в нем будут отражены в базе данных.
Отлично: относится к данным, соответствующим данным в базе данных, но поскольку сеанс закрыт, вносящие его изменения не будут влиять на записи базы данных.
Давайте напрямую код:
Транзакция tx = session.beginTransaction (); Пользователь пользователь = новый пользователь (); user.setname ("Shun"); // пользователь здесь не был сохранен в базе данных, и в таблице баз данных нет соответствующей записи. Это временное состояние. Session.save (пользователь); tx.commit (); // после совершения коммита пользователь становится постоянным государственным сеансом.close (); // Поскольку сеанс закрыт, пользователь отстранен в настоящее время, и все его модификации не будут отражены в базе данных. Session2 = sessionFactory.Opensession (); tx = session2.beginTransaction (); user.setname ("shun123"); session2.saveorupdate (пользователь); tx.commit (); // Когда мы называем SaveTorUpdate, пользователь снова становится настойчивым, и все его модификации будут отражены в базе данных. session2.close (); Мы видим код. Сначала мы определяем пользователя объекта. Перед тем, как он будет сохранен, это переходное состояние, и в базе данных нет соответствующей записи. Когда мы сохраняем и отправляем модификацию, пользователь становится постоянным состоянием, и в базе данных есть соответствующая запись. Когда мы закрываем сеанс, пользователь становится отделенным, и его изменения не будут отражены в базе данных, если мы вручную не вызовут соответствующие методы обновления и добавления, такие как SaveTorUpdate. И что мы должны делать, когда хотим, чтобы он перешел от настойчивого к временному состоянию? Просто удалите его напрямую. После удаления объект не будет иметь соответствующей записи в базе данных, которая станет переходной.
Государственный переход Hibernate относительно прост. Когда он переходен, нет соответствующей записи для базы данных, в то время как постоянные и отделенные имеют соответствующие записи. Тем не менее, единственное отличие состоит в том, что отстраненным является состояние, которое существует только после закрытия сессии. Так в чем же разница между временными и отделенными? Это просто вопрос о том, есть ли соответствующая запись таблицы баз данных.
2) После прочтения статуса давайте посмотрим на кеш Hibernate
Существует два типа кэша для Hibernate: кэш 1 и кэш уровня 2.
Кэш 1-го уровня: так называемый кэш уровня 1-это внутренний кэш.
Кэш уровня 2: он включает в себя кэш на уровне приложения, который называется SessionFactory Cache в Hibernate, а другой-распределенный кэш, который является самым безопасным методом кэша.
Давайте напрямую посмотрим на программу:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.BuildSessionFactory (); Session Session = sessionFactory.Opensession (); Пользователь пользователь = (пользователь) session.load (user.class, new Long (29)); System.out.println (user.getName ()); Пользователь user2 = (пользователь) session.load (user.class, new long (29)); System.out.println (user2.getName ()); session.close (); } Смотрите результаты:
Hibernate: выберите user0_.user_id as user1_0_0_, user0_.user_name as user2_0_0_, user0_.age as age0_0_ от пользователя user0_, где user0_.user_id =? Shun123123 Shun123123
В примере мы использовали нагрузку дважды, но в результате был только один оператор SQL, который указал, что он был запросил только один раз.
Почему? Вот почему работает кэш с гибернат. После того, как первый запрос будет завершен, спяньте найденную сущность в кэше. В следующий раз, когда вы проверяете, кэш будет проверен, чтобы увидеть, есть ли какой -либо объект с соответствующим идентификатором. Если есть, он будет выведен напрямую, в противном случае будет проведен запрос базы данных.
Давайте изменим код на:
Пользователь пользователь = (пользователь) session.load (user.class, new Long (29)); System.out.println (user.getName ()); session.evict (user); // удалить пользователя из Cache user2 = (пользователь) session.load (user.class, new long (29)); System.out.println (user2.getName ()); session.close ();
Смотрите результаты:
Hibernate: выберите user0_.user_id as user1_0_0_, user0_.user_name as user2_0_0_, user0_.age as age0_0_ от пользователя user0_, где user0_.user_id =? Shun123123 Hibernate: выберите user0_.user_id as user1_0_0_, user0_.user_name as user2_0_0_, user0_.age as age0_0_ от пользователя user0_ user0_.user_id =? Shun123123
После того, как мы удалим пользователя из кэша, второй запрос также непосредственно извлечен из базы данных.
Кэш -разговор уровня 2
Сначала посмотрим на класс сущности:
Пользователь открытого класса реализует сериализуемый {public long Id; Приватное название строки; частный int возраст; } Файл отображения опущен, каждый должен написать его.
Давайте посмотрим на файл конфигурации Hibernate:
<name = name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property> <property name = "hibernate.cache.use_second_level_cache"> true </propetion> <name = "hibernate.cache.use_cache"> true </proportment> property name = "hibernate.cache.use_cache"
Мы видим, что в провайдере_CLASS мы указываем eHcache, поэтому нам также нужно, чтобы ehcache.xml был размещен в панели класса:
<? xml version = "1.0" Encoding = "utf-8"?> <ehcache> <diskstore path = "java.io.path"/> <defaultcache maxelementsinmemory = "10000" Eternal = "false" dimeTodleseconds = "120" timeToLiveseconds = "120" upplowTodeConds = "120" timeToLiveseconds = "120".
Далее, давайте посмотрим на метод испытания:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.BuildSessionFactory (); Session Session = sessionFactory.Opensession (); Query Query = session.createQuery ("От пользователя пользователя, где name = 'shun123'"); Итератор iter = Query.iterate (); while (iter.hasnext ()) {System.out.println (((пользователь) iter.next ()). getName ()); } session.close (); Session2 = sessionFactory.Opensession (); Query Query2 = session2.createequery ("От пользователя пользователя, где name = 'shun123'"); Итератор iter2 = Query2.iterate (); while (iter2.hasnext ()) {System.out.println (((пользователь) iter2.next ()). getName ()); } session2.close (); } После бега вы можете увидеть:
Hibernate: выберите user0_.user_id как col_0_0_ из пользователя user0_, где user0_.user_name = 'shun123' hibernate: select user0_.user_id as user1_0_0_, user0_.user_name as user2_0_0_0_0_0_.age as aeg_0_0_.ser_name as user2_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 г. Shun123 Hibernate: выберите user0_.user_id AS COL_0_0_ из пользователя user0_, где user0_.user_name = 'shun123' shun123
Мы видим, что он выполняет только одно предложение поиска, и идентификатор не получен для поиска по второму запросу, который в основном связан со вторичным кэшем.
Давайте сначала проанализируем код в методе испытания. В методе испытаний мы открываем два сеанса и создаем два запроса отдельно для одного и того же запроса. Тем не менее, две сессии могут разделить кэш, который является кэшем второго уровня, кэш уровня SessionFactory. Пока наш сеанс создается одним и тем же сеансом, мы можем поделиться вторичным кэшем, чтобы уменьшить взаимодействие с базой данных.
Давайте посмотрим на значение в файле конфигурации:
<name = name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property> <property name = "hibernate.cache.use_second_level_cache"> true </propetion> <name = "hibernate.cache.use_cache"> true </proportment> property name = "hibernate.cache.use_cache"
Если нам нужно использовать вторичный кэш, нам нужно сначала настроить его:
<имя свойства = "hibernate.cache.use_second_level_cache"> true </property>
Выполните кеш открытия учетной записи второго уровня, а затем пройдите:
<name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property>
Укажите класс предоставления для вторичного кэша. Как правило, мы используем ehcache. Другие мои не используются в настоящее время и не очень ясны, поэтому я не буду говорить о них на данный момент.
Как и наш пример прямо сейчас, нам нужно только настроить вышеупомянутые два, которые могут полностью работать нормально и использовать вторичный кэш.
Итак, для чего стоит третье предложение?
<имя свойства = "hibernate.cache.use_query_cache"> true </property>
Эта конфигурация указывает, что нам нужно использовать кэш при запросе. Если нам нужно использовать это, мы должны заранее позвонить Query.SetCachable (true), чтобы включить его.
Давайте посмотрим на код вместе (мы пока не включим в кеш):
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.BuildSessionFactory (); Session Session = sessionFactory.Opensession (); Query Query = session.createQuery ("От пользователя пользователя, где name = 'shun123'"); Список списка = Query.list (); for (int i = 0; i <list.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session.close (); Session2 = sessionFactory.Opensession (); Query Query2 = session2.createequery ("От пользователя пользователя, где name = 'shun123'"); Список списка2 = Query2.list (); for (int i = 0; i <list2.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session2.close (); } Результат вывода здесь:
Hibernate: выберите user0_.user_id as user1_0_, user0_.user_name as user2_0_, user0_.age as age0_ из пользователя user0_ где user0_.user_name = 'shun123' shun123 hibernate: select user0_.user_id as aser1_0_0_. AGE0_ от пользователя user0_, где user0_.user_name = 'Shun123' Shun123
Мы видим, что он не использует кэш, потому что мы используем список здесь, и только списки записываются и не читают кэш. Так что здесь будет два запроса.
Тогда давайте изменим это:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.BuildSessionFactory (); Session Session = sessionFactory.Opensession (); Query Query = session.createQuery ("От пользователя пользователя, где name = 'shun123'"); <span style = "foangy-color: #ffffff;"> <span style = "color: #ff0000;"> Query.setCachable (true); </span> </span> list list = Query.list (); for (int i = 0; i <list.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session.close (); Session2 = sessionFactory.Opensession (); Query Query2 = session2.createequery ("От пользователя пользователя, где name = 'shun123'"); <span style = "color: #ff0000;"> Query2.setCachable (true); </span> list2 = Query2.list (); for (int i = 0; i <list2.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session2.close (); } Я видел два красных предложения кода. Это два кода, которые мы добавили, чтобы включить кэш запросов. Теперь мы видим результат:
Hibernate: выберите user0_.user_id as user1_0_, user0_.user_name as user2_0_, user0_.age as age0_ от пользователя user0_, где user0_.user_name = 'shun123' shun123 shun123
Остался только один запрос, почему? Как раз в этих двух красных кодах мы включили кэш, помните, что его нужно использовать дважды. Установите оба кэша запроса для кэширования.
Критерии также являются аналогичным подходом. Чтобы избежать детской обуви, забывая, как написать критерии, я помесчу код:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.BuildSessionFactory (); Session Session = sessionFactory.Opensession (); Критерии критериев1 = session.createcritia (user.class); критерии1.setCachable (True); Criteria1.add (RELICTIONS.EQ ("Имя", "Shun123")); Список списка = критерии1.list (); for (int i = 0; i <list.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session.close (); Session2 = sessionFactory.Opensession (); Критерии критериев 2 = session2.createcriteria (user.class); критерии2.setCachable (True); Criteria2.Add (RELYCTIONS.EQ ("Имя", "Shun123")); Список списка2 = критерии2.list (); for (int i = 0; i <list2.size (); i ++) {System.out.println ((((пользователь) list.get (i)). getName ()); } session2.close (); } Посмотрим результаты:
Hibernate: выберите это_.user_id as user1_0_0_, this_.user_name как user2_0_0_, это_.age as age0_0_ от пользователя This_, где это_.user_name =? Shun123 Shun123