
2005年6月2日
最近在弄swing,需要由JComponent生成BufferedImage,在CSDN上發(fā)現(xiàn)一個(gè)好例子。下面是范例:
Rectangle?rect?=?comp.getBounds();
?BufferedImage?bufImage?=?new?BufferedImage(rect.width,
???????????rect.height,
???????????BufferedImage.TYPE_INT_RGB);
?Graphics?g?=?bufImage.getGraphics();
?g.translate(-rect.x,?-rect.y);
?comp.paint(g);這樣,JComponent中的圖像就保存到BufferedImage中了。
原文的鏈接:
http://dev.csdn.net/article/13/13531.shtm
??????? 好久沒有寫blog了,距離上次寫幾乎已經(jīng)是半年前的事情了。

?這半年發(fā)生了不少事情。首先換了家公司,進(jìn)了家金融企業(yè),每天要西裝革履的,一開始還真是不習(xí)慣。

?這里開發(fā)是用的spring框架,以后要多研究研究spring的東西了。
??????? 第二件事就是和戀愛了三年的女友結(jié)婚了,從此兩人長(zhǎng)相廝守,不知道時(shí)間久了會(huì)不會(huì)審美疲勞。呵呵。

??????? 第三件事就是在深圳買了自己的小房子,雖然是小小的兩房,不過我們已經(jīng)很知足了。

?而且剛好是趕在房?jī)r(jià)大漲前買的,還算走了點(diǎn)運(yùn)氣。換到現(xiàn)在,都不知道去哪里買好了。
??????? 在這里要向一些留言和發(fā)郵件給我的網(wǎng)友道歉,前段時(shí)間實(shí)在是太忙,沒有空回復(fù)你們的信息和郵件。請(qǐng)?jiān)彛?img height="20" src="/Emoticons/QQ/15.gif" width="20" border="0" />
最近真是多事情忙,而且可能要忙到9月底。好久沒有上來更新我的博客了,暫且發(fā)發(fā)牢騷。
這一節(jié)是非常實(shí)用的一節(jié),我在閱讀此書的時(shí)候,一直在迷惑,究竟應(yīng)該怎樣管理Session呢?因?yàn)镾ession的管理是如此重要,類似于以前寫程序?qū)DBC Connection的管理。看完此節(jié)后,終于找到了方法。
在各種Session管理方案中,ThreadLocal模式得到了大量使用。ThreadLocal是Java中一種較為特殊的線程綁定機(jī)制。通過ThreadLocal存取的數(shù)據(jù),總是與當(dāng)前線程相關(guān),也就是說,JVM為每個(gè)運(yùn)行的線程,綁定了私有的本定實(shí)例存取空間,從而為多線程環(huán)境經(jīng)常出現(xiàn)的并發(fā)訪問問題提供了一種隔離機(jī)制。
下面是Hibernate官方提供的一個(gè)ThreadLocal工具:
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
import org.apache.log4j.Logger;


/**//**
* <p>Title: </p>
*
* <p>Description: Session的管理類</p>
*
* <p>Copyright: Copyright (c) 2005</p>
*
* <p>Company: </p>
*
* @author George Hill
* @version 1.0
*/


