EHCache简单使用

EHCache简单使用 博客分类: java
转载:http://voyageivi.iteye.com/blog/1484715 感谢分享。
SQLCacheMySQLJVMXML .
关于缓存的话题,在坛子里已经有很多讨论,简单的来说,如果一个应用中80% 的时间内都在访问20% 的数据,那么,这时候就应该使用缓存了。
测试环境:
MySQL 5.0.22,
jdk1.6.0_07,
ehcache-1.6.0-beta2,
mysql-connector-java-3.1.14

测试表:
Sql代码
1.CREATE TABLE TEST
2.(
3.TEST_ID BIGINT,
4.TEST_NAME VARCHAR(50),
5.TEST_TIME TIMESTAMP,
6.TEST_VALUE DECIMAL(10, 3)
7.);
CREATE TABLE TEST
(
TEST_ID BIGINT,
TEST_NAME VARCHAR(50),
TEST_TIME TIMESTAMP,
TEST_VALUE DECIMAL(10, 3)
);
支持类:

Java代码
1.public class Util {
2.
3. public static Random rand = new Random();
4. public static String atoz = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
5.
6. public static String genString(int length) {
7. StringBuilder re = new StringBuilder(length);
8. re.append(atoz.charAt(rand.nextInt(52)));
9. for (int i = 0; i < length; i++) {
10. re.append(atoz.charAt(rand.nextInt(62)));
11. }
12. return re.toString();
13. }
14.
15. public static double genDouble() {
16. double d1 = 5120 * rand.nextDouble();
17. double d2 = 1024000 * rand.nextDouble();
18. return d1 + d2;
19. }
20.}
public class Util {

public static Random rand = new Random();
public static String atoz = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

public static String genString(int length) {
StringBuilder re = new StringBuilder(length);
re.append(atoz.charAt(rand.nextInt(52)));
for (int i = 0; i < length; i++) {
re.append(atoz.charAt(rand.nextInt(62)));
}
return re.toString();
}

public static double genDouble() {
double d1 = 5120 * rand.nextDouble();
double d2 = 1024000 * rand.nextDouble();
return d1 + d2;
}
}
插入测试数据:

Java代码
1.public static void traditionalInsert(int total) throws Exception {
2. Thread.sleep(3000);
3. Timestamp current = new Timestamp(System.currentTimeMillis());
4. String currentStr = dateFormat.format(current);
5. System.out.println(currentStr);
6. Connection conn = DriverManager.getConnection(dbURL, user, pass);
7. try {
8. long begin = System.currentTimeMillis();
9. conn.setAutoCommit(false);
10. String sql = "INSERT INTO TEST (TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE) VALUES (?, ?, ?, ?)";
11. PreparedStatement ps = conn.prepareStatement(sql);
12. for (int i = 1; i <= total; i++) {
13. ps.setLong(1, i);
14. ps.setString(2, Util.genString(33));
15. ps.setTimestamp(3, current);
16. ps.setBigDecimal(4, new BigDecimal(Util.genDouble()));
17. ps.addBatch();
18. if ((i % 500) == 0) {
19. ps.executeBatch();
20. }
21. }
22. ps.executeBatch();
23. conn.commit();
24. long end = System.currentTimeMillis();
25. System.out.printf("Count:%d Time:%d\n", total, (end - begin));
26. } catch (Exception ex) {
27. ex.printStackTrace();
28. conn.rollback();
29. } finally {
30. conn.close();
31. }
32. }
public static void traditionalInsert(int total) throws Exception {
Thread.sleep(3000);
Timestamp current = new Timestamp(System.currentTimeMillis());
String currentStr = dateFormat.format(current);
System.out.println(currentStr);
Connection conn = DriverManager.getConnection(dbURL, user, pass);
try {
long begin = System.currentTimeMillis();
conn.setAutoCommit(false);
String sql = "INSERT INTO TEST (TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE) VALUES (?, ?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 1; i <= total; i++) {
ps.setLong(1, i);
ps.setString(2, Util.genString(33));
ps.setTimestamp(3, current);
ps.setBigDecimal(4, new BigDecimal(Util.genDouble()));
ps.addBatch();
if ((i % 500) == 0) {
ps.executeBatch();
}
}
ps.executeBatch();
conn.commit();
long end = System.currentTimeMillis();
System.out.printf("Count:%d Time:%d\n", total, (end - begin));
} catch (Exception ex) {
ex.printStackTrace();
conn.rollback();
} finally {
conn.close();
}
}
使用的javaBean:

