자바 프레임 워 크-hibenate 캐 시 메커니즘

22895 단어 Hibernate
1.why(왜 Hibernate 캐 시 를 사용 합 니까?)
Hibernate 는 물리 데이터 베 이 스 를 자주 방문 하 는 영구적 인 프레임 워 크 입 니 다.
응용 프로그램 이 물리 데이터 원본 에 접근 하 는 빈 도 를 낮 추고 응용 프로그램의 운행 성능 을 향상 시 키 기 위해 서다.
캐 시 에 있 는 데 이 터 는 물리 데이터 원본 의 데 이 터 를 복사 하 는 것 입 니 다.프로그램 이 실 행 될 때 캐 시 에서 데 이 터 를 읽 고 쓰 며 특정한 시간 이나 이벤트 에서 캐 시 와 물리 데이터 원본 의 데 이 터 를 동기 화 합 니 다.
 
2.what(Hibernate 캐 시 원 리 는 어 떻 습 니까?)Hibernate 캐 시 는 두 가지 유형 을 포함 합 니 다.Hibernate 1 급 캐 시 와 Hibernate 2 급 캐 시 입 니 다.
1.Hibernate 1 급 캐 시 는'Session 의 캐 시'라 고도 부른다.
Session 내 장 된 캐 시 는 마 운 트 해제 할 수 없습니다.Session 의 캐 시 는 트 랜 잭 션 범위 의 캐 시 입 니 다.(Session 대상 의 생명 주 기 는 보통 데이터베이스 트 랜 잭 션 이나 응용 트 랜 잭 션 에 대응 합 니 다)
1 급 캐 시 에서 지구 화 클래스 의 모든 인 스 턴 스 는 유일한 OID 를 가지 고 있 습 니 다.
2.Hibernate 2 급 캐 시 는'Session Factory 의 캐 시'라 고도 부른다.
Session Factory 대상 의 수명 주기 와 프로그램의 전체 과정 이 대응 하기 때문에 Hibernate 2 급 캐 시 는 프로 세 스 범위 나 클 러 스 터 범위 의 캐 시 로 병발 문제 가 발생 할 수 있 으 므 로 캐 시 된 데이터 에 트 랜 잭 션 격 리 단 계 를 제공 하 는 적절 한 병발 접근 정책 을 사용 해 야 합 니 다.
두 번 째 캐 시 는 선택 할 수 있 습 니 다.설정 가능 한 플러그 인 입 니 다.기본적으로 Session Factory 에 서 는 이 플러그 인 을 사용 하지 않 습 니 다.
Hibernate 는 org.hibernate.cache.cache Provider 인 터 페 이 스 를 제공 합 니 다.캐 시 플러그 인과 Hibernate 사이 의 어댑터 역할 을 합 니 다.
어떤 데이터 가 2 급 캐 시 에 저장 하기에 적합 합 니까?1)수정 되 지 않 은 데이터 2)중요 한 데이터 가 아 닙 니 다.가끔 동시 다발 되 는 데이터 가 나타 날 수 있 습 니 다.3)동시 다발 되 지 않 는 데이터 4)상수 데 이 터 는 2 급 캐 시 에 저장 하기에 적합 하지 않 습 니까?1)자주 수정 되 는 데이터 2)재무 데이터 와 같은 동시 방문 데이터 가 나타 나 는 것 을 절대 허용 하지 않 는 다.
 
3.Session 의 지연 로 딩 실현 은 두 가지 문 제 를 해결 해 야 합 니 다.연결 을 정상적으로 닫 고 요청 에 접근 하 는 것 이 같은 session 인지 확인 해 야 합 니 다.
Hibernate session 은 java.sql.connection 의 고급 패키지 입 니 다.하나의 session 은 하나의 Connection 에 대응 합 니 다.
http 요청 이 끝 난 후 정확 한 session 닫 기(필터 가 session 의 정상 적 인 닫 기 를 실현 함);로 딩 지연 은 같은 session(session 이 ThreadLocal 에 연결 되 어 있 음)이 어야 합 니 다.
 