public class HibernateUtil
{

private static final Logger log = Logger.getLogger(HibernateUtil.class);

private static final SessionFactory sessionFactory;


/**//**
* 初始化Hibernate配置
*/

static
{

try
{
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();

} catch (Throwable ex)
{
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}

public static final ThreadLocal session = new ThreadLocal();


/**//**
* 根據(jù)當(dāng)前線程獲取相應(yīng)的Session
* @return Session
* @throws HibernateException
*/

public static Session currentSession() throws HibernateException
{
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet

if (s == null)
{
s = sessionFactory.openSession();
session.set(s);
}
return s;
}


/**//**
* 返回Session給相應(yīng)的線程
* @throws HibernateException
*/

public static void closeSession() throws HibernateException
{
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}

}

針對(duì)WEB程序,還可以利用Servlet2.3的Filter機(jī)制,輕松實(shí)現(xiàn)線程生命周期內(nèi)的Session管理。下面是一個(gè)通過Filter進(jìn)行Session管理的典型案例:

public class PersistenceFilter implements Filter
{
protected static ThreadLocal hibernateHolder = new ThreadLocal();


public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
hibernateHolder.set(getSession());

try
{


chain.doFilter(request, response);



} finally
{
Session session = (Session) hibernateHolder.get();

if (session != null)
{
hibernateHolder.set(null);

try
{
session.close();

} catch (HibernateException ex)
{
throw new ServletException(ex);
}
}
}
}


}
數(shù)據(jù)分頁顯示,是很多B/S系統(tǒng)會(huì)遇到的問題。現(xiàn)在大多數(shù)主流數(shù)據(jù)庫都提供了數(shù)據(jù)部分讀取機(jī)制,而對(duì)于某些沒有提供相應(yīng)機(jī)制的數(shù)據(jù)而言,Hibernate也通過其它途徑實(shí)現(xiàn)了分頁,如通過Scrollable ResultSet,如果JDBC不支持Scrollable ResultSet,Hibernate也會(huì)自動(dòng)通過ResultSet的next方法進(jìn)行記錄定位。Hibernate的Criteria、Query等接口提供了一致的方法設(shè)定分頁范圍。下面是書中的例子:
Criteria criteria = session.createCriteria(TUser.class);
Criteria.add(Expression.eq("age", "20"));
//從檢索結(jié)果中獲取第100條記錄開始的20條記錄
criteria.setFirstResult(100);
criteria.setFetchSize(20); 不過,我在測(cè)試的時(shí)候總是不能夠正常工作,把setFetchSize方法換成setMaxResults方法才行。換成最新的mysql-connector-java-3.1.10-bin-g.jar驅(qū)動(dòng)也是一樣。
Hibernate通過Lifecycle、Validatable接口制定了實(shí)體對(duì)象CRUD過程中的回調(diào)方式。
Lifecycle接口中的onSave、onUpdate、onDelete方法,如果返回true則意味著需要中止執(zhí)行相應(yīng)的操作過程。如果代碼運(yùn)行期間拋出了CallbackException,對(duì)應(yīng)的操作也會(huì)被中止。注意,不要試圖在這些方法中調(diào)用Session進(jìn)行持久化操作,這些方法中Session無法正常使用。
Validatable.validate方法將在實(shí)體被持久化之前得到調(diào)用以對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證。此方法在實(shí)體對(duì)象的生命周期內(nèi)可能被數(shù)次調(diào)用,因此,此方法僅用于數(shù)據(jù)本身的邏輯校驗(yàn),而不要試圖在此實(shí)現(xiàn)業(yè)務(wù)邏輯的驗(yàn)證。
Hibernate還引入了Interceptor,為持久化事件的捕獲和處理提供了一個(gè)非侵略性的實(shí)現(xiàn)。Interceptor接口定義了Hibernate中的通用攔截機(jī)制。Session創(chuàng)建時(shí)即可指定加載相應(yīng)的Interceptor,之后,此Session的持久化操作動(dòng)作都將首先經(jīng)由此攔截器捕獲處理。簡(jiǎn)單的加載范例如下:
SessionFactory factory = config.buildSessionFactory();
Interceptor it = new MyInterceptor();
session = sessionFactory.openSession(it); 需要注意的是,與Lifecycle相同,Interceptor的方法中不可通過Session實(shí)例進(jìn)行持久化操作。
有興趣的可以去參加看看,網(wǎng)址:
http://www.javachina.cn/Index.jsp
最近真是忙,事情都擠到一塊去了。
終于有時(shí)間又看了幾頁書。
言歸正傳,Hibernate中的Collection類型分為有序集和無序集兩類。這里所謂的有序和無序,是針對(duì)Hibernate數(shù)據(jù)持久過程中,是否保持?jǐn)?shù)據(jù)集合中的記錄排列順序加以區(qū)分的。無序集有Set,Bag,Map幾種,有序集有List一種。有序集的數(shù)據(jù)在持久化過程中,會(huì)將集合中元素排列的先后順序同時(shí)固化到數(shù)據(jù)庫中,讀取時(shí)也會(huì)返回一個(gè)具備同樣排列順序的數(shù)據(jù)集合。
Hibernate中的Collection類型是用的自己的實(shí)現(xiàn),所以在程序中,不能夠把接口強(qiáng)制轉(zhuǎn)化成相應(yīng)的JDK Collection的實(shí)現(xiàn)。
結(jié)果集的排序有兩種方式:
1. Sort
Collection中的數(shù)據(jù)排序。
2. order-by
對(duì)數(shù)據(jù)庫執(zhí)行Select SQL時(shí),由order by子句實(shí)現(xiàn)的數(shù)據(jù)排序方式。
需要注意的是,order-by特性在實(shí)現(xiàn)中借助了JDK 1.4中的新增集合類LinkedHashSet以及LinkedHashMap。因此,order-by特性只支持在1.4版本以上的JDK中運(yùn)行。
Session.get/load的區(qū)別:
1.如果未能發(fā)現(xiàn)符合條件的記錄,get方法返回null,而load方法會(huì)拋出一個(gè)ObejctNotFoundException。
2.Load方法可返回實(shí)體的代理類類型,而get方法永遠(yuǎn)直接返回實(shí)體類。
3.Load方法可以充分利用內(nèi)部緩存和二級(jí)緩存中現(xiàn)有數(shù)據(jù),而get方法則僅僅在內(nèi)部緩存中進(jìn)行數(shù)據(jù)查找,如沒有發(fā)現(xiàn)對(duì)應(yīng)數(shù)據(jù),將越過二級(jí)緩存,直接調(diào)用SQL完成數(shù)據(jù)讀取。
Session.find/iterate的區(qū)別:
find方法將執(zhí)行Select SQL從數(shù)據(jù)庫中獲得所有符合條件的記錄并構(gòu)造相應(yīng)的實(shí)體對(duì)象,實(shí)體對(duì)象構(gòu)建完畢之后,就將其納入緩存。它對(duì)緩存只寫不讀,因此無法利用緩存。
iterate方法首先執(zhí)行一條Select SQL以獲得所有符合查詢條件的數(shù)據(jù)id,隨即,iterate方法首先在本地緩存中根據(jù)id查找對(duì)應(yīng)的實(shí)體對(duì)象是否存在,如果緩存中已經(jīng)存在對(duì)應(yīng)的數(shù)據(jù),則直接以此數(shù)據(jù)對(duì)象作為查詢結(jié)果,如果沒有找到,再執(zhí)行相應(yīng)的Select語句獲得對(duì)應(yīng)的庫表記錄(iterate方法如果執(zhí)行了數(shù)據(jù)庫讀取操作并構(gòu)建了完整的數(shù)據(jù)對(duì)象,也會(huì)將其查詢結(jié)果納入緩存)。
Query Cache產(chǎn)生作用的情況:
1.完全相同的Select SQL重復(fù)執(zhí)行。
2.在兩次查詢之間,此Select SQL對(duì)應(yīng)的庫表沒有發(fā)生過改變。
Session.save方法的執(zhí)行步驟:
1.在Session內(nèi)部緩存中尋找待保存對(duì)象。內(nèi)部緩存命中,則認(rèn)為此數(shù)據(jù)已經(jīng)保存(執(zhí)行過insert操作),實(shí)體對(duì)象已經(jīng)處于Persistent狀態(tài),直接返回。
2.如果實(shí)體類實(shí)現(xiàn)了lifecycle接口,則調(diào)用待保存對(duì)象的onSave方法。
3.如果實(shí)體類實(shí)現(xiàn)了validatable接口,則調(diào)用其validate()方法。
4.調(diào)用對(duì)應(yīng)攔截器的Interceptor.onSave方法(如果有的話)。
5.構(gòu)造Insert SQL,并加以執(zhí)行。
6.記錄插入成功,user.id屬性被設(shè)定為insert操作返回的新記錄id值。
7.將user對(duì)象放入內(nèi)部緩存。
8.最后,如果存在級(jí)聯(lián)關(guān)系,對(duì)級(jí)聯(lián)關(guān)系進(jìn)行遞歸處理。
Session.update方法的執(zhí)行步驟:
1.根據(jù)待更新實(shí)體對(duì)象的Key,在當(dāng)前session的內(nèi)部緩存中進(jìn)行查找,如果發(fā)現(xiàn),則認(rèn)為當(dāng)前實(shí)體對(duì)象已經(jīng)處于Persistent狀態(tài),返回。
2.初始化實(shí)體對(duì)象的狀態(tài)信息(作為之后臟數(shù)據(jù)檢查的依據(jù)),并將其納入內(nèi)部緩存。注意這里Session.update方法本身并沒有發(fā)送Update SQL完成數(shù)據(jù)更新操作,Update SQL將在之后的Session.flush方法中執(zhí)行(Transaction.commit在真正提交數(shù)據(jù)庫事務(wù)之前會(huì)調(diào)用Session.flush)。
Session.saveOrUpdate方法的執(zhí)行步驟:
1.首先在Session內(nèi)部緩存中進(jìn)行查找,如果發(fā)現(xiàn)則直接返回。
2.執(zhí)行實(shí)體類對(duì)應(yīng)的Interceptor.isUnsaved方法(如果有的話),判斷對(duì)象是否為未保存狀態(tài)。
3.根據(jù)unsaved-value判斷對(duì)象是否處于未保存狀態(tài)。
4.如果對(duì)象未保存(Transient狀態(tài)),則調(diào)用save方法保存對(duì)象。
5.如果對(duì)象為已保存(Detached狀態(tài)),調(diào)用update方法將對(duì)象與Session重新關(guān)聯(lián)。
事務(wù)的4個(gè)基本特性(ACID):
1. Atomic(原子性):事務(wù)中包含的操作被看作一個(gè)邏輯單元,這個(gè)邏輯單元中的操作要么全部成功,要么全部失敗。
2. Consistency(一致性):只有合法的數(shù)據(jù)可以被寫入數(shù)據(jù)庫,否則事務(wù)應(yīng)該將其回滾到最初狀態(tài)。
3. Isolation(隔離性):事務(wù)允許多個(gè)用戶對(duì)同一個(gè)數(shù)據(jù)的并發(fā)訪問,而不破壞數(shù)據(jù)的正確性和完整性。同時(shí),并行事務(wù)的修改必須與其他并行事務(wù)的修改相互獨(dú)立。
4. Durability(持久性):事務(wù)結(jié)束后,事務(wù)處理的結(jié)果必須能夠得到固化。
數(shù)據(jù)庫操作過程中可能出現(xiàn)的3種不確定情況:
1. 臟讀取(Dirty Reads):一個(gè)事務(wù)讀取了另一個(gè)并行事務(wù)未提交的數(shù)據(jù)。
2. 不可重復(fù)讀取(Non-repeatable Reads):一個(gè)事務(wù)再次讀取之前的數(shù)據(jù)時(shí),得到的數(shù)據(jù)不一致,被另一個(gè)已提交的事務(wù)修改。
3. 虛讀(Phantom Reads):一個(gè)事務(wù)重新執(zhí)行一個(gè)查詢,返回的記錄中包含了因?yàn)槠渌罱峤坏氖聞?wù)而產(chǎn)生的新記錄。
標(biāo)準(zhǔn)SQL規(guī)范中,為了避免上面3種情況的出現(xiàn),定義了4個(gè)事務(wù)隔離等級(jí):
1. Read Uncommitted:最低等級(jí)的事務(wù)隔離,僅僅保證了讀取過程中不會(huì)讀取到非法數(shù)據(jù)。上訴3種不確定情況均有可能發(fā)生。
2. Read Committed:大多數(shù)主流數(shù)據(jù)庫的默認(rèn)事務(wù)等級(jí),保證了一個(gè)事務(wù)不會(huì)讀到另一個(gè)并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”。該級(jí)別適用于大多數(shù)系統(tǒng)。
3. Repeatable Read:保證了一個(gè)事務(wù)不會(huì)修改已經(jīng)由另一個(gè)事務(wù)讀取但未提交(回滾)的數(shù)據(jù)。避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來了更多的性能損失。
4. Serializable:最高等級(jí)的事務(wù)隔離,上面3種不確定情況都將被規(guī)避。這個(gè)級(jí)別將模擬事務(wù)的串行執(zhí)行。
Hibernate將事務(wù)管理委托給底層的JDBC或者JTA,默認(rèn)是基于JDBC Transaction的。
Hibernate支持“悲觀鎖(Pessimistic Locking)”和“樂觀鎖(Optimistic Locking)”。
悲觀鎖對(duì)數(shù)據(jù)被外界修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機(jī)制。Hibernate通過使用數(shù)據(jù)庫的for update子句實(shí)現(xiàn)了悲觀鎖機(jī)制。Hibernate的加鎖模式有:
1. LockMode.NONE:無鎖機(jī)制
2. LockMode.WRITE:Hibernate在Insert和Update記錄的時(shí)候會(huì)自動(dòng)獲取
3. LockMode.READ:Hibernate在讀取記錄的時(shí)候會(huì)自動(dòng)獲取
4. LockMode.UPGRADE:利用數(shù)據(jù)庫的for update子句加鎖
5. LockMode.UPGRADE_NOWAIT:Oracle的特定實(shí)現(xiàn),利用Oracle的for update nowait子句實(shí)現(xiàn)加鎖
樂觀鎖大多是基于數(shù)據(jù)版本(Version)記錄機(jī)制實(shí)現(xiàn)。Hibernate在其數(shù)據(jù)訪問引擎中內(nèi)置了樂觀鎖實(shí)現(xiàn),可以通過class描述符的optimistic-lock屬性結(jié)合version描述符指定。optimistic-lock屬性有如下可選取值:
1. none:無樂觀鎖
2. version:通過版本機(jī)制實(shí)現(xiàn)樂觀鎖
3. dirty:通過檢查發(fā)生變動(dòng)過的屬性實(shí)現(xiàn)樂觀鎖
4. all:通過檢查所有屬性實(shí)現(xiàn)樂觀鎖
現(xiàn)在搜狐新聞上報(bào)道已經(jīng)有700多人傷亡,這是自從911事件以后最大的一次恐怖襲擊了。現(xiàn)在這個(gè)世界,是越來越不太平了,貧富差距的加大使得恐怖活動(dòng)有生存的土壤。
不知道世界的經(jīng)濟(jì)會(huì)不會(huì)隨著這次恐怖襲擊而開始走向蕭條。現(xiàn)在的地球越來越像一個(gè)村,發(fā)生在任何一個(gè)角落的事情,都有可能會(huì)影響到每一個(gè)人。
昨晚偶然看見國(guó)際臺(tái)播放星戰(zhàn)的作者喬治盧卡斯榮獲AFI終身成就獎(jiǎng)的頒獎(jiǎng)典禮,耐心的看完了整個(gè)頒獎(jiǎng)典禮。喬治在發(fā)表致詞的時(shí)候,說自己很高興能夠從事自己喜歡的電影工作,如果不拍攝電影,都不知道自己還能夠做什么。拍電影已經(jīng)成了喬治生命的一部分。
看到熒屏上全世界的老人,中年人,年輕人,孩子說著:“Thank you! George.”可以看到喬治的眼睛朦朧。我心中真是感慨,每個(gè)人都有自己的夢(mèng)想,能夠從事自己喜歡的事情,確實(shí)是很開心的一件事。而自己所做的工作,能夠給自己帶來快樂,能夠給人們帶來快樂,這樣的工作才值得用一生的時(shí)間去從事。
每一個(gè)登山者都有著自己心目中最想登上的山頂,能夠登上這個(gè)山頂,前面付出的艱辛都是值得的。人生不也如此么?找到自己喜歡從事的事情,用自己畢生的精力去做這件事。
獻(xiàn)出一份愛心 共同援助重病程序員王俊 |
(2005.06.27) 來自:BJUG |
|
|
|
|
向IT界倡議:援助程序員王俊行動(dòng)
王俊,今年27歲,北京北方銀證公司項(xiàng)目經(jīng)理,是北京Java用戶組(BJUG, 員(http://forum.javaeye.com/profile.php?mode=viewprofile&u=33)。一個(gè)年輕 人,有感興趣的工作,不錯(cuò)的前途,還有一群可以隨時(shí)交流技術(shù)的朋友,生活看起來平 淡卻充實(shí)。
業(yè)余時(shí)間,王俊經(jīng)常還利用blog(http://befresh.blogbus.com)寫下自己生活和工作 中的酸甜苦辣,此外他還有一個(gè)并不富裕但卻很溫馨的家。
然而從今年二月份起,王俊的blog就再也沒有更新過了,他也沒有在BJUG的聚會(huì)和 javaeye出現(xiàn)了,所有人都以為他出差去了。直到最近,驚聞他要換骨髓,才知道今年 年初,王俊被查出患有“骨髓增生異常綜合癥”。
骨髓增生異常綜合征目前認(rèn)為是造血干細(xì)胞增殖分化異常所致的造血功能障礙。主要表 現(xiàn)為外周血全血細(xì)胞減少,骨髓細(xì)胞增生,成熟和幼稚細(xì)胞有形態(tài)異常即病態(tài)造血。部 分患者在經(jīng)歷一定時(shí)期的MDS后轉(zhuǎn)化成為急性白血病;部分因感染、出血或其他原因死 亡,病程中始終不轉(zhuǎn)化為急性白血病。
這種病目前最有效的治療手段是換骨髓。萬幸的是,王俊的妹妹和他的骨髓配型一致, 免疫系統(tǒng)的疾病發(fā)現(xiàn)治療的越早,就越可能成功,他目前的身體狀況還好,只要能更換 骨髓,完全可以康復(fù)!但讓他們一家望而卻步的是,僅手術(shù)押金就需要20萬,全部療程 視治療效果可能需要30-100萬。
王俊的家在浙江杭州千島湖,父母都是農(nóng)民,已然老邁且沒有固定的經(jīng)濟(jì)收入,姐姐在 當(dāng)?shù)爻黾蓿杖腩H低,妹妹目前在北京讀成人教育并在公司打工。王俊是家庭經(jīng)濟(jì)主要 來源,他的病不僅掐斷了家里唯一的經(jīng)濟(jì)來源,還要花上對(duì)他們而言是天文數(shù)字的錢來 治病。
"文章千古事,得失寸心知",這是王俊blog上的座右銘。細(xì)細(xì)翻看這個(gè)典型程序員的 blog,就和他的人一樣樸實(shí)無華,在那里滿眼看到的都是對(duì)技術(shù)的孜孜追求。誰能想到 一個(gè)如此活躍的頭腦現(xiàn)在卻被病魔折磨著。
生命是美好的,這世界每天都有若干悲劇發(fā)生,這次,大家每個(gè)人出一份力,這世界就 會(huì)少一個(gè)悲劇,多一份美好,多一份歡笑。也許,你只是少吃一頓大餐,少買一瓶化妝 品,少看一場(chǎng)演唱會(huì),少買一件名牌服裝,少玩一個(gè)月的網(wǎng)絡(luò)游戲,少上一個(gè)月的網(wǎng), 但是你卻可以為一個(gè)家庭托起一份生的希望。
*****
聯(lián)系方式 郵件 help@bjug.org MSN icecloud@sina.com 冰云(BJUG)
援助辦法:
1 捐款 帳號(hào): 工商銀行 戶名 王俊 帳號(hào) 0200 2008 0102 3428 807 開戶行 工商銀行北京市西內(nèi)所
招商銀行 戶名 王俊 帳號(hào) 9555 5001 0200 2820 開戶行 招商銀行 北京分行
中國(guó)銀行 戶名 王俊 帳號(hào) 4021400-0188-001204-0 開戶行 北京西直門支行
國(guó)外匯款方式 ADD: BANK OF CHINA BEIJING BRANCH NO.8 YA BAO LU BEIJING, CHINA SWIFT-CODE: BKCHCNBJ110 A/CNo: 4021400-0188-001204-0 NAME: WANG JUN
捐款方式: A 網(wǎng)上銀行 工行請(qǐng)采用行內(nèi)匯款->有收款帳號(hào)匯款 招行請(qǐng)采用個(gè)人銀行專業(yè)版的同城轉(zhuǎn)帳/異地匯款,并選中:采用系統(tǒng)內(nèi)快速匯款
B 銀行匯款 請(qǐng)抄錄上述帳號(hào)并到銀行填寫匯款單
請(qǐng)?jiān)诰杩詈螅l(fā)郵件至help@bjug.org,通知我們,以便統(tǒng)計(jì)核對(duì)捐款帳目。郵件中請(qǐng)說明以下信息: (1) 姓名, (2) id/網(wǎng)站, (3) 發(fā)出銀行/發(fā)出帳號(hào), (4) 金額, (5) 時(shí)間
2 幫助宣傳:
- 請(qǐng)到http://befresh.bjug.org 留下你對(duì)他的祝福
- 請(qǐng)?jiān)贛SN上修改您的名字,我們都寫上 [祝福后山]
- 請(qǐng)修改您MSN的頭像為我們提供的圖標(biāo)
- 增加行動(dòng)網(wǎng)站的地址 http://befresh.bjug.org 到MSN名字后面的個(gè)人信息
- 請(qǐng)看到此文的Blogger,在您的blog上link此文,并Trackback到后山的blog
- 請(qǐng)看到此信息的人,幫助一起宣傳,我們需要您的幫助
- 在您的BLOG或網(wǎng)站,加上用我們提供的LOGO,并連接到網(wǎng)站http://befresh.bjug.org
- 泡論壇的,請(qǐng)修改你的論壇LOGO和簽名檔為提供的圖標(biāo)

