EHCache简单使用

测试环境: 
MySQL 5.0.22, 
jdk1.6.0_07, 
ehcache-1.6.0-beta2, 
mysql-connector-java-3.1.14 

测试表:

CREATE TABLE TEST  
(  
TEST_ID BIGINT,  
TEST_NAME VARCHAR(50),  
TEST_TIME TIMESTAMP,  
TEST_VALUE DECIMAL(10, 3)  
);

支持类:

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;  
    }  
}

插入测试数据:

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:

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);  
    }  
}

先试一下缓存到字典中: 

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就可以解决缓存数据太少的问题。 

一个简单的配置:

<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: 

CacheManager manager = CacheManager.create("ehcache.xml");  
Cache demo = manager.getCache("demoCache");

往cache中加入数据: 

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一份。 
使用方法,像字典一样使用就行: 

Cache cid = manager.getCache("TEST_ID.TEST");  
Element e5120 = cid.get(new Long(5120));  
System.out.println(e5120.getValue());

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

你可能感兴趣的:(EHCache简单使用)