创建一个Java工程OSCacheTest,在其中引入Hibernate 3.2的类库文件。因为需要使用OSCache,还需要引入oscache-2.1.jar包。
一般使用OSCache缓存需要进行三个步骤的配置,具体如下:
步骤一:在Hibernate中配置OSCache
1. 在Hibernate配置文件中打开二级缓存的配置,如下:
<property name="cache.use_second_level_cache">true</property>
2. 这个值在配置文件中,缺省是打开的。这只是打开二级缓存,并没有指定使用哪个二级缓存。所以需要指定使用的何种二级缓存。配置如下:
<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
特别注意:关于二级缓存的配置,必须在<mapping resource="…………" />配置之前,否则报错
步骤二:配置OSCache配置文件
关于缓存中存放多少数据,Hibernate是不关心的,全部由OSCache来完成。需要将OSCache的配置文件oscache.properties放入classpath中(注意不能修改这个文件名),对二级缓存进行具体配置。
在oscache.properties中,有如下的参数配置:cache.capacity=1000
这个数值代表放入缓存的对象数量,这个数量根据用户机器的内存来配置,一般只需要配置这个参数即可。
步骤三:通知Hibernate那些类需要OSCache进行缓存
这个步骤有两种方式可以使用,其作用相同:
第1种:在hibernate.cfg.xml的session-factory中加入:
<class-cache usage="read-only" class="com.mixele.oscache.entity.UserOS"/>
第2种:在映射文件的class元素加入子元素:<class-cache usage="read-only" />
关于usage属性,有4个值可以配置:
read-only:只读,缓存效率最高,用于不更新的数据
read-write:可读写
nonstrict-read-write:用于不重视并发修改的操作(会出现一定的错误数据,即不同步数据)
transactional:事务缓存,可支持事务回滚(OSCache中没有此项功能)
经过以上配置,OSCache缓存就已经生效。
编写测试程序:
Hibernate配置:
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/cachetest</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
<property name="generate_statistics">true</property>
<mapping resource="com/mixele/oscache/entity/UserOS.hbm.xml" />
</session-factory>
</hibernate-configuration>
POJO类及hbm:
public class UserOS {
private int id;
private String name;
private Date birthday;
………………
}
<hibernate-mapping package="com.mixele.oscache.entity">
<class name="UserOS">
<cache usage="read-only"/>
<id name="id"> <generator class="native"/> </id>
<property name="name" length="100"/>
<property name="birthday"/>
</class>
</hibernate-mapping>
缓存测试类:
public class CacheTest{
public static void main(String [] args) {
int num = 1;
DataPutInDB.saveData(num);
for(int i=0;i<num;i++) {
getOSCacheCache(i+1);
}
Statistics st = HibernateUtil.getSessionfactory().getStatistics();
System.out.println("输出统计信息............");
System.out.println(st);
System.out.println("放入: "+st.getSecondLevelCachePutCount()+"次");
System.out.println("命中: "+st.getSecondLevelCacheHitCount()+"次");
System.out.println("失去: "+st.getSecondLevelCacheMissCount()+"次");
}
static UserOS getOSCacheCache(int id) {
Session s = null;
UserOS useros = null;
try{
s = HibernateUtil.getSession();
useros = (UserOS)s.get(UserOS.class, id);//第一次查询,二级缓存中没有信息,miss一次
useros = (UserOS)s.load(UserOS.class, id);//第二次查询,在一级缓存中找到,不进入二级缓存
s.clear();//清空一级缓存
}finally{
if(s != null){
s.close();
}
}
for(int i=1;i<101;i++){
try{
s = HibernateUtil.getSession();
useros = (UserOS)s.get(UserOS.class, id);//在二级缓存中找到,hit两次
System.out.println("第"+i+"次从二级缓存查找 "+useros.getClass());
}finally{
if(s != null){ s.close(); }
}
}
return useros;
}
}