*****
聯(lián)合發(fā)起: BJUG http://www.bjug.org <http://www.bjug.org/> CSDN http://www.csdn.net <http://www.csdn.net/> JavaEye http://www.javaeye.com <http://www.javaeye.com/> JActionGroup http://www.jactiongroup.net/ Huihoo http://www.huihoo.org <http://www.huihoo.org/> RedSaga http://www.redsaga.com <http://www.redsaga.com/> Matrix http://www.matrix.org.cn <http://www.matrix.org.cn/> Blogbus http://www.blogbus.com <http://www.blogbus.com/> |
摘要: 要將BufferedImage實(shí)例保存為BMP文件,就需要知道BMP文件的格式,可以參考我轉(zhuǎn)載的文章:《BMP文件格式》。 下面是我的將BufferedImage實(shí)例保存為24位色BMP文件的實(shí)現(xiàn)。 ...
閱讀全文
在公元2005年6月27日,我做出了一個(gè)重大的決定,買房!花了自己至今為止都沒有見過的那么多的錢買了一個(gè)小小的2房2廳,

從此變成了“負(fù)翁”。
不過,從此以后再也不用去租房,再也不用幫別人供房,再也不用一年搬一次家。深圳租房實(shí)在太貴,蓮花北的一個(gè)小小的二房都要1800,有點(diǎn)裝修就叫豪華裝修,就是一個(gè)空蕩蕩的房子也開口要1500,太夸張了。住農(nóng)民房又極度不安全,不想拿自己的生命開玩笑。
從此就變成月供一族了,

