您的位置:首页 > 其它

ehcache简单使用

2014-08-26 11:49 399 查看
转自 http://oaklet.iteye.com/blog/309037
关于缓存的话题,在坛子里已经有很多讨论,简单的来说,如果一个应用中80% 的时间内都在访问20% 的数据,那么,这时候就应该使用缓存了。

测试环境:

MySQL 5.0.22,

jdk1.6.0_07,

ehcache-1.6.0-beta2,

mysql-connector-java-3.1.14

测试表:

Sql代码


CREATE TABLE TEST

(

TEST_ID BIGINT,

TEST_NAME VARCHAR(50),

TEST_TIME TIMESTAMP,

TEST_VALUE DECIMAL(10, 3)

);

支持类:

Java代码


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代码


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代码


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代码


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代码


<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代码


CacheManager manager = CacheManager.create("ehcache.xml");

Cache demo = manager.getCache("demoCache");

往cache中加入数据:

Java代码


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代码


Cache cid = manager.getCache("TEST_ID.TEST");

Element e5120 = cid.get(new Long(5120));

System.out.println(e5120.getValue());

ehcache中数据是以java对象的形式存在的,使用了java的序列化保存到磁盘,所以保存的对象要实现Serializable接口。ehcache还可以支持分布式缓存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: