1.见表
CREATE TABLE `dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dname` varchar(30) NOT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2.添加jar 包(mysql 驱动包,ehcache使用jar包。hiberante的jar包)
3.添加hiberante支持,生成实体映射。
3.1 : hibernate.cfg.xml 配置
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<!--ehcache 使用的配置-->
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--启用查询cache-->
<property name="hibernate.cache.use_query_cache">true</property>
<!--启用二级缓存cache-->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="show_sql">true</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">mysql</property>
<mapping resource="com/shen/domain/Dept.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.2: Dept 实体类 和Dept.hbm.xml
package com.shen.domain;
// default package
/**
* Dept entity. @author MyEclipse Persistence Tools
*/
public class Dept implements java.io.Serializable {
// Fields
private Integer id;
private String dname;
private Integer version;
// Constructors
/** default constructor */
public Dept() {
}
/** minimal constructor */
public Dept(String dname) {
this.dname = dname;
}
/** full constructor */
public Dept(String dname, Integer version) {
this.dname = dname;
this.version = version;
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDname() {
return this.dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public Integer getVersion() {
return this.version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
<?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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.shen.domain.Dept" table="dept" catalog="test">
<!--添加这个配置-
缓存策略
◆只读缓存(read-only):只读策略,不能修改。
◆读/写缓存(read-write):读写策略,缓存中的数据即能读也能写。。
◆不严格的读/写缓存(nonstrict-read-write):需要更新数据,但是两个事务更新同一条记录的可能性很小,性能比读写缓存好。
◆事务缓存(transactional):缓存支持事务,发生异常的时候,缓存也能够回滚,只支持jta环境,这个我没有怎么研究过。
读写缓存和不严格读写缓存在实现上的区别在于,读写缓存更新缓存的时候会把缓存里面的数据换成一个锁,其他事务如果去取相应的缓存数据,发现被锁住了,然后就直接取数据库查询。
->
<cache usage="read-only"/>
或者 <cache usage="read-only" region="deptcache" /> 与下文cache 名称对应
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="dname" type="java.lang.String">
<column name="dname" length="30" not-null="true" />
</property>
<property name="version" type="java.lang.Integer">
<column name="version" />
</property>
</class>
</hibernate-mapping>
4.在src 下添加ehcache.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--
diskStore:设置缓存数据存放的路径
defaultCache:设置数据的默认过期策略。
cache:设置具体的命名缓存的数据过期策略。
-->
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="1000" eternal="false"
overflowToDisk="false" timeToIdleSeconds="300" timeToLiveSeconds="300"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />
<cache name="deptcache" maxElementsInMemory="5000"
eternal="true"
overflowToDisk="true" />
<!-- name 值可为类的完整名称或者集合的名称,或者hbm.xml文件中, region="abc" 中对应的值。
maxElementsinMemory:设置内存中允许存放对象的最大数量。
eternal:如果为true,表示对象永不过期(默认为false)
overflowToDisk:如果为true,表示当对象数量超过了最大上限,则把溢出的对象写到基于硬盘的缓存中。
timeToIdleSeconds:设置允许对象空闲的最大时间。当超过这个时间,Ehcache会把对象从缓存中清除。
timeToLiveSeconds:设置对象允许存在于缓存中的最大时间。如果取值为0,表示对象可以无限期的存在缓存中,
他的值只有在大于等于timeToIdleSeconds时,才有意义。
-->
<cache name="com.shen.Dept" maxElementsInMemory="500"
eternal="true" />
</ehcache>
5.测试
添加测试数据
package com.shen.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.shen.domain.Dept;
public class MainTest {
public static void main(String[] args) {
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session sess = sf.openSession();
Transaction tx = null;
tx = sess.beginTransaction();
for (int i=0;i<=10000;i++)
{
Dept dept =new Dept();
dept.setDname("Eachace"+i);
sess.save(dept);
}
tx.commit();
sess.close();
System.out.println("结束");
}
}
查询
package com.shen.test;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class MainTest1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session session = sf.openSession();
List list = session.createQuery("from Dept").setMaxResults(20).setCacheable(true).list();
session.close();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("\n==================\n");
Session session2 = sf.openSession();
List list2 = session2.createQuery("from Dept").setMaxResults(20).setCacheable(true).list();
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
session2.close();
sf.close();
}
}
6:附
< defaultCache
maxElementsInMemory = "10000"
maxElementsOnDisk = "0"
eternal = "true"
overflowToDisk = "true"
diskPersistent = "false"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
diskSpoolBufferSizeMB = "50"
diskExpiryThreadIntervalSeconds = "120"
memoryStoreEvictionPolicy = "LFU"
/>
< cache name = "myCache"
maxElementsInMemory = "100"
maxElementsOnDisk = "0"
eternal = "false"
overflowToDisk = "false"
diskPersistent = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
diskSpoolBufferSizeMB = "50"
diskExpiryThreadIntervalSeconds = "120"
memoryStoreEvictionPolicy = "FIFO"
/>
diskStore :指定数据存储位置,可指定磁盘中的文件夹位置
defaultCache : 默认的管理策略
以下属性是必须的:
name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)。
maxElementsInMemory: 在内存中缓存的element的最大数目。
maxElementsOnDisk: 在磁盘上缓存的element的最大数目,默认值为0,表示不限制。
eternal: 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断。
overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上。
以下属性是可选的:
timeToIdleSeconds: 对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问。
timeToLiveSeconds: 对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问。
diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。
diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。
diskSpoolBufferSizeMB: DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore。
memoryStoreEvictionPolicy: 如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU。
缓存的3 种清空策略 :
FIFO ,first in first out (先进先出).
LFU , Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
LRU ,Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。ently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。east Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
附2.
<cache name="testCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU" />
各配置参数的含义:
maxElementsInMemory:缓存中允许创建的最大对象数
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
overflowToDisk:内存不足时,是否启用磁盘缓存。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
附3.
经过测试
maxElementsInMemory="5000"
当list中数据大于配置中的5000时,查询效率反而慢了,测试表明,设置的数,越接近实际数值,效率越高(实际值大于配置值)。设置的数越大于实际值,效率越高。
List list2 = session2.createQuery("from Dept").setCacheable(true).list();
//全查询。考虑实际值和配置值的大小。