,不過,有了壓力才有動(dòng)力。為了自己的將來,自己的理想,努力奮斗!
9月26日是入伙的日子,好期待那天的到來啊。
一般而言,ORM的數(shù)據(jù)緩存應(yīng)包含如下幾個(gè)層次:
1. 事務(wù)級(jí)緩存(Transcation Layer Cache)
2. 應(yīng)用級(jí)/進(jìn)程級(jí)緩存(Application/Process Layer Cache)
3. 分布式緩存(Cluster Layer Cache)
Hibernate數(shù)據(jù)緩存(Cache)分為兩個(gè)層次,以Hibernate語義加以區(qū)分,可分為:
1. 內(nèi)部緩存(Session Level,也稱為一級(jí)緩存)
2. 二級(jí)緩存(SessionFactory Level,也稱為二級(jí)緩存)
Hibernate中,緩存將在以下情況中發(fā)揮作用:
1. 通過id[主鍵]加載數(shù)據(jù)時(shí)
2. 延遲加載
內(nèi)部緩存正常情況下由Hibernate自動(dòng)維護(hù),如果需要手動(dòng)干預(yù),可以通過以下方法完成:
1. Session.evict
將某個(gè)特定對(duì)象從內(nèi)部緩存清除。
2. Session.clear
清空內(nèi)部緩存。
在Hibernate中,二級(jí)緩存涵蓋了應(yīng)用級(jí)緩存和分布式緩存領(lǐng)域。如果數(shù)據(jù)滿足以下條件,則可將其納入緩存管理。
1. 數(shù)據(jù)不會(huì)被第三方應(yīng)用修改;
2. 數(shù)據(jù)大小(Data Size)在可接收的范圍之內(nèi);
3. 數(shù)據(jù)更新頻率較低;
4. 同一數(shù)據(jù)可能會(huì)被系統(tǒng)頻繁引用;
5. 非關(guān)鍵數(shù)據(jù)(關(guān)鍵數(shù)據(jù),如金融帳戶數(shù)據(jù))。
Hibernate本身并未提供二級(jí)緩存的產(chǎn)品化實(shí)現(xiàn),而是為眾多的第三方緩存組件提供了接入接口,較常用的第三方組件有:
1. JCS
2. EHCache
3. OSCache
4. JBossCache
5. SwarmCache
Hibernate中啟用二級(jí)緩存,需要在hibernate.cfg.xml配置hibernate.cache.provider_class參數(shù),之后,需要在映射文件中指定各個(gè)映射實(shí)體(以及collection)的緩存同步策略。Hibernate提供了一下4種內(nèi)置的緩存同步策略:
1. read-only
只讀。對(duì)于不會(huì)發(fā)生改變的數(shù)據(jù),可使用只讀型緩存。
2. nonstrict-read-write
如果程序?qū)Σl(fā)訪問下的數(shù)據(jù)同步要求不是非常嚴(yán)格,且數(shù)據(jù)更新操作頻率較低,可以采用本選項(xiàng),獲得較好的性能。
3. read-write
嚴(yán)格可讀寫緩存。基于時(shí)間戳判定機(jī)制,實(shí)現(xiàn)了“read committed”事務(wù)隔離等級(jí)。可用于對(duì)數(shù)據(jù)同步要求嚴(yán)格的情況,但不支持分布式緩存。這也是實(shí)際應(yīng)用中使用最多的同步策略。
4. transactional
事務(wù)型緩存,必須運(yùn)行在JTA事務(wù)環(huán)境中。
在Java語言中,對(duì)象之間的比較可以通過引用比較(==)和內(nèi)容比較(equals)兩種方式進(jìn)行,而在Hibernate的實(shí)體對(duì)象的比較是通過主鍵值來比較,如果要實(shí)現(xiàn)自己的識(shí)別邏輯,則需要重寫equals方法和hashCode方法。
檢查數(shù)據(jù)對(duì)象改變檢查的一般策略有下面兩種:
1. 數(shù)據(jù)對(duì)象監(jiān)控
數(shù)據(jù)對(duì)象監(jiān)控的實(shí)現(xiàn)方式,通過攔截器對(duì)數(shù)據(jù)對(duì)象的設(shè)值方法進(jìn)行攔截。一旦數(shù)據(jù)對(duì)象的設(shè)置方法被調(diào)用,則將其標(biāo)志為“待更新”狀態(tài),之后在數(shù)據(jù)庫操作時(shí)將其更新到對(duì)應(yīng)的庫表。
2. 數(shù)據(jù)版本對(duì)比
在持久層框架中維持?jǐn)?shù)據(jù)對(duì)象的最近讀取版本,當(dāng)數(shù)據(jù)提交時(shí)將提交數(shù)據(jù)與此版本進(jìn)行比對(duì),如果發(fā)生變化則將其同步到數(shù)據(jù)庫對(duì)應(yīng)的庫表。
Hibernate采取的是第二種檢查策略。它采用一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu)"EntityEntry"保存對(duì)應(yīng)實(shí)體類的狀態(tài)信息。
對(duì)于級(jí)聯(lián)對(duì)象的更新,Hibernate將根據(jù)unsaved-value進(jìn)行判定。首先Hibernate會(huì)取出目標(biāo)對(duì)象的id。之后,將此值與unsaved-value進(jìn)行比對(duì),如果相等,則認(rèn)為目標(biāo)對(duì)象尚未保存,否則,認(rèn)為對(duì)象已經(jīng)保存,無需再進(jìn)行保存操作。
最近正在研讀《深入淺出Hibernate》一書,前面寫的隨筆有些也是讀該書的筆記,只是未做歸類,從這篇開始,我將把相關(guān)的內(nèi)容都整理成一個(gè)系列的讀書筆記。
今天這篇是有關(guān)實(shí)體對(duì)象的生命周期。我剛開始接觸Hibernate的時(shí)候,只是簡(jiǎn)單的把它當(dāng)做一個(gè)API工具,直到后來看到有關(guān)VO和PO的內(nèi)容時(shí),才意識(shí)到Hibernate不僅僅是一個(gè)O/R Mapping的API工具,它還是一個(gè)容器。它可以幫你管理實(shí)體對(duì)象的生命周期。
實(shí)體對(duì)象的生命周期有三種狀態(tài):
1.Transient(自由狀態(tài))
此時(shí)的實(shí)體對(duì)象和數(shù)據(jù)庫中的記錄無關(guān)聯(lián),只是一個(gè)普通的JavaBean。
2.Persistent(持久狀態(tài))
此時(shí)的實(shí)體對(duì)象和數(shù)據(jù)庫中的記錄有關(guān)聯(lián),其變更將由Hibernate固化到數(shù)據(jù)庫中。該實(shí)體對(duì)象處于由Hibernate框架所管理的狀態(tài)。
3.Detached(游離狀態(tài))
處于Persistent狀態(tài)的對(duì)象,其對(duì)應(yīng)的Session實(shí)例關(guān)閉之后,那么,此對(duì)象就處于"Detached"狀態(tài)。Detached狀態(tài)和Transient狀態(tài)的區(qū)別在于Detached狀態(tài)的對(duì)象可以再次與某個(gè)Session實(shí)例相關(guān)聯(lián)而成為Persistent對(duì)象。
從實(shí)體對(duì)象是否被納入Hibernate實(shí)體管理容器的角度,Transient和Detached狀態(tài)的實(shí)體對(duì)象可以統(tǒng)稱為VO(Value Object),而被管理的實(shí)體對(duì)象稱為PO(Persistent Object)。兩者的區(qū)別:
1.VO是相對(duì)獨(dú)立的實(shí)體對(duì)象,處于非管理狀態(tài)。
2.PO是Hibernate納入其實(shí)體管理容器(Entity Map)的對(duì)象,它代表了與數(shù)據(jù)庫中某條記錄對(duì)應(yīng)的Hibernate實(shí)體,PO的變化在事務(wù)提交時(shí)將反映到實(shí)際數(shù)據(jù)庫中。
3.如果一個(gè)PO與其對(duì)應(yīng)的Session實(shí)例分離,那么此時(shí),它又會(huì)變成一個(gè)VO。
下圖是我畫的實(shí)體對(duì)象生命周期的狀態(tài)轉(zhuǎn)換圖:
在使用HQL查詢中,有時(shí)并不需要獲取完整的一個(gè)實(shí)體對(duì)象,例如一個(gè)實(shí)體對(duì)象User有三個(gè)屬性:account, password和email,如果我們只需要獲取account和email屬性,那么有兩種方法可以選擇。
1. 用普通的"select user.account, user.email from User as user",程序片斷如下:
List list = session.createQuery("select user.account, user.email from User as user").list();
Iterator it = list.iterator();

