은닉처
오늘 우리는 최대 절전 모드의 엔티티 상태 및 최대 절전 모드 캐시에 대해 이야기 할 것입니다.
1) 먼저 엔티티 상태를 살펴 보겠습니다.
엔티티 상태에는 세 가지 주요 유형이 있습니다 : 일시적, 영구 및 분리.
당신은 아마도 영어를 읽음으로써 그것을 이해할 것입니다.
과도 : 데이터베이스의 데이터에 아직 해당하지 않은 데이터를 나타냅니다.
Persistent : 데이터베이스의 데이터에 해당하는 데이터를 나타냅니다.이 변경 사항은 데이터베이스에 반영됩니다.
분리 된 : 데이터베이스의 데이터에 해당하는 데이터를 말하지만 세션이 닫히기 때문에 수정이 데이터베이스 레코드에 영향을 미치지 않습니다.
직접 코드를하자 :
트랜잭션 tx = session.begintransaction (); 사용자 user = 새 사용자 (); user.setName ( "shun"); // 여기의 사용자는 데이터베이스에 저장되지 않았으며 데이터베이스 테이블에 해당 레코드가 없습니다. 일시적 상태 세션입니다 .Save (사용자); tx.commit (); // 커밋 후, 사용자는 영구 상태 세션이됩니다 .Close (); // 세션이 닫히기 때문에 현재 사용자는 분리되며 모든 수정은 데이터베이스에 반영되지 않습니다. 세션 세션 2 = sessionfactory.opensession (); tx = session2.begintransaction (); user.setName ( "shun123"); session2.saveorupdate (사용자); tx.commit (); // SaveORUPDATE를 호출하면 사용자가 다시 지속되며 모든 수정은 데이터베이스에 반영됩니다. session2.close ();
우리는 코드를 봅니다. 먼저 객체 사용자를 정의합니다. 저장되기 전에 과도 상태이며 데이터베이스에는 해당 레코드가 없습니다. 수정을 저장하고 제출하면 사용자는 영구 상태가되고 데이터베이스에는 해당 레코드가 있습니다. 세션을 닫으면 사용자가 분리되며 해당 업데이트 및 SaveorupDate와 같은 추가 방법을 수동으로 호출하지 않으면 변경 사항이 데이터베이스에 반영되지 않습니다. 그리고 우리가 지속적으로 일시적 상태로 가기를 원할 때 우리는 무엇을해야합니까? 직접 삭제하십시오. 삭제 후, 객체는 데이터베이스에 해당 레코드가 없어서 일시적이됩니다.
최대 절전 모드의 상태 전환은 비교적 간단합니다. 일시적이면 데이터베이스에 대한 해당 레코드가 없지만 영구 및 분리 된에는 해당 레코드가 있습니다. 그러나 유일한 차이점은 분리 된 것이 세션이 닫힌 후에 만 존재하는 상태라는 것입니다. 그렇다면 과도와 분리의 차이점은 무엇입니까? 해당 데이터베이스 테이블 레코드가 있는지 여부에 대한 질문 일뿐입니다.
2) 상태를 읽은 후 최대 절전 모드 캐시를 살펴 보겠습니다.
최대 절전 모드를위한 캐시에는 두 가지 유형의 캐시가 있습니다 : 레벨 1 캐시와 레벨 2 캐시.
레벨 1 캐시 : 소위 레벨 1 캐시는 내부 캐시입니다.
레벨 2 캐시 : 최대 절전 모드에서 SessionFactory 캐시라고하는 응용 프로그램 수준 캐시가 포함되어 있고 다른 캐시는 가장 안전한 캐시 방법 인 분산 캐시입니다.
프로그램을 직접 살펴 보겠습니다.
public static void main (String [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = CFG.BuildSessionFactory (); 세션 세션 = sessionfactory.opensession (); 사용자 user = (user) session.load (user.class, new Long (29)); System.out.println (user.getName ()); user user2 = (user) session.load (user.class, new long (29)); System.out.println (user2.getName ()); session.close (); } 결과보기 :
Hibernate : user0_0_0_, user2_0_0_, user2_0_0_, user0_.age as user0_0_ as user0_0_ as user0_.user_id를 선택하십시오. SHUN123123 SHUN123123
이 예에서는로드를 두 번 사용했지만 결과에는 하나의 SQL 문 만 있었으며, 이는 한 번만 쿼리되었음을 나타냅니다.
왜? 이것이 최대 절전 모드 캐시가 작동하는 이유입니다. 첫 번째 쿼리가 완료되면 캐시에서 발견 된 엔티티의 최대 절전 모드. 다음에 확인하면 캐시를 확인하여 해당 ID가있는 엔티티가 있는지 확인합니다. 있으면 직접 꺼내면 데이터베이스 쿼리가 수행됩니다.
코드를 다음과 같이 수정합시다.
사용자 user = (user) session.load (user.class, new Long (29)); System.out.println (user.getName ()); session.evict (user); // 캐시에서 사용자 삭제 사용자 user2 = (user) session.load (user.class, new long (29)); System.out.println (user2.getName ()); session.close ();
결과보기 :
Hibernate : user0_0_0_, user2_0_0_, user2_0_0_, user0_.age as user0_0_ as user0_0_ as user0_.user_id를 선택하십시오. SHUN123123 HIBERNATE : user0_0_0_, user2_0_0_, user2_0_0_, user0_.age as user0_0_ as user0_0_ as user0_.user0_. SHUN123123
캐시에서 사용자를 삭제 한 후 두 번째 쿼리도 데이터베이스에서 직접 검색됩니다.
레벨 2 캐시 토크
먼저 엔티티 클래스를 살펴 보겠습니다.
공개 클래스 사용자는 직렬화 가능 {public long id; 개인 문자열 이름; 사적인 int 연령; } 매핑 파일은 생략되며 모든 사람이 작성해야합니다.
최대 절전 모드 구성 파일을 살펴 보겠습니다.
<property name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property> <property name = "hibernate.cache.use_second_level_cache"> true> <속성 이름 = "hibernate.cache.use_query_cache"> true </property>
우리는 Provider_Class에서 ehcache를 지정하므로 classPath에 배치하려면 ehcache.xml도 필요합니다.
<? xml version = "1.0"alcoding = "utf-8"?> <ehcache> <diskstore path = "java.io.path"/> <defaultCache maxelementsInmemory = "10000"Eternal = "False"TimetoidleSeconds = "120"TimetoLiveseconds = "120"Overflowtisk = "/>>"/> "/>"/> "
다음으로 테스트 방법을 살펴 보겠습니다.
public static void main (String [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = CFG.BuildSessionFactory (); 세션 세션 = sessionfactory.opensession (); query query = session.createquery ( "name = 'shun123'"); 반복자 iter = query.iterate (); while (iter.hasnext ()) {system.out.println ((((사용자) iter.next ()). getName ()); } session.close (); 세션 세션 2 = sessionfactory.opensession (); query query2 = session2.createquery ( "name = 'shun123'"); 반복자 iter2 = query2.iterate (); while (iter2.hasnext ()) {system.out.println ((((사용자) iter2.next ()). getName ()); } session2.close (); } 실행 후 다음을 볼 수 있습니다.
Hibernate : user0_.user_name = 'shun123'hibernate : user1_0_0_, user0_.user_name as user2_0_0_, user0_0_, user0_.age as user0_.age as user0_.age as user0_0_ as user0_0_? SHUN123 HIBERNATE : 사용자 0_.USER_ID를 사용하여 사용자 0_.USER_NAME = 'SHUN123'SHUN123에서 user0_.user_id를 선택하십시오.
우리는 그것이 검색 문장 하나만 수행한다는 것을 알 수 있으며, ID는 주로 보조 캐시 때문입니다.
먼저 테스트 방법의 코드를 분석하겠습니다. 테스트 방법에서는 두 세션을 열고 동일한 쿼리에 대해 별도로 두 개의 쿼리를 만듭니다. 그러나 두 세션은 두 번째 레벨 캐시 인 SessionFactory 레벨 캐시 인 캐시를 공유 할 수 있습니다. 세션이 동일한 SessionFactory에 의해 생성되는 한, 데이터베이스와의 상호 작용을 줄이기 위해 보조 캐시를 공유 할 수 있습니다.
구성 파일의 의미를 살펴 보겠습니다.
<property name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property> <property name = "hibernate.cache.use_second_level_cache"> true> <속성 이름 = "hibernate.cache.use_query_cache"> true </property>
보조 캐시를 사용해야하는 경우 먼저 구성해야합니다.
<property name = "hibernate.cache.use_second_level_cache"> true </property>
계정 개방의 두 번째 레벨 캐시를 수행 한 다음 다음을 통과하십시오.
<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 (); 세션 세션 = sessionfactory.opensession (); query query = session.createquery ( "name = 'shun123'"); 목록 List = Query.list (); for (int i = 0; i <list.size (); i ++) {system.out.println (((사용자) list.get (i)). getName ()); } session.close (); 세션 세션 2 = sessionfactory.opensession (); query query2 = session2.createquery ( "name = 'shun123'"); List2 = Query2.List (); for (int i = 0; i <list2.size (); i ++) {system.out.println (((사용자) list.get (i)). getName ()); } session2.close (); } 여기서 결과 출력은 다음과 같습니다.
Hibernate : user0_0_, user0_.user_name as user0_.user_name as user0_0_, user0_.age as user0_.user0_ as user0_.user_name = 'shun123'shun123 hibernate : user0_.user0 as user user0_.user0 as at user2_0_. user0_.user_name = 'shun123'shun123에서 Age0_
여기에 목록을 사용하기 때문에 캐시를 사용하지 않으며 목록 만 쓰기 만 캐시를 읽지 않습니다. 따라서 여기에는 두 가지 쿼리가 있습니다.
그런 다음 수정합시다 :
public static void main (String [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = CFG.BuildSessionFactory (); 세션 세션 = sessionfactory.opensession (); query query = session.createquery ( "name = 'shun123'"); <span style = "back for (int i = 0; i <list.size (); i ++) {system.out.println (((사용자) list.get (i)). getName ()); } session.close (); 세션 세션 2 = sessionfactory.opensession (); query query2 = session2.createquery ( "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_.use0_.age as user0_.user_name = 'shun123'shun123 shun123을 선택하십시오.
쿼리가 하나만 남았습니다. 왜? 이 두 개의 빨간색 코드에서 캐시를 켜고 두 번 사용해야합니다. 두 쿼리 캐시를 캐시 할 수 있도록 설정하십시오.
기준도 비슷한 접근법입니다. 기준을 작성하는 방법을 잊어 버리는 어린이 신발을 피하기 위해 코드를 넣을 것입니다.
public static void main (String [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = CFG.BuildSessionFactory (); 세션 세션 = sessionfactory.opensession (); 기준 기준 1 = session.createCriteria (user.class); criteria1.setCachable (true); 기준 1.add (제한 .eq ( "name", "shun123")); 목록 = criteria1.list (); for (int i = 0; i <list.size (); i ++) {system.out.println (((사용자) list.get (i)). getName ()); } session.close (); 세션 세션 2 = sessionfactory.opensession (); 기준 기준 2 = session2.createCriteria (user.class); Criteria2.SetCachable (true); criteria2.add (gestrictions.eq ( "name", "shun123")); list2 = criteria2.list (); for (int i = 0; i <list2.size (); i ++) {system.out.println (((사용자) list.get (i)). getName ()); } session2.close (); } 결과를 보자 :
Hibernate : user1_0_0_, user2 this_. SHUN123 SHUN123