4.Hibernate 검색 대상 은 캐 시 를 어떻게 사용 합 니까?Hibernate 가 ID 에 따라 데이터 대상 에 접근 할 때 먼저 Session 1 급 캐 시 에서 찾 습 니 다.
찾 을 수 없습니다.2 급 캐 시 를 설정 하면 2 급 캐 시 에서 찾 습 니 다.
찾 을 수 없 으 면 데이터 베 이 스 를 조회 하고 결 과 를 ID 에 따라 캐 시 에 넣 어 데 이 터 를 삭제,업데이트,추가 할 때 캐 시 를 업데이트 합 니 다.
 
5.1 급 캐 시 와 2 급 캐 시의 대비 도.
 
1 급 캐 시
2 급 캐 시
데이터 저장 형식
상호 관련 된 지구 화 대상
대상 의 벌 크 데이터
캐 시 범위
트 랜 잭 션 범위,모든 트 랜 잭 션 은 단독 1 급 캐 시 를 가지 고 있 습 니 다.
프로 세 스 범위 나 클 러 스 터 범위,캐 시 는 같은 프로 세 스 나 클 러 스 터 범위 내 모든 트 랜 잭 션 에 공 유 됩 니 다.
동시 접근 정책
모든 사무 가 단독 1 급 캐 시 를 가지 고 있 기 때문에 동시 접근 정책 을 제공 할 필요 가 없습니다.
여러 개의 트 랜 잭 션 이 2 급 캐 시 에 있 는 같은 데 이 터 를 동시에 방문 하기 때문에 특정한 트 랜 잭 션 격 리 단 계 를 확보 하기 위해 적당 한 병행 접근 전략 을 제공 해 야 합 니 다.
데이터 만 료 정책
프로그램 이 특정 대상 을 비우 거나 비우 지 않 는 한 1 급 캐 시 에 있 는 대상 은 만 료 되 지 않 습 니 다.
메모리 기반 캐 시 대상 의 최대 수,캐 시 에 있 는 대상 의 최 장 시간,캐 시 에 있 는 대상 의 최 장 시간 등 데이터 만 료 정책 을 제공 해 야 합 니 다.
물리 매체
메모리
메모리 와 하 드 디스크,대상 의 벌 크 데 이 터 는 메모리 기반 캐 시 에 먼저 저장 되 며,메모리 의 대상 수가 데이터 만 료 정책 의 max Element sInMemory 값 에 도달 하면 나머지 대상 을 하 드 디스크 기반 캐 시 에 기록 합 니 다.
캐 시 소프트웨어 구현
Hibernate 의 Session 구현 에 포함 되 어 있 습 니 다.
제3자 가 제공 하 는 Hibernate 는 캐 시 어댑터 만 제공 하여 특정한 캐 시 플러그 인 을 Hibernate 에 통합 하 는 데 사용 합 니 다.
캐 시 사용 방법
세 션 인 터 페 이 스 를 통 해 저장,업데이트,삭제,불 러 오기,조회 만 실행 하면 Hibernate 는 1 급 캐 시 를 사용 합 니 다.1 급 캐 시 를 사용 하지 않 으 려 면 JDCAPI 를 통 해 직접 실행 합 니 다.
사용 자 는 하나의 클래스 나 클래스 의 단일 집합 입도 에 2 급 캐 시 를 설정 할 수 있 습 니 다.클래스 의 인 스 턴 스 가 자주 읽 히 지만 수정 되 지 않 으 면 2 급 캐 시 를 사용 하 는 것 을 고려 할 수 있 습 니 다.특정한 클래스 나 집합 에 2 급 캐 시 를 설정 해 야 Hibernate 가 실 행 될 때 만 인 스 턴 스 를 2 급 캐 시 에 추가 할 수 있 습 니 다.
사용자 캐 시 관리 방식
1 급 캐 시 물리 미디어 는 메모리 입 니 다.메모리 의 용량 이 제한 되 어 있 기 때문에 적절 한 검색 정책 과 검색 방식 으로 로드 대상 의 수 를 제한 해 야 합 니 다.Session 의 evit()방법 으로 표시 할 수 있 는 캐 시 에서 특정 대상 을 비우 지만 추천 하지 않 습 니 다.
2 급 캐 시 물리 미디어 는 메모리 와 하 드 디스크 를 사용 할 수 있 습 니 다.따라서 2 급 캐 시 는 대 용량 의 데 이 터 를 저장 할 수 있 습 니 다.데이터 만 료 정책 의 maxElement sInMemory 속성 은 메모리 의 대상 수 를 제어 할 수 있 습 니 다.2 급 캐 시 를 관리 하 는 것 은 주로 두 가지 측면 을 포함 합 니 다.2 급 캐 시 를 사용 해 야 하 는 지구 화 류 를 선택 하고 적당 한 병행 접근 전략 을 설정 합 니 다.캐 시 어댑터 를 선택 하고 데이터 만 료 정책 을 설정 하 십시오.Session Factory 의 evit()방법 도 표시 할 수 있 는 캐 시 에서 특정 대상 을 비 울 수 있 지만 추천 하지 않 습 니 다.
 