while (it.hasNext())
{
Object[] values = (Object[]) it.next();
System.out.println(values[0] + " " + values[1]);
} 這時(shí)調(diào)用Query類的list方法返回的將是一個(gè)每個(gè)元素都是一個(gè)Object數(shù)組的List。如果只獲取一個(gè)屬性,那么返回的List中的每個(gè)元素都是String實(shí)例。
2.在HQL中用new操作符生成實(shí)體對(duì)象,例如:"select new User(user.account, user.email) from User as user",程序片斷如下:
List list = session.createQuery("select new User(user.account, user.email) from User as user").list();
Iterator it = list.iterator();

while (it.hasNext())
{
User user = (User) it.next();
System.out.println(user.getAccount() + " " + user.getEmail());
} 這時(shí)list方法返回的List中的每一個(gè)元素都是User實(shí)體對(duì)象。這里有三點(diǎn)需要注意的:
a.在HQL語句中需要使用as操作符指定User的別名,并且需要在構(gòu)造函數(shù)的屬性前面加上別名;
b.HQL語句中的構(gòu)造函數(shù)在User類中必須要有相應(yīng)的構(gòu)造函數(shù);
c.生成的實(shí)體對(duì)象是VO對(duì)象,如果對(duì)這些對(duì)象調(diào)用Session的saveOrUpdate方法將導(dǎo)致插入新的記錄,而不是更新記錄。
JBuilder 2005中多了一個(gè)Smart MemberInsight功能,這個(gè)功能會(huì)智能的匹配需要調(diào)用的方法或者獲取的屬性。例如有一個(gè)賦值操作,左邊是一個(gè)List,右邊是用一個(gè)方法獲取值,那么當(dāng)輸入"."時(shí),JBuilder 2005會(huì)自動(dòng)的找到所有返回的值為L(zhǎng)ist的方法。
不過,這實(shí)在是一個(gè)不怎么討好的方法。因?yàn)楹芏鄷r(shí)候并不是只有一層方法調(diào)用的,例如,當(dāng)需要用一個(gè)方法獲取一個(gè)實(shí)例,然后再用這個(gè)實(shí)例的方法獲取需要的值時(shí),這個(gè)功能就顯得很礙手了。
終于,我還是決定關(guān)閉這個(gè)“智能”的功能。打開"Tools"——>"Preferences",在"Editor"的子項(xiàng)"CodeInsight"里,展開"MemberInsight",把"Default to Smart MemberInsight"這一項(xiàng)去掉。如下圖所示:
這個(gè)范例說明如何用JFreeChart畫簡(jiǎn)單的柱狀圖,下面是一個(gè)JSP的簡(jiǎn)單范例:
<%@ page contentType="text/html; charset=GB2312" %>
<%@ page import="java.awt.*, java.text.*, java.util.*" %>
<%@ page import="org.jfree.chart.*" %>
<%@ page import="org.jfree.chart.axis.*" %>
<%@ page import="org.jfree.chart.labels.StandardCategoryItemLabelGenerator" %>
<%@ page import="org.jfree.chart.plot.*" %>
<%@ page import="org.jfree.chart.renderer.*" %>
<%@ page import="org.jfree.chart.servlet.ServletUtilities" %>
<%@ page import="org.jfree.data.DefaultCategoryDataset" %>
<%@ page import="org.jfree.ui.TextAnchor" %>