Java代码
1.public class TEST implements Serializable {
2. private static final long serialVersionUID = 1L;
3. public Long TEST_ID;
4. public String TEST_NAME;
5. public Timestamp TEST_TIME;
6. public BigDecimal TEST_VALUE;
7. @Override
8. public String toString() {
9. return String.format("ID:%s,,,NAME:%s", TEST_ID, TEST_NAME);
10. }
11.}
public class TEST implements Serializable {
private static final long serialVersionUID = 1L;
public Long TEST_ID;
public String TEST_NAME;
public Timestamp TEST_TIME;
public BigDecimal TEST_VALUE;
@Override
public String toString() {
return String.format("ID:%s,,,NAME:%s", TEST_ID, TEST_NAME);
}
}
先试一下缓存到字典中:

Java代码
1.public static HashMap<Long, TEST> simpleCache() throws Exception {
2. HashMap<Long, TEST> cacheid = new HashMap<Long, TEST>();
3. Class.forName(dbDriver);
4. Connection conn = DriverManager.getConnection(dbURL, user, pass);
5. try {
6. long begin = System.currentTimeMillis();
7. Statement s = conn.createStatement();
8. String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST";
9. ResultSet querySet = s.executeQuery(sql);
10. for (int i = 1; querySet.next(); i++) {
11. TEST curr = new TEST();
12. curr.TEST_ID = querySet.getLong(1);
13. curr.TEST_NAME = querySet.getString(2);
14. curr.TEST_TIME = querySet.getTimestamp(3);
15. curr.TEST_VALUE = querySet.getBigDecimal(4);
16. cacheid.put(curr.TEST_ID, curr);
17. }
18. long end = System.currentTimeMillis();
19. System.out.printf("Time:%d\n", (end - begin));
20. } catch (Exception ex) {
21. ex.printStackTrace();
22. } finally {
23. conn.close();
24. }
25. return cacheid;
26. }
public static HashMap<Long, TEST> simpleCache() throws Exception {
HashMap<Long, TEST> cacheid = new HashMap<Long, TEST>();
Class.forName(dbDriver);
Connection conn = DriverManager.getConnection(dbURL, user, pass);
try {
long begin = System.currentTimeMillis();
Statement s = conn.createStatement();
String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST";
ResultSet querySet = s.executeQuery(sql);
for (int i = 1; querySet.next(); i++) {
TEST curr = new TEST();
curr.TEST_ID = querySet.getLong(1);
curr.TEST_NAME = querySet.getString(2);
curr.TEST_TIME = querySet.getTimestamp(3);
curr.TEST_VALUE = querySet.getBigDecimal(4);
cacheid.put(curr.TEST_ID, curr);
}
long end = System.currentTimeMillis();
System.out.printf("Time:%d\n", (end - begin));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
conn.close();
}
return cacheid;
}
缓存到字典中,写法比较简单,使用方便,缺点就是缓存数据量比较少,一般缓存10W就有可能把jvm的缓存给占完了。用ehcache就可以解决缓存数据太少的问题。

一个简单的配置:

Xml代码
1.<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2. xsi:noNamespaceSchemaLocation="ehcache.xsd">
3. <diskStore path="java.io.tmpdir"/>
4. <defaultCache
5. maxElementsInMemory="10000"
6. maxElementsOnDisk="0"
7. eternal="true"
8. overflowToDisk="true"
9. diskPersistent="false"
10. timeToIdleSeconds="0"
11. timeToLiveSeconds="0"
12. diskSpoolBufferSizeMB="50"
13. diskExpiryThreadIntervalSeconds="120"
14. memoryStoreEvictionPolicy="LFU"
15. />
16. <cache name="demoCache"
17. maxElementsInMemory="100"
18. maxElementsOnDisk="0"
19. eternal="false"
20. overflowToDisk="false"
21. diskPersistent="false"
22. timeToIdleSeconds="119"
23. timeToLiveSeconds="119"
24. diskSpoolBufferSizeMB="50"
25. diskExpiryThreadIntervalSeconds="120"
26. memoryStoreEvictionPolicy="FIFO"
27. />
28.</ehcache>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="0"
eternal="true"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LFU"
/>
<cache name="demoCache"
maxElementsInMemory="100"
maxElementsOnDisk="0"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="119"
timeToLiveSeconds="119"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="FIFO"
/>
</ehcache>
Cache配置中的几个属性:

name:Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)。
maxElementsInMemory:内存中保持的对象数量。
maxElementsOnDisk:DiskStore中保持的对象数量,默认值为0,表示不限制。
eternal:是否是永恒数据,如果是,则它的超时设置会被忽略。
overflowToDisk:如果内存中数据数量超过maxElementsInMemory限制,是否要缓存到磁盘上。
timeToIdleSeconds:对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问。
timeToLiveSeconds:对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问。
diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。
diskExpiryThreadIntervalSeconds:对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。
diskSpoolBufferSizeMB:DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore。
memoryStoreEvictionPolicy:如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU。

获取配置中的demoCache:

Java代码
1.CacheManager manager = CacheManager.create("ehcache.xml");
2.Cache demo = manager.getCache("demoCache");
CacheManager manager = CacheManager.create("ehcache.xml");
Cache demo = manager.getCache("demoCache");
往cache中加入数据:

Java代码
1.public static void ehcache() throws Exception {
2. CacheManager manager = CacheManager.create("ehcache.xml");
3. manager.addCache("TEST_ID.TEST");
4. Cache cid = manager.getCache("TEST_ID.TEST");
5. Class.forName(dbDriver);
6. Connection conn = DriverManager.getConnection(dbURL, user, pass);
7. try {
8. long begin = System.currentTimeMillis();
9. Statement s = conn.createStatement();
10. String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST";
11. ResultSet querySet = s.executeQuery(sql);
12. for (int i = 1; querySet.next(); i++) {
13. TEST curr = new TEST();
14. curr.TEST_ID = querySet.getLong(1);
15. curr.TEST_NAME = querySet.getString(2);
16. curr.TEST_TIME = querySet.getTimestamp(3);
17. curr.TEST_VALUE = querySet.getBigDecimal(4);
18. cid.put(new Element(curr.TEST_ID, curr));
19. }
20. long end = System.currentTimeMillis();
21. System.out.printf("Time:%d\n", (end - begin));
22. } catch (Exception ex) {
23. ex.printStackTrace();
24. } finally {
25. conn.close();
26. }
27. }
public static void ehcache() throws Exception {
CacheManager manager = CacheManager.create("ehcache.xml");
manager.addCache("TEST_ID.TEST");
Cache cid = manager.getCache("TEST_ID.TEST");
Class.forName(dbDriver);
Connection conn = DriverManager.getConnection(dbURL, user, pass);
try {
long begin = System.currentTimeMillis();
Statement s = conn.createStatement();
String sql = "SELECT TEST_ID,TEST_NAME,TEST_TIME,TEST_VALUE FROM TEST";
ResultSet querySet = s.executeQuery(sql);
for (int i = 1; querySet.next(); i++) {
TEST curr = new TEST();
curr.TEST_ID = querySet.getLong(1);
curr.TEST_NAME = querySet.getString(2);
curr.TEST_TIME = querySet.getTimestamp(3);
curr.TEST_VALUE = querySet.getBigDecimal(4);
cid.put(new Element(curr.TEST_ID, curr));
}
long end = System.currentTimeMillis();
System.out.printf("Time:%d\n", (end - begin));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
conn.close();
}
}
这里在CacheManager中直接加入了一个叫TEST_ID.TEST的cache。因为只给了一个名字,所以系统会把defaultCache的设置给它clone一份。
使用方法,像字典一样使用就行:

Java代码
1.Cache cid = manager.getCache("TEST_ID.TEST");
2.Element e5120 = cid.get(new Long(5120));
3.System.out.println(e5120.getValue());
Cache cid = manager.getCache("TEST_ID.TEST");
Element e5120 = cid.get(new Long(5120));
System.out.println(e5120.getValue());

ehcache中数据是以java对象的形式存在的,使用了java的序列化保存到磁盘,所以保存的对象要实现Serializable接口。ehcache还可以支持分布式缓存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值