2015年10月31日 星期六

二級快取 (Hibernate3.x 九)

二級快取又稱SessionFactory快取,必需設定才有辦法使用

※二級快取

二級快取必需由第三方廠商提供,3.6有支緩的廠商在這裡,各家的差別在這裡,由於EHCache看起來都有支緩,所以現在以EHCache為例

pom.xml
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>3.6.10.Final</version>
</dependency>

※先抓個jar檔


hibernate.cfg.xml
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.QueryCacheEnabled">true</property>

※從這裡的Second-level caching複製

Emp.hbm.xml
<class name="vo.Emp" table="Emp">
    <cache usage="read-only" />
    <id name="empno" type="int">
        ...
    </id>
    <property name="ename" type="java.lang.String">
        ...
    </property>
    ...
</class>

※順序要正確,如果把cache打在最下面,執行時會出「org.hibernate.InvalidMappingException: Unable to read XML」的錯


Emp.java
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "DEPT", schema = "c##scott")
public class Dept {
    ...
}

※打在class層級的地方,xml和annotation選其一即可,只是hibernate.cfg.xml的mapping resource和mapping class要打對


TestHibernate.java
SessionFactory sf = HibernateUtil2.getSessionFactory();
Session s1 = sf.openSession();
Session s2 = sf.openSession();
    
try {
    Emp e1 = (Emp) s1.get(Emp.class, 7369);
    Emp e2 = (Emp) s2.get(Emp.class, 7369);
    System.out.println("e1:" + e1.getEname());
    System.out.println("e2:" + e2.getEname());

} catch (Exception e) {
    System.err.println("例外錯誤!");
    e.printStackTrace();
} finally {
    if (s1.isOpen()) {
        s1.close();
    }
    if (s2.isOpen()) {
        s2.close();
    }
}

※因為有用二級快取,所以只會查詢一次

還可以對整個package設定二級快取,這樣hbm.xml或annotation就可以不用設定了,如下:

hibernate.cfg.xml
<session-factory>
        ...
        <mapping class="vo.Dept" />
        <mapping class="vo.Emp" />
    <class-cache usage="read-only" class="vo.Emp"/>
</session-factory>

※打在最下面是ok的,但其他順序會出現「org.hibernate.MappingException: invalid configuration」的錯

※usage有以下五種
.NONE:不設定快取,annotation才有,xml不打就可以了

.READ_ONLY:查詢才有快取,修改和刪除會出「java.lang.UnsupportedOperationException: Can't write to a readonly object」錯,新增ok,但沒快取


------以下三個選項在JPA環境要設定hibernate.transaction.manager_lookup_class------
以下三個選項我沒試,是參考網友的文章和官方的文件寫的

.NONSTRICT_READ_WRITE:增刪改查都會快取,但資料改變時,快取資料不會立刻修改,進行下一次查詢時才會重新保存,所以才會叫nonstrict(不嚴格)

.READ_WRITE:增刪改查都有快取

.TRANSACTIONAL:commit有快取,rollback也會回滾快取

官方可參考這裡

沒有留言:

張貼留言