<%
//The data for the bar chart

double[] data =
{85, 156, 179.5, 211, 123};
//The labels for the bar chart

String[] labels =
{"Mon", "Tue", "Wed", "Thu", "Fri"};
DefaultCategoryDataset dataset = new DefaultCategoryDataset();

for (int i = 0; i < data.length; i++)
{
dataset.addValue(data[i], null, labels[i]);
}
JFreeChart chart = ChartFactory.createBarChart3D("Weekly Server Load", "Work Week 25", "MBytes", dataset, PlotOrientation.VERTICAL, false, false, false);
chart.setBackgroundPaint(new Color(0xE1E1E1));
CategoryPlot plot = chart.getCategoryPlot();
// 設(shè)置Y軸顯示整數(shù)
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
CategoryAxis domainAxis = plot.getDomainAxis();
//設(shè)置距離圖片左端距離
domainAxis.setLowerMargin(0.05);
BarRenderer3D renderer = new BarRenderer3D();
//設(shè)置柱的顏色
renderer.setSeriesPaint(0, new Color(0xff00));
plot.setRenderer(renderer);
String filename = ServletUtilities.saveChartAsPNG(chart, 300, 280, null, session);
String graphURL = request.getContextPath() + "/displayChart?filename=" + filename;
%>
<html>
<body topmargin="5" leftmargin="5" rightmargin="0">
<div style="font-size:18pt; font-family:verdana; font-weight:bold">
3D Bar Chart
</div>
<br>
<img src="<%= graphURL %>" border=0>
</body>
</html>

