1、關于數據緩存(Cache )
在應用程序中可使用緩存的環節是比較多的,對于如何來使用緩存,為什么要使用緩存以及生命時候使用緩存技術,有興趣的小伙伴們可以去閱讀其它大牛的技術文章或博客。我們今天只是對jfinal的數據緩存和插件使用做一個簡單的科普。
緩存的使用主要還是要根據應用的特性來考慮。首先得分析應用的“變”與“不變”,哪些地方是主要用來展示的,數據操作的不是很頻繁的話,那可以使用緩存來提升應用的性能。
EHCache 是一個純java的在進程中的緩存,它具有以下特性:快速,簡單。接下來我們一起來學習在jfinal中如何使用ehCache。
1.1下載jfinal框架中使用到的jar包
jar包下載地址:http://www.jfinal.com/download?file=jfinal-2.2-all.zip(需注冊賬號)
序列 | 名稱 | 備注 |
---|---|---|
1、 | ehcache-core-2.5.2.jar | 緩存核心包 |
2、 | slf4j-api-1.6.1.jar | slf4j核心接口包 |
3、 | slf4j-log4j12-1.6.1.jar | slf4j調用log4j的實現包 |
1.2添加jar包到project(工程)
copy文件到projectName\WebRoot\WEB-INF\lib目錄下。
1.3 添加ehcache.xml文件
copy文件到ehcache.xml文件到project中src路徑下。
2、寫一點代碼使用cache
2.1我們來為數據讀取作一個簡單的數據緩存操作。翠花上代碼:
/**
* @author yetangtang
* @see 查詢用戶信息
* @param void
* @return Page<Record> list
*/
public Page<Record> queryUsetrList(){
//使用Db中的paginate(分頁)方法。同model操作一樣
Page<Record> list = Db.paginateByCache("userInfo", "userList", 1, 4, "select * ","from user where id > ? ",2);
//Page<Record> list = Db.paginate(1, 4, "select * ","from user where id > ? ",2);
//返回查詢結果
return list;
}
2.2配置ehcache.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir"/>
<!--
name:緩存名稱。
maxElementsInMemory:緩存最大個數。
eternal:對象是否永久有效,一但設置了,timeout將不起作用。
timeToIdleSeconds:設置對象在失效前的允許閑置時間(單位:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,默認值是0,也就是可閑置時間無窮大。
timeToLiveSeconds:設置對象在失效前允許存活時間(單位:秒)。最大時間介于創建時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,默認是0.,也就是對象存活時間無窮大。
overflowToDisk:當內存中對象數量達到maxElementsInMemory時,Ehcache將會對象寫到磁盤中。
diskSpoolBufferSizeMB:這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每個Cache都應該有自己的一個緩沖區。
maxElementsOnDisk:硬盤最大緩存個數。
diskPersistent:是否緩存虛擬機重啟期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認是120秒。
memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU(最近最少使用)。你可以設置為FIFO(先進先出)或是LFU(較少使用)。
clearOnFlush:內存數量最大時是否清除。
-->
<!--默認使用的配置方式-->
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="20"
timeToLiveSeconds="60">
</defaultCache>
<!--
Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes.
If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
-->
<!--demo中使用的配置,第一種-->
<cache name="userInfo"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off"
/>
<!--
Sample cache named sampleCache2
This cache has a maximum of 1000 elements in memory. There is no overflow to disk, so 1000
is also the maximum cache size. Note that when a cache is eternal, timeToLive and
timeToIdle are not used and do not need to be specified.
-->
<!--第二種配置方式-->
<cache name="sampleCache2"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="FIFO"
/>
<!--
Sample cache named sampleCache3. This cache overflows to disk. The disk store is
persistent between cache and VM restarts. The disk expiry thread interval is set to 10
minutes, overriding the default of 2 minutes.
-->
<!--第三種配置方式-->
<cache name="sampleCache3"
maxEntriesLocalHeap="500"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1"
memoryStoreEvictionPolicy="LFU"
/>
</ehcache>
3、探討實現
3.1查看方法
Db操作類中實現了三種分頁緩存方法,我們一起來看一下第一種。第一個參數是cacheName緩存名稱,第二個是Object key(數據對象的名字,你可以這么理解),剩下的都比較熟悉,在此就略過。
/**
* Paginate by cache.
* @see #paginate(int, int, String, String, Object...)
* @return Page
*/
public static Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) {
return dbPro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect, paras);
}
3.2不知代碼真面目,只緣身在代碼外
/**
* Paginate by cache.
* @see #paginate(int, int, String, String, Object...)
* @return Page
*/
public Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) {
//獲取配置文件
ICache cache = config.getCache();
//嘗試從緩存中獲取數據對象信息
Page<Record> result = cache.get(cacheName, key);
//如果緩存中沒有數據信息,則需要去執行查詢;
//得到查詢結果后,并將數據信息添加到緩存中。
if (result == null) {
result = paginate(pageNumber, pageSize, select, sqlExceptSelect, paras);
cache.put(cacheName, key, result);
}
return result;
}
3.3眼見為實,斷點測試一下
首次讀取數據會執行
恭喜,恭喜。至此,小伙伴們已經學會簡單的使用緩存了。接下來,我們會繼續玩一些好玩的技能點。
PS:緩存雖好,依舊多結合自己系統的實際情況考慮。