3.how(Hibernate 의 캐 시 메커니즘 은 어떻게 응용 합 니까?)
1.  1 급 캐 시 관리:
evit(Object obj)  지정 한 지구 화 대상 을 1 급 캐 시 에서 제거 하고 대상 이 사용 하 는 메모리 자원 을 방출 하 며 지정 한 대상 을 지구 화 상태 에서 탈 관 상태 로 바 꾸 어 유리 대상 이 됩 니 다.
clear()  1 급 캐 시 에 있 는 모든 영구적 인 대상 을 삭제 하고 사용 하 는 메모리 자원 을 방출 합 니 다.
contains(Object obj) 지정 한 대상 이 1 급 캐 시 에 존재 하 는 지 판단 합 니 다.
flush() 데이터베이스 데이터 와 동기 화 할 수 있 도록 1 급 캐 시 구역 의 내용 을 새로 고 칩 니 다.
 
2.1 급 캐 시 적용:save().session 대상 이 save()방법 으로 대상 을 저장 하면 이 대상 은 session 캐 시 에 넣 습 니 다.get()과 load().session 대상 이 get()또는 load()방법 으로 데이터베이스 에서 대상 을 꺼 내 면 이 대상 도 session 캐 시 에 넣 습 니 다.데이터베이스 에서 HQL 과 QBC 등 을 이용 해 데 이 터 를 조회 합 니 다.
public class Client
{
    public static void main(String[] args)
    {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try
        {
            /*      */
            tx = session.beginTransaction();
            /*       id="402881e534fa5a440134fa5a45340002" Customer  */
            Customer customer1 = (Customer)session.get(Customer.class, "402881e534fa5a440134fa5a45340002");
            System.out.println("customer.getUsername is"+customer1.getUsername());
            /*    */
            tx.commit();
            
            System.out.println("-------------------------------------");
            
            /*       */
            tx = session.beginTransaction();
            /*       id="402881e534fa5a440134fa5a45340002" Customer  */
            Customer customer2 = (Customer)session.get(Customer.class, "402881e534fa5a440134fa5a45340002");
            System.out.println("customer2.getUsername is"+customer2.getUsername());
            /*    */
            tx.commit();
            
            System.out.println("-------------------------------------");
            
            /*    get()               */
            System.out.println("customer1 == customer2 result is "+(customer1==customer2));
        }
        catch (Exception e)
        {
            if(tx!=null)
            {
                tx.rollback();
            }
        }
        finally
        {
            session.close();
        }
    }
}
  
Hibernate: 
    select
        customer0_.id as id0_0_,
        customer0_.username as username0_0_,
        customer0_.balance as balance0_0_ 
    from
        customer customer0_ 
    where
        customer0_.id=?
customer.getUsername islisi
-------------------------------------
customer2.getUsername islisi
-------------------------------------
customer1 == customer2 result is true

출력 결과 에는 SELECT SQL 문구 만 포함 되 어 있 으 며,customer 1==customer 2 result is true 는 두 대상 이 같은 대상 임 을 설명 합 니 다.그 원 리 는 첫 번 째 get()방법 을 호출 하 는 것 입 니 다.Hibernate 는 캐 시 에 이 검색 대상 이 있 는 지,없 는 지 를 먼저 검색 합 니 다.Hibernate 는 SELECT 문 구 를 데이터베이스 에 보 내 해당 대상 을 꺼 낸 다음 에 사용 할 수 있 도록 캐 시 에 넣 습 니 다.두 번 째 는 get()방법 을 호출 합 니 다.Hibernate 는 캐 시 에 이 검색 대상 이 있 는 지,마침 이 검색 대상 이 있 는 것 을 발견 하면 캐 시 에서 꺼 내 데이터베이스 에서 검색 하지 않 습 니 다.
 
3.2 급 캐 시 관리:
evict(Class arg 0,Serializable arg 1)는 지정 한 ID 의 영구 화 대상 을 2 급 캐 시 에서 제거 하고 대상 이 사용 하 는 자원 을 방출 합 니 다.
sessionFactory.evict(Customer.class, new Integer(1));  

evict(Class arg0)  지정 한 클래스 의 모든 지구 화 대상 을 2 급 캐 시 에서 삭제 하고 사용 하 는 메모리 자원 을 방출 합 니 다.
sessionFactory.evict(Customer.class);  

evictCollection(String arg0)  지정 한 클래스 의 모든 지구 화 대상 의 지정 한 집합 을 2 급 캐 시 에서 삭제 하고 사용 하 는 메모리 자원 을 방출 합 니 다.
sessionFactory.evictCollection("Customer.orders");  

4.2 급 캐 시 설정
자주 사용 하 는 2 급 캐 시 플러그 인
EHCache  org.hibernate.cache.EhCacheProvider
OSCache  org.hibernate.cache.OSCacheProvider
SwarmCahe  org.hibernate.cache.SwarmCacheProvider
JBossCache  org.hibernate.cache.TreeCacheProvider
<!-- EHCache   ,hibernate.cfg.xml --> 
<hibernate-configuration>
    <session-factory>
       <!--         EHCache Provider -->
       <property name="hibernate.cache.provider_class">
          org.hibernate.cache.EhCacheProvider
       </property>
       <!--   "    " -->
       <property name="hibernate.cache.use_query_cache">
          true
       </property>
    </session-factory>
  </hibernate-configuration>
<!-- ehcache.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!--
                
    -->
    <diskStore path="d:/ehcache"></diskStore>
    <!--
            
        maxElementsInMemory :              。
        eternal :            。
        timeToIdleSeconds :         。
        timeToLiveSeconds :          ,                。
        overflowToDisk :    ,        。
    -->
    <defaultCache maxElementsInMemory="200" eternal="false" 
        timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></defaultCache>
    <!--
               。
                       ,         。
    -->
    <cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" 
        timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache>
</ehcache>
<!-- *.hbm.xml -->
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
   <class>
       <!--                    read-only read-write nonstrict-read-write transactional-->
       <cache usage="read-write"/>    
   </class>
</hibernate-mapping>

한 쌍 이상 의 관계 가 있다 면 한 쪽 을 가 져 올 때 연 결 된 다 중 캐 시 를 하려 면 집합 속성 에하위 탭 을 추가 해 야 합 니 다.연 결 된 대상 의 hbm 파일 에탭 에 도탭 을 추가 해 야 합 니 다.그렇지 않 으 면 Hibernate 는 OID 만 캐 시 합 니 다.
<hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer">
            <!--      -->
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
            
            <!--      -->
            <property name="username" column="username" type="string"></property>
            <property name="balance" column="balance" type="integer"></property>
            
            <set name="orders" inverse="true" cascade="all" lazy="false" fetch="join">
                <cache usage="read-only"/>
                <key column="customer_id" ></key>
                <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/>
            </set>
            
        </class>
    </hibernate-mapping>

다음으로 전송:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html

좋은 웹페이지 즐겨찾기