畫出來的圖:

和ChartDirector畫出來的圖做一個(gè)比較:

以前一直是用JFreeChart畫統(tǒng)計(jì)圖的,不過JFreeChart畫出來的圖形不夠精細(xì),看起來有些模糊,今天在網(wǎng)上看到另外一個(gè)工具ChartDirector,這是一個(gè)商業(yè)版本的工具,不過也可以免費(fèi)使用,只是在畫出來的圖形下面都有一條它的廣告條。
下面是它的一個(gè)柱狀圖的例子:

范例程序:
<%@page import="ChartDirector.*" %>
<%
//The data for the bar chart

double[] data =
{85, 156, 179.5, 211, 123};

//The labels for the bar chart

String[] labels =
{"Mon", "Tue", "Wed", "Thu", "Fri"};

//Create a XYChart object of size 300 x 280 pixels
XYChart c = new XYChart(300, 280);

//Set the plotarea at (45, 30) and of size 200 x 200 pixels
c.setPlotArea(45, 30, 200, 200);

//Add a title to the chart
c.addTitle("Weekly Server Load");

//Add a title to the y axis
c.yAxis().setTitle("MBytes");

//Add a title to the x axis
c.xAxis().setTitle("Work Week 25");

//Add a bar chart layer with green (0x00ff00) bars using the given data
c.addBarLayer(data, 0xff00).set3D();

//Set the labels on the x axis.
c.xAxis().setLabels(labels);

//output the chart
String chart1URL = c.makeSession(request, "chart1");

//include tool tip for the chart
String imageMap1 = c.getHTMLImageMap("", "", "title='{xLabel}: {value} MBytes'")
;
%>
<html>
<body topmargin="5" leftmargin="5" rightmargin="0">
<div style="font-size:18pt; font-family:verdana; font-weight:bold">
3D Bar Chart
</div>
<hr color="#000080">
<a href="viewsource.jsp?file=<%=request.getServletPath()%>">
<font size="2" face="Verdana">View Chart Source Code</font>
</a>
</div>
<br>
<img src='<%=response.encodeURL("getchart.jsp?"+chart1URL)%>'
usemap="#map1" border="0">
<map name="map1"><%=imageMap1%></map>
</body>
</html>

如果要在柱的頂部顯示數(shù)值,可以調(diào)用Layer的setDataLabelFormat方法設(shè)置,范例:layer.setDataLabelFormat("{value}");
其它的例子可以參考它的文檔的說明。ChartDirector的網(wǎng)址:http://www.advsofteng.com
如果要在程序中定時(shí)執(zhí)行任務(wù),可以使用java.util.Timer這個(gè)類實(shí)現(xiàn)。使用Timer類需要一個(gè)繼承了java.util.TimerTask的類。TimerTask是一個(gè)虛類,需要實(shí)現(xiàn)它的run方法,實(shí)際上是他implements了Runnable接口,而把run方法留給子類實(shí)現(xiàn)。
下面是我的一個(gè)例子:

