<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-57  評論-202  文章-17  trackbacks-0
      2005年5月26日
    最近在弄swing,需要由JComponent生成BufferedImage,在CSDN上發現一個好例子。下面是范例:

    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
    posted @ 2006-04-14 23:41 小米 閱讀(1383) | 評論 (1)編輯 收藏
    ??????? 好久沒有寫blog了,距離上次寫幾乎已經是半年前的事情了。?這半年發生了不少事情。首先換了家公司,進了家金融企業,每天要西裝革履的,一開始還真是不習慣。?這里開發是用的spring框架,以后要多研究研究spring的東西了。
    ??????? 第二件事就是和戀愛了三年的女友結婚了,從此兩人長相廝守,不知道時間久了會不會審美疲勞。呵呵。
    ??????? 第三件事就是在深圳買了自己的小房子,雖然是小小的兩房,不過我們已經很知足了。?而且剛好是趕在房價大漲前買的,還算走了點運氣。換到現在,都不知道去哪里買好了。
    ??????? 在這里要向一些留言和發郵件給我的網友道歉,前段時間實在是太忙,沒有空回復你們的信息和郵件。請原諒!
    posted @ 2006-03-29 19:43 小米 閱讀(788) | 評論 (0)編輯 收藏
          最近真是多事情忙,而且可能要忙到9月底。好久沒有上來更新我的博客了,暫且發發牢騷。
    posted @ 2005-08-10 17:32 小米 閱讀(1184) | 評論 (1)編輯 收藏
          這一節是非常實用的一節,我在閱讀此書的時候,一直在迷惑,究竟應該怎樣管理Session呢?因為Session的管理是如此重要,類似于以前寫程序對JDBC Connection的管理。看完此節后,終于找到了方法。
          在各種Session管理方案中,ThreadLocal模式得到了大量使用。ThreadLocal是Java中一種較為特殊的線程綁定機制。通過ThreadLocal存取的數據,總是與當前線程相關,也就是說,JVM為每個運行的線程,綁定了私有的本定實例存取空間,從而為多線程環境經常出現的并發訪問問題提供了一種隔離機制。
          下面是Hibernate官方提供的一個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();

      
    /**
       * 根據當前線程獲取相應的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給相應的線程
       * @throws HibernateException
       
    */

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


    }


          針對WEB程序,還可以利用Servlet2.3的Filter機制,輕松實現線程生命周期內的Session管理。下面是一個通過Filter進行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);
            }

          }

        }

      }

      
    }
    posted @ 2005-07-29 19:43 小米 閱讀(3938) | 評論 (1)編輯 收藏
          數據分頁顯示,是很多B/S系統會遇到的問題。現在大多數主流數據庫都提供了數據部分讀取機制,而對于某些沒有提供相應機制的數據而言,Hibernate也通過其它途徑實現了分頁,如通過Scrollable ResultSet,如果JDBC不支持Scrollable ResultSet,Hibernate也會自動通過ResultSet的next方法進行記錄定位。Hibernate的Criteria、Query等接口提供了一致的方法設定分頁范圍。下面是書中的例子:

    Criteria criteria = session.createCriteria(TUser.class);
    Criteria.add(Expression.eq(
    "age""20"));
    //從檢索結果中獲取第100條記錄開始的20條記錄
    criteria.setFirstResult(100);
    criteria.setFetchSize(
    20);

          不過,我在測試的時候總是不能夠正常工作,把setFetchSize方法換成setMaxResults方法才行。換成最新的mysql-connector-java-3.1.10-bin-g.jar驅動也是一樣。
    posted @ 2005-07-26 18:12 小米 閱讀(5554) | 評論 (4)編輯 收藏

          Hibernate通過Lifecycle、Validatable接口制定了實體對象CRUD過程中的回調方式。
          Lifecycle接口中的onSave、onUpdate、onDelete方法,如果返回true則意味著需要中止執行相應的操作過程。如果代碼運行期間拋出了CallbackException,對應的操作也會被中止。注意,不要試圖在這些方法中調用Session進行持久化操作,這些方法中Session無法正常使用。
          Validatable.validate方法將在實體被持久化之前得到調用以對數據進行驗證。此方法在實體對象的生命周期內可能被數次調用,因此,此方法僅用于數據本身的邏輯校驗,而不要試圖在此實現業務邏輯的驗證。



          Hibernate還引入了Interceptor,為持久化事件的捕獲和處理提供了一個非侵略性的實現。Interceptor接口定義了Hibernate中的通用攔截機制。Session創建時即可指定加載相應的Interceptor,之后,此Session的持久化操作動作都將首先經由此攔截器捕獲處理。簡單的加載范例如下:

    SessionFactory factory = config.buildSessionFactory();
    Interceptor it 
    = new MyInterceptor();
    session 
    = sessionFactory.openSession(it);

          需要注意的是,與Lifecycle相同,Interceptor的方法中不可通過Session實例進行持久化操作。
    posted @ 2005-07-21 18:35 小米 閱讀(3364) | 評論 (1)編輯 收藏
          有興趣的可以去參加看看,網址:http://www.javachina.cn/Index.jsp
    posted @ 2005-07-20 14:55 小米 閱讀(1023) | 評論 (2)編輯 收藏

          最近真是忙,事情都擠到一塊去了。 終于有時間又看了幾頁書。
          言歸正傳,Hibernate中的Collection類型分為有序集和無序集兩類。這里所謂的有序和無序,是針對Hibernate數據持久過程中,是否保持數據集合中的記錄排列順序加以區分的。無序集有Set,Bag,Map幾種,有序集有List一種。有序集的數據在持久化過程中,會將集合中元素排列的先后順序同時固化到數據庫中,讀取時也會返回一個具備同樣排列順序的數據集合。
          Hibernate中的Collection類型是用的自己的實現,所以在程序中,不能夠把接口強制轉化成相應的JDK Collection的實現。



          結果集的排序有兩種方式:
          1. Sort
             Collection中的數據排序。
          2. order-by
             對數據庫執行Select SQL時,由order by子句實現的數據排序方式。

          需要注意的是,order-by特性在實現中借助了JDK 1.4中的新增集合類LinkedHashSet以及LinkedHashMap。因此,order-by特性只支持在1.4版本以上的JDK中運行。

    posted @ 2005-07-20 10:56 小米 閱讀(3943) | 評論 (0)編輯 收藏
          Session.get/load的區別:
          1.如果未能發現符合條件的記錄,get方法返回null,而load方法會拋出一個ObejctNotFoundException。
          2.Load方法可返回實體的代理類類型,而get方法永遠直接返回實體類。
          3.Load方法可以充分利用內部緩存和二級緩存中現有數據,而get方法則僅僅在內部緩存中進行數據查找,如沒有發現對應數據,將越過二級緩存,直接調用SQL完成數據讀取。



          Session.find/iterate的區別:
          find方法將執行Select SQL從數據庫中獲得所有符合條件的記錄并構造相應的實體對象,實體對象構建完畢之后,就將其納入緩存。它對緩存只寫不讀,因此無法利用緩存。
          iterate方法首先執行一條Select SQL以獲得所有符合查詢條件的數據id,隨即,iterate方法首先在本地緩存中根據id查找對應的實體對象是否存在,如果緩存中已經存在對應的數據,則直接以此數據對象作為查詢結果,如果沒有找到,再執行相應的Select語句獲得對應的庫表記錄(iterate方法如果執行了數據庫讀取操作并構建了完整的數據對象,也會將其查詢結果納入緩存)。



          Query Cache產生作用的情況:
          1.完全相同的Select SQL重復執行。
          2.在兩次查詢之間,此Select SQL對應的庫表沒有發生過改變。



          Session.save方法的執行步驟:
          1.在Session內部緩存中尋找待保存對象。內部緩存命中,則認為此數據已經保存(執行過insert操作),實體對象已經處于Persistent狀態,直接返回。
          2.如果實體類實現了lifecycle接口,則調用待保存對象的onSave方法。
          3.如果實體類實現了validatable接口,則調用其validate()方法。
          4.調用對應攔截器的Interceptor.onSave方法(如果有的話)。
          5.構造Insert SQL,并加以執行。
          6.記錄插入成功,user.id屬性被設定為insert操作返回的新記錄id值。
          7.將user對象放入內部緩存。
          8.最后,如果存在級聯關系,對級聯關系進行遞歸處理。



          Session.update方法的執行步驟:
          1.根據待更新實體對象的Key,在當前session的內部緩存中進行查找,如果發現,則認為當前實體對象已經處于Persistent狀態,返回。
          2.初始化實體對象的狀態信息(作為之后臟數據檢查的依據),并將其納入內部緩存。注意這里Session.update方法本身并沒有發送Update SQL完成數據更新操作,Update SQL將在之后的Session.flush方法中執行(Transaction.commit在真正提交數據庫事務之前會調用Session.flush)。


          Session.saveOrUpdate方法的執行步驟:
          1.首先在Session內部緩存中進行查找,如果發現則直接返回。
          2.執行實體類對應的Interceptor.isUnsaved方法(如果有的話),判斷對象是否為未保存狀態。
          3.根據unsaved-value判斷對象是否處于未保存狀態。
          4.如果對象未保存(Transient狀態),則調用save方法保存對象。
          5.如果對象為已保存(Detached狀態),調用update方法將對象與Session重新關聯。

    posted @ 2005-07-12 18:49 小米 閱讀(4900) | 評論 (5)編輯 收藏
          事務的4個基本特性(ACID):
          1. Atomic(原子性):事務中包含的操作被看作一個邏輯單元,這個邏輯單元中的操作要么全部成功,要么全部失敗。
          2. Consistency(一致性):只有合法的數據可以被寫入數據庫,否則事務應該將其回滾到最初狀態。
          3. Isolation(隔離性):事務允許多個用戶對同一個數據的并發訪問,而不破壞數據的正確性和完整性。同時,并行事務的修改必須與其他并行事務的修改相互獨立。
          4. Durability(持久性):事務結束后,事務處理的結果必須能夠得到固化。

          數據庫操作過程中可能出現的3種不確定情況:
          1. 臟讀取(Dirty Reads):一個事務讀取了另一個并行事務未提交的數據。
          2. 不可重復讀取(Non-repeatable Reads):一個事務再次讀取之前的數據時,得到的數據不一致,被另一個已提交的事務修改。
          3. 虛讀(Phantom Reads):一個事務重新執行一個查詢,返回的記錄中包含了因為其他最近提交的事務而產生的新記錄。

          標準SQL規范中,為了避免上面3種情況的出現,定義了4個事務隔離等級:
          1. Read Uncommitted:最低等級的事務隔離,僅僅保證了讀取過程中不會讀取到非法數據。上訴3種不確定情況均有可能發生。
          2. Read Committed:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”。該級別適用于大多數系統。
          3. Repeatable Read:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據。避免了“臟讀取”和“不可重復讀取”的情況,但是帶來了更多的性能損失。
          4. Serializable:最高等級的事務隔離,上面3種不確定情況都將被規避。這個級別將模擬事務的串行執行。

          Hibernate將事務管理委托給底層的JDBC或者JTA,默認是基于JDBC Transaction的。
          Hibernate支持“悲觀鎖(Pessimistic Locking)”和“樂觀鎖(Optimistic Locking)”。
          悲觀鎖對數據被外界修改持保守態度,因此,在整個數據處理過程中,將數據處于鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制。Hibernate通過使用數據庫的for update子句實現了悲觀鎖機制。Hibernate的加鎖模式有:
          1. LockMode.NONE:無鎖機制
          2. LockMode.WRITE:Hibernate在Insert和Update記錄的時候會自動獲取
          3. LockMode.READ:Hibernate在讀取記錄的時候會自動獲取
          4. LockMode.UPGRADE:利用數據庫的for update子句加鎖
          5. LockMode.UPGRADE_NOWAIT:Oracle的特定實現,利用Oracle的for update nowait子句實現加鎖
          樂觀鎖大多是基于數據版本(Version)記錄機制實現。Hibernate在其數據訪問引擎中內置了樂觀鎖實現,可以通過class描述符的optimistic-lock屬性結合version描述符指定。optimistic-lock屬性有如下可選取值:
          1. none:無樂觀鎖
          2. version:通過版本機制實現樂觀鎖
          3. dirty:通過檢查發生變動過的屬性實現樂觀鎖
          4. all:通過檢查所有屬性實現樂觀鎖
    posted @ 2005-07-08 16:19 小米 閱讀(4850) | 評論 (4)編輯 收藏

          現在搜狐新聞上報道已經有700多人傷亡,這是自從911事件以后最大的一次恐怖襲擊了。現在這個世界,是越來越不太平了,貧富差距的加大使得恐怖活動有生存的土壤。
          不知道世界的經濟會不會隨著這次恐怖襲擊而開始走向蕭條。現在的地球越來越像一個村,發生在任何一個角落的事情,都有可能會影響到每一個人。

    posted @ 2005-07-08 10:50 小米 閱讀(657) | 評論 (0)編輯 收藏
          昨晚偶然看見國際臺播放星戰的作者喬治盧卡斯榮獲AFI終身成就獎的頒獎典禮,耐心的看完了整個頒獎典禮。喬治在發表致詞的時候,說自己很高興能夠從事自己喜歡的電影工作,如果不拍攝電影,都不知道自己還能夠做什么。拍電影已經成了喬治生命的一部分。
          看到熒屏上全世界的老人,中年人,年輕人,孩子說著:“Thank you! George.”可以看到喬治的眼睛朦朧。我心中真是感慨,每個人都有自己的夢想,能夠從事自己喜歡的事情,確實是很開心的一件事。而自己所做的工作,能夠給自己帶來快樂,能夠給人們帶來快樂,這樣的工作才值得用一生的時間去從事。
          每一個登山者都有著自己心目中最想登上的山頂,能夠登上這個山頂,前面付出的艱辛都是值得的。人生不也如此么?找到自己喜歡從事的事情,用自己畢生的精力去做這件事。
    posted @ 2005-07-07 12:00 小米 閱讀(662) | 評論 (0)編輯 收藏
    獻出一份愛心 共同援助重病程序員王俊
    (2005.06.27)   來自:BJUG  
     

    向IT界倡議:援助程序員王俊行動

    王俊,今年27歲,北京北方銀證公司項目經理,是北京Java用戶組(BJUG,
    員(http://forum.javaeye.com/profile.php?mode=viewprofile&u=33)。一個年輕
    人,有感興趣的工作,不錯的前途,還有一群可以隨時交流技術的朋友,生活看起來平
    淡卻充實。

    業余時間,王俊經常還利用blog(http://befresh.blogbus.com)寫下自己生活和工作
    中的酸甜苦辣,此外他還有一個并不富裕但卻很溫馨的家。

    然而從今年二月份起,王俊的blog就再也沒有更新過了,他也沒有在BJUG的聚會和
    javaeye出現了,所有人都以為他出差去了。直到最近,驚聞他要換骨髓,才知道今年
    年初,王俊被查出患有“骨髓增生異常綜合癥”。

    骨髓增生異常綜合征目前認為是造血干細胞增殖分化異常所致的造血功能障礙。主要表
    現為外周血全血細胞減少,骨髓細胞增生,成熟和幼稚細胞有形態異常即病態造血。部
    分患者在經歷一定時期的MDS后轉化成為急性白血病;部分因感染、出血或其他原因死
    亡,病程中始終不轉化為急性白血病。

    這種病目前最有效的治療手段是換骨髓。萬幸的是,王俊的妹妹和他的骨髓配型一致,
    免疫系統的疾病發現治療的越早,就越可能成功,他目前的身體狀況還好,只要能更換
    骨髓,完全可以康復!但讓他們一家望而卻步的是,僅手術押金就需要20萬,全部療程
    視治療效果可能需要30-100萬。

    王俊的家在浙江杭州千島湖,父母都是農民,已然老邁且沒有固定的經濟收入,姐姐在
    當地出嫁,收入頗低,妹妹目前在北京讀成人教育并在公司打工。王俊是家庭經濟主要
    來源,他的病不僅掐斷了家里唯一的經濟來源,還要花上對他們而言是天文數字的錢來
    治病。

    "文章千古事,得失寸心知",這是王俊blog上的座右銘。細細翻看這個典型程序員的
    blog,就和他的人一樣樸實無華,在那里滿眼看到的都是對技術的孜孜追求。誰能想到
    一個如此活躍的頭腦現在卻被病魔折磨著。

    生命是美好的,這世界每天都有若干悲劇發生,這次,大家每個人出一份力,這世界就
    會少一個悲劇,多一份美好,多一份歡笑。也許,你只是少吃一頓大餐,少買一瓶化妝
    品,少看一場演唱會,少買一件名牌服裝,少玩一個月的網絡游戲,少上一個月的網,
    但是你卻可以為一個家庭托起一份生的希望。

    *****

    聯系方式 
    郵件 help@bjug.org
    MSN  icecloud@sina.com 冰云(BJUG) 

    援助辦法:

    1 捐款
    帳號:
    工商銀行
    戶名 王俊
    帳號 0200 2008 0102 3428 807
    開戶行 工商銀行北京市西內所

    招商銀行
    戶名 王俊
    帳號 9555 5001 0200 2820
    開戶行 招商銀行 北京分行

    中國銀行
    戶名 王俊
    帳號 4021400-0188-001204-0
    開戶行 北京西直門支行

    國外匯款方式
    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 網上銀行
    工行請采用行內匯款->有收款帳號匯款
    招行請采用個人銀行專業版的同城轉帳/異地匯款,并選中:采用系統內快速匯款

    B 銀行匯款
    請抄錄上述帳號并到銀行填寫匯款單

    請在捐款后,發郵件至help@bjug.org,通知我們,以便統計核對捐款帳目。郵件中請說明以下信息:
     (1) 姓名,
    (2) id/網站,
    (3) 發出銀行/發出帳號,
    (4) 金額,
    (5) 時間

    2 幫助宣傳:

    • 請到http://befresh.bjug.org 留下你對他的祝福
    • 請在MSN上修改您的名字,我們都寫上 [祝福后山]
    • 請修改您MSN的頭像為我們提供的圖標
    • 增加行動網站的地址 http://befresh.bjug.org 到MSN名字后面的個人信息
    • 請看到此文的Blogger,在您的blog上link此文,并Trackback到后山的blog
    • 請看到此信息的人,幫助一起宣傳,我們需要您的幫助
    • 在您的BLOG或網站,加上用我們提供的LOGO,并連接到網站http://befresh.bjug.org
    • 泡論壇的,請修改你的論壇LOGO和簽名檔為提供的圖標

     

    *****

    聯合發起:
    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/

    posted @ 2005-07-04 18:48 小米 閱讀(1706) | 評論 (22)編輯 收藏
         摘要:       要將BufferedImage實例保存為BMP文件,就需要知道BMP文件的格式,可以參考我轉載的文章:《BMP文件格式》。      下面是我的將BufferedImage實例保存為24位色BMP文件的實現。     ...  閱讀全文
    posted @ 2005-07-04 17:33 小米 閱讀(3432) | 評論 (6)編輯 收藏
          在公元2005年6月27日,我做出了一個重大的決定,買房!花了自己至今為止都沒有見過的那么多的錢買了一個小小的2房2廳, 從此變成了“負翁”。
          不過,從此以后再也不用去租房,再也不用幫別人供房,再也不用一年搬一次家。深圳租房實在太貴,蓮花北的一個小小的二房都要1800,有點裝修就叫豪華裝修,就是一個空蕩蕩的房子也開口要1500,太夸張了。住農民房又極度不安全,不想拿自己的生命開玩笑。
          從此就變成月供一族了,,不過,有了壓力才有動力。為了自己的將來,自己的理想,努力奮斗!
          9月26日是入伙的日子,好期待那天的到來啊。
    posted @ 2005-06-29 09:47 小米 閱讀(918) | 評論 (9)編輯 收藏
          一般而言,ORM的數據緩存應包含如下幾個層次:
          1. 事務級緩存(Transcation Layer Cache)
          2. 應用級/進程級緩存(Application/Process Layer Cache)
          3. 分布式緩存(Cluster Layer Cache)

          Hibernate數據緩存(Cache)分為兩個層次,以Hibernate語義加以區分,可分為:
          1. 內部緩存(Session Level,也稱為一級緩存)
          2. 二級緩存(SessionFactory Level,也稱為二級緩存)

          Hibernate中,緩存將在以下情況中發揮作用:
          1. 通過id[主鍵]加載數據時
          2. 延遲加載

          內部緩存正常情況下由Hibernate自動維護,如果需要手動干預,可以通過以下方法完成:
          1. Session.evict
             將某個特定對象從內部緩存清除。
          2. Session.clear
             清空內部緩存。

          在Hibernate中,二級緩存涵蓋了應用級緩存和分布式緩存領域。如果數據滿足以下條件,則可將其納入緩存管理。
          1. 數據不會被第三方應用修改;
          2. 數據大小(Data Size)在可接收的范圍之內;
          3. 數據更新頻率較低;
          4. 同一數據可能會被系統頻繁引用;
          5. 非關鍵數據(關鍵數據,如金融帳戶數據)。
          Hibernate本身并未提供二級緩存的產品化實現,而是為眾多的第三方緩存組件提供了接入接口,較常用的第三方組件有:
          1. JCS
          2. EHCache
          3. OSCache
          4. JBossCache
          5. SwarmCache
          Hibernate中啟用二級緩存,需要在hibernate.cfg.xml配置hibernate.cache.provider_class參數,之后,需要在映射文件中指定各個映射實體(以及collection)的緩存同步策略。Hibernate提供了一下4種內置的緩存同步策略:
          1. read-only
             只讀。對于不會發生改變的數據,可使用只讀型緩存。
          2. nonstrict-read-write
             如果程序對并發訪問下的數據同步要求不是非常嚴格,且數據更新操作頻率較低,可以采用本選項,獲得較好的性能。
          3. read-write
             嚴格可讀寫緩存。基于時間戳判定機制,實現了“read committed”事務隔離等級。可用于對數據同步要求嚴格的情況,但不支持分布式緩存。這也是實際應用中使用最多的同步策略。
          4. transactional
             事務型緩存,必須運行在JTA事務環境中。
    posted @ 2005-06-22 18:15 小米 閱讀(6107) | 評論 (5)編輯 收藏

          在Java語言中,對象之間的比較可以通過引用比較(==)和內容比較(equals)兩種方式進行,而在Hibernate的實體對象的比較是通過主鍵值來比較,如果要實現自己的識別邏輯,則需要重寫equals方法和hashCode方法。

          檢查數據對象改變檢查的一般策略有下面兩種:
          1. 數據對象監控
             數據對象監控的實現方式,通過攔截器對數據對象的設值方法進行攔截。一旦數據對象的設置方法被調用,則將其標志為“待更新”狀態,之后在數據庫操作時將其更新到對應的庫表。
          2. 數據版本對比
             在持久層框架中維持數據對象的最近讀取版本,當數據提交時將提交數據與此版本進行比對,如果發生變化則將其同步到數據庫對應的庫表。

          Hibernate采取的是第二種檢查策略。它采用一個內部數據結構"EntityEntry"保存對應實體類的狀態信息。

          對于級聯對象的更新,Hibernate將根據unsaved-value進行判定。首先Hibernate會取出目標對象的id。之后,將此值與unsaved-value進行比對,如果相等,則認為目標對象尚未保存,否則,認為對象已經保存,無需再進行保存操作。

    posted @ 2005-06-22 16:32 小米 閱讀(5158) | 評論 (4)編輯 收藏
          最近正在研讀《深入淺出Hibernate》一書,前面寫的隨筆有些也是讀該書的筆記,只是未做歸類,從這篇開始,我將把相關的內容都整理成一個系列的讀書筆記。
          今天這篇是有關實體對象的生命周期。我剛開始接觸Hibernate的時候,只是簡單的把它當做一個API工具,直到后來看到有關VO和PO的內容時,才意識到Hibernate不僅僅是一個O/R Mapping的API工具,它還是一個容器。它可以幫你管理實體對象的生命周期。

          實體對象的生命周期有三種狀態:
          1.Transient(自由狀態)
          此時的實體對象和數據庫中的記錄無關聯,只是一個普通的JavaBean。
          2.Persistent(持久狀態)
          此時的實體對象和數據庫中的記錄有關聯,其變更將由Hibernate固化到數據庫中。該實體對象處于由Hibernate框架所管理的狀態。
          3.Detached(游離狀態)
          處于Persistent狀態的對象,其對應的Session實例關閉之后,那么,此對象就處于"Detached"狀態。Detached狀態和Transient狀態的區別在于Detached狀態的對象可以再次與某個Session實例相關聯而成為Persistent對象。

          從實體對象是否被納入Hibernate實體管理容器的角度,Transient和Detached狀態的實體對象可以統稱為VO(Value Object),而被管理的實體對象稱為PO(Persistent Object)。兩者的區別:
          1.VO是相對獨立的實體對象,處于非管理狀態。
          2.PO是Hibernate納入其實體管理容器(Entity Map)的對象,它代表了與數據庫中某條記錄對應的Hibernate實體,PO的變化在事務提交時將反映到實際數據庫中。
          3.如果一個PO與其對應的Session實例分離,那么此時,它又會變成一個VO。

          下圖是我畫的實體對象生命周期的狀態轉換圖:

    vopolife.JPG
    posted @ 2005-06-16 18:31 小米 閱讀(3080) | 評論 (9)編輯 收藏
          在使用HQL查詢中,有時并不需要獲取完整的一個實體對象,例如一個實體對象User有三個屬性: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]);
        }

          這時調用Query類的list方法返回的將是一個每個元素都是一個Object數組的List。如果只獲取一個屬性,那么返回的List中的每個元素都是String實例。

          2.在HQL中用new操作符生成實體對象,例如:"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());
        }

          這時list方法返回的List中的每一個元素都是User實體對象。這里有三點需要注意的:
          a.在HQL語句中需要使用as操作符指定User的別名,并且需要在構造函數的屬性前面加上別名;
          b.HQL語句中的構造函數在User類中必須要有相應的構造函數;
          c.生成的實體對象是VO對象,如果對這些對象調用Session的saveOrUpdate方法將導致插入新的記錄,而不是更新記錄。
    posted @ 2005-06-15 16:33 小米 閱讀(2998) | 評論 (0)編輯 收藏
          JBuilder 2005中多了一個Smart MemberInsight功能,這個功能會智能的匹配需要調用的方法或者獲取的屬性。例如有一個賦值操作,左邊是一個List,右邊是用一個方法獲取值,那么當輸入"."時,JBuilder 2005會自動的找到所有返回的值為List的方法。
          不過,這實在是一個不怎么討好的方法。因為很多時候并不是只有一層方法調用的,例如,當需要用一個方法獲取一個實例,然后再用這個實例的方法獲取需要的值時,這個功能就顯得很礙手了。
          終于,我還是決定關閉這個“智能”的功能。打開"Tools"——>"Preferences",在"Editor"的子項"CodeInsight"里,展開"MemberInsight",把"Default to Smart MemberInsight"這一項去掉。如下圖所示:

    memberinsight.JPG
    posted @ 2005-06-15 16:02 小米 閱讀(521) | 評論 (0)編輯 收藏
          這個范例說明如何用JFreeChart畫簡單的柱狀圖,下面是一個JSP的簡單范例:

    <%@ 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 = {85156179.5211123};
      
    //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, falsefalsefalse);
      chart.setBackgroundPaint(
    new Color(0xE1E1E1));
      
      CategoryPlot plot 
    = chart.getCategoryPlot();
      
      
    // 設置Y軸顯示整數
      NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
      rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
      
      CategoryAxis domainAxis 
    = plot.getDomainAxis();
      
    //設置距離圖片左端距離
      domainAxis.setLowerMargin(0.05);
      
      BarRenderer3D renderer 
    = new BarRenderer3D();
      
    //設置柱的顏色
      renderer.setSeriesPaint(0new Color(0xff00));
      plot.setRenderer(renderer);
      
      String filename 
    = ServletUtilities.saveChartAsPNG(chart, 300280null, 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>


          畫出來的圖:

    displayChart.JPG

          和ChartDirector畫出來的圖做一個比較:

    threedbar.JPG

    posted @ 2005-06-14 18:40 小米 閱讀(10690) | 評論 (7)編輯 收藏
          以前一直是用JFreeChart畫統計圖的,不過JFreeChart畫出來的圖形不夠精細,看起來有些模糊,今天在網上看到另外一個工具ChartDirector,這是一個商業版本的工具,不過也可以免費使用,只是在畫出來的圖形下面都有一條它的廣告條。
          下面是它的一個柱狀圖的例子:

    threedbar.JPG
          范例程序:

    <%@page import="ChartDirector.*" %>
    <%
    //The data for the bar chart
    double[] data = {85156179.5211123};

    //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(300280);

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

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


          如果要在柱的頂部顯示數值,可以調用Layer的setDataLabelFormat方法設置,范例:layer.setDataLabelFormat("{value}");

          其它的例子可以參考它的文檔的說明。ChartDirector的網址:http://www.advsofteng.com

    posted @ 2005-06-14 17:46 小米 閱讀(5246) | 評論 (5)編輯 收藏
          如果要在程序中定時執行任務,可以使用java.util.Timer這個類實現。使用Timer類需要一個繼承了java.util.TimerTask的類。TimerTask是一個虛類,需要實現它的run方法,實際上是他implements了Runnable接口,而把run方法留給子類實現。
          下面是我的一個例子:

    class Worker extends TimerTask {
      
    public void run() {
        System.
    out.println("我在工作啦!");
      }

    }

          Timer類用schedule方法或者scheduleAtFixedRate方法啟動定時執行,schedule重載了四個版本,scheduleAtFixedRate重載了兩個。每個方法的實現都不同,下面是每個方法的說明:

    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.
    說明:該方法會在設定的延時后執行一次任務。

    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.
    說明:該方法會在指定的時間點執行一次任務。

    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.
    說明:該方法會在指定的延時后執行任務,并且在設定的周期定時執行任務。

    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.
    說明:該方法會在指定的時間點執行任務,然后從該時間點開始,在設定的周期定時執行任務。特別的,如果設定的時間點在當前時間之前,任務會被馬上執行,然后開始按照設定的周期定時執行任務。

    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的相同參數的版本類似,不同的是,如果該任務因為某些原因(例如垃圾收集)而延遲執行,那么接下來的任務會盡可能的快速執行,以趕上特定的時間點。

    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.
    說明:和上一個方法類似。

          下面是我的一個測試片斷:

      public static void main(String[] args) throws Exception {
        Timer timer 
    = new Timer(false);
        timer.schedule(
    new Worker(), new Date(System.currentTimeMillis() + 1000));
      }
    posted @ 2005-06-09 10:29 小米 閱讀(33741) | 評論 (7)編輯 收藏

          今天得知,現在住的房子,公司要準備拍賣了,那就是說,我又要搬家了。 這將是我大學畢業后的第四次搬家了,每年搬一次家,有時候真的厭倦了這樣的生活,剛適應一個環境,又要重新去適應新的環境。好想擁有自己的房子,但是現在深圳的房價卻讓人望樓興嘆! 什么時候才能夠讓老百姓過上安居樂業的生活。
          《我想有個家》,潘美辰的這首老歌,現在最能夠代表我的心情了。

    posted @ 2005-06-06 21:49 小米 閱讀(548) | 評論 (4)編輯 收藏
          Criteria Query是很好的一種面向對象的查詢實現,它提供了一種示例查詢的方式。該方式根據已有的對象,查找數據庫中屬性匹配的其他對象。
          下面是一個場景片斷,模糊查找數據庫中用戶帳號為'test',郵件地址為'georgehill@21cn.com'的實例,忽略大小寫。

      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實例,可以通過Example的靜態方法create生成。Example類有下面的幾個方法指定查詢的方式:

    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



          當用enableLike()方法時,可以通過MatchMode指定匹配的方式。MatchMode提供了四種匹配的方式:

    Field Summary
    static MatchMode ANYWHERE
              Match the pattern anywhere in the string
    static MatchMode END
              Match the end of the string to the pattern
    static MatchMode EXACT
              Match the entire string to the pattern
    static MatchMode START
              Match the start of the string to the pattern
    posted @ 2005-06-03 17:27 小米 閱讀(2186) | 評論 (3)編輯 收藏
         摘要:       利用JavaMail的API可以快速的實現發送郵件的功能。下面是我使用的一個簡單的實例,實現了簡單的文本郵件的發送。 import java.io.*;import java.util.*;import javax.activation.*;import javax.mail.*;...  閱讀全文
    posted @ 2005-06-02 16:30 小米 閱讀(2214) | 評論 (7)編輯 收藏
          好懷念以前可以過六一兒童節的時候,可以放假,學校還會組織活動,每到這天,都可以名正言順的出去玩。呵呵。現在可沒有六一兒童節過了。
    posted @ 2005-06-01 16:29 小米 閱讀(440) | 評論 (0)編輯 收藏
          上個月過了理論考試,昨天終于第一次開起了汽車。呵呵,一開始好緊張啊,給師傅狂罵。有兩次還差點撞到墻。后來熟悉了后,就好了很多了。呵呵,第一天學會了怎么啟動,停車,打檔和轉方向盤。上手還是很快滴!不過,想起要上路,我就感覺恐怖。
    posted @ 2005-05-26 10:21 小米 閱讀(481) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 最好免费观看韩国+日本| 亚洲欧美国产欧美色欲| 四虎永久精品免费观看| 日韩免费在线视频| 无套内射无矿码免费看黄| 亚洲黄页网在线观看| 久久久亚洲欧洲日产国码农村| 国产在线ts人妖免费视频| 免费看美女裸露无档网站| 永久免费不卡在线观看黄网站| 国产成人综合亚洲一区| 亚洲中文字幕久久精品无码VA| 亚洲精品影院久久久久久| 久久亚洲高清观看| 亚洲精品乱码久久久久久自慰| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 亚洲日韩国产一区二区三区| 成人免费视频观看无遮挡| 亚洲免费在线观看视频| 外国成人网在线观看免费视频| 久青草视频97国内免费影视| 免费人成在线观看播放a| 欧美激情综合亚洲一二区| 亚洲国产系列一区二区三区| 亚洲香蕉在线观看| 亚洲午夜电影在线观看| 亚洲日韩中文字幕| 亚洲欧洲日产国码二区首页| 亚洲黄色在线观看网站| 亚洲AV无码日韩AV无码导航| 亚洲女久久久噜噜噜熟女| 亚洲色婷婷综合久久| 国产偷v国产偷v亚洲高清| 亚洲国产精品福利片在线观看| 亚洲国产精品无码久久久不卡| 久久久久久久尹人综合网亚洲| 亚洲AV无码不卡在线播放| 国产亚洲欧洲精品| 亚洲国产香蕉碰碰人人| 亚洲高清在线mv| 亚洲已满18点击进入在线观看|