class Worker extends TimerTask
{

public void run()
{
System.out.println("我在工作啦!");
}
} Timer類用schedule方法或者scheduleAtFixedRate方法啟動(dòng)定時(shí)執(zhí)行,schedule重載了四個(gè)版本,scheduleAtFixedRate重載了兩個(gè)。每個(gè)方法的實(shí)現(xiàn)都不同,下面是每個(gè)方法的說明:
schedule
public void schedule(TimerTask task,
long delay)
- Schedules the specified task for execution after the specified delay.
-
- Parameters:
task
- task to be scheduled.
delay
- delay in milliseconds before task is to be executed.
- Throws:
IllegalArgumentException
- if delay is negative, or delay + System.currentTimeMillis() is negative.
IllegalStateException
- if task was already scheduled or cancelled, or timer was cancelled.
說明:該方法會(huì)在設(shè)定的延時(shí)后執(zhí)行一次任務(wù)。
schedule
public void schedule(TimerTask task,
Date time)
- Schedules the specified task for execution at the specified time. If the time is in the past, the task is scheduled for immediate execution.
-
- Parameters:
task
- task to be scheduled.
time
- time at which task is to be executed.
- Throws:
IllegalArgumentException
- if time.getTime() is negative.
IllegalStateException
- if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
說明:該方法會(huì)在指定的時(shí)間點(diǎn)執(zhí)行一次任務(wù)。
schedule
public void schedule(TimerTask task,
long delay,
long period)
- Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.
In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down.
-
- Parameters:
task
- task to be scheduled.
delay
- delay in milliseconds before task is to be executed.
period
- time in milliseconds between successive task executions.
- Throws:
IllegalArgumentException
- if delay is negative, or delay + System.currentTimeMillis() is negative.
IllegalStateException
- if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
說明:該方法會(huì)在指定的延時(shí)后執(zhí)行任務(wù),并且在設(shè)定的周期定時(shí)執(zhí)行任務(wù)。
schedule
public void schedule(TimerTask task,
Date firstTime,
long period)
- Schedules the specified task for repeated fixed-delay execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.
In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down.
-
- Parameters:
task
- task to be scheduled.
firstTime
- First time at which task is to be executed.
period
- time in milliseconds between successive task executions.
- Throws:
IllegalArgumentException
- if time.getTime() is negative.
IllegalStateException
- if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
說明:該方法會(huì)在指定的時(shí)間點(diǎn)執(zhí)行任務(wù),然后從該時(shí)間點(diǎn)開始,在設(shè)定的周期定時(shí)執(zhí)行任務(wù)。特別的,如果設(shè)定的時(shí)間點(diǎn)在當(dāng)前時(shí)間之前,任務(wù)會(huì)被馬上執(zhí)行,然后開始按照設(shè)定的周期定時(shí)執(zhí)行任務(wù)。
scheduleAtFixedRate
public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)
- Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period.
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.
-
- Parameters:
task
- task to be scheduled.
delay
- delay in milliseconds before task is to be executed.
period
- time in milliseconds between successive task executions.
- Throws:
IllegalArgumentException
- if delay is negative, or delay + System.currentTimeMillis() is negative.
IllegalStateException
- if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
說明:該方法和schedule的相同參數(shù)的版本類似,不同的是,如果該任務(wù)因?yàn)槟承┰颍ɡ缋占┒舆t執(zhí)行,那么接下來的任務(wù)會(huì)盡可能的快速執(zhí)行,以趕上特定的時(shí)間點(diǎn)。
scheduleAtFixedRate
public void scheduleAtFixedRate(TimerTask task,
Date firstTime,
long period)
- Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.
-
- Parameters:
task
- task to be scheduled.
firstTime
- First time at which task is to be executed.
period
- time in milliseconds between successive task executions.
- Throws:
IllegalArgumentException
- if time.getTime() is negative.
IllegalStateException
- if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
說明:和上一個(gè)方法類似。
下面是我的一個(gè)測(cè)試片斷:

public static void main(String[] args) throws Exception
{
Timer timer = new Timer(false);
timer.schedule(new Worker(), new Date(System.currentTimeMillis() + 1000));
}
今天得知,現(xiàn)在住的房子,公司要準(zhǔn)備拍賣了,那就是說,我又要搬家了。
這將是我大學(xué)畢業(yè)后的第四次搬家了,每年搬一次家,有時(shí)候真的厭倦了這樣的生活,剛適應(yīng)一個(gè)環(huán)境,又要重新去適應(yīng)新的環(huán)境。好想擁有自己的房子,但是現(xiàn)在深圳的房?jī)r(jià)卻讓人望樓興嘆!
什么時(shí)候才能夠讓老百姓過上安居樂業(yè)的生活。
《我想有個(gè)家》,潘美辰的這首老歌,現(xiàn)在最能夠代表我的心情了。
Criteria Query是很好的一種面向?qū)ο蟮牟樵儗?shí)現(xiàn),它提供了一種示例查詢的方式。該方式根據(jù)已有的對(duì)象,查找數(shù)據(jù)庫中屬性匹配的其他對(duì)象。
下面是一個(gè)場(chǎng)景片斷,模糊查找數(shù)據(jù)庫中用戶帳號(hào)為'test',郵件地址為
'georgehill@21cn.com'的實(shí)例,忽略大小寫。

public void testCriteriaExampleQuery() throws Exception
{
User user = new User();
user.setAccount("test");
user.setEmail("georgehill@21cn.com");
Criteria criteria = session.createCriteria(User.class).add(Example.create(user).enableLike(MatchMode.ANYWHERE).ignoreCase());
List list = criteria.list();

if (list != null)
{

for (int i = 0; i < list.size(); i++)
{
System.out.println(((User) list.get(i)).getAccount());
}
}
} 示例查詢需要生成Example實(shí)例,可以通過Example的靜態(tài)方法create生成。Example類有下面的幾個(gè)方法指定查詢的方式:
excludeZeroes
public Example excludeZeroes()
- Exclude zero-valued properties
-
excludeNone
public Example excludeNone()
- Don't exclude null or zero-valued properties
-
enableLike
public Example enableLike(MatchMode matchMode)
- Use the "like" operator for all string-valued properties
-
enableLike
public Example enableLike()
- Use the "like" operator for all string-valued properties
-
ignoreCase
public Example ignoreCase()
- Ignore case for all string-valued properties
-
excludeProperty
public Example excludeProperty(String name)
- Exclude a particular named property
-
當(dāng)用enableLike()方法時(shí),可以通過MatchMode指定匹配的方式。MatchMode提供了四種匹配的方式:
摘要: 利用JavaMail的API可以快速的實(shí)現(xiàn)發(fā)送郵件的功能。下面是我使用的一個(gè)簡(jiǎn)單的實(shí)例,實(shí)現(xiàn)了簡(jiǎn)單的文本郵件的發(fā)送。
import java.io.*;import java.util.*;import javax.activation.*;import javax.mail.*;...
閱讀全文