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

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

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

    風雨無阻

    2008年3月12日

    Jvm工作原理學習筆記

    class loader 加載 class file 到內存
    jvm內存包括: method area(存放class name, class path , 類修飾符等信息), java stack(每一個線程單獨有個stack),java heap(存放對象的數據,數組數據等,被所有線程共享的), pc寄存器(每一個線程單獨有個pc寄存器,用于存放下一步指令),本地方法棧。

    java 堆 可 分為三部分:Perm,Tenured,Yong區。可以通過參數來配置空間大小:

    -Xms :指定了JVM初始啟動以后初始化內存

    -Xmx:指定JVM堆得最大內存,在JVM啟動以后,會分配-Xmx參數指定大小的內存給JVM,但是不一定全部使用,JVM會根據-Xms參數來調節真正用于JVM的內存

     Perm Generation

    -XX:PermSize=16M -XX:MaxPermSize=64M

    posted @ 2014-02-10 18:01 秋楓故事 閱讀(249) | 評論 (0)編輯 收藏

    Ajax Post提交

    jQuery.post( url, [data], [callback], [type] ) :使用POST方式來進行異步請求


    參數:

    url (String) : 發送請求的URL地址.

    data (Map) : (可選) 要發送給服務器的數據,以 Key/value 的鍵值對形式表示。

    callback (Function) : (可選) 載入成功時回調函數(只有當Response的返回狀態是success才是調用該方法)。

    type (String) : (可選)官方的說明是:Type of data to be sent。其實應該為客戶端請求的類型(JSON,XML,等等)

    這是一個簡單的 POST 請求功能以取代復雜 $.ajax 。請求成功時可調用回調函數。如果需要在出錯時執行函數,請

    使用 $.ajax。示例代碼:

     var con = $('#content').val();//待提交的數據

        $.post("checkContent.action",{"mess.content":con},
        function (data){
      
       if(data != "")//有非法敏感字
        {  
         alert(data);
         $('#content').focus();
        }
      },"html");


    點擊提交:

    posted @ 2009-09-03 14:42 秋楓故事 閱讀(3117) | 評論 (4)編輯 收藏

    xmlns:XML命名空間

    以下轉載自:
    http://hi.baidu.com/tianhesj/blog/item/0dd9718d32be4011b21bbacc.html

    Namespaces翻譯為命名空間。命名空間有什么作用呢?當我們在一個XML文檔中使用他人的或者多個DTD文件,就會出現這樣的矛盾:因為XML中標識都是自己創建的,在不同的DTD文件中,標識名可能相同但表示的含義不同,這就可能引起數據混亂。
    比如在一個文檔<table>wood table</table>中<table>表示桌子,
    而在另一個文檔<table>namelist</table>中<table>表示表格。如果我需要同時處理這兩個文檔,就會發生名字沖突。
    了解決這個問題,我們引進了namespaces這個概念。namespaces通過給標識名稱加一個網址(URL)定位的方法來區別這些名稱相同的標識。
    Namespaces同樣需要在XML文檔的開頭部分聲明,聲明的語法如下:
    <document xmlns:yourname='URL'>
    其中yourname是由你定義的namespaces的名稱,URL就是名字空間的網址。
    假設上面的"桌子<table>"文檔來自http://www.zhuozi.com,我們就可以聲明為
    <document xmlns:zhuozi='http://www.zhuozi.com'>;
    然后在后面的標識中使用定義好的名字空間:
    <zhuozi:table>wood table</table>
    這樣就將這兩個<table>區分開來。注意的是:設置URL并不是說這個標識真的要到那個網址去讀取,僅僅作為一種區別的標志而已。


    命名沖突
    因為XML文檔中使用的元素不是固定的,那么兩個不同的XML文檔使用同一個名字來描述不同類型的元素的情況就可能發生。而這種情況又往往會導致命名沖突。請看下面兩個例子

    這個 XML 文檔在table元素中攜帶了水果的信息:

    <table>
    <tr>
    <td>Apples</td>
    <td>Bananas</td>
    </tr>
    </table>
    這個 XML 文檔在table元素中攜帶了桌子的信息(家具,不能吃的哦):

    <table>
    <name>African Coffee Table</name>
    <width>80</width>
    <length>120</length>
    </table>

    如果上面兩個XML文檔片斷碰巧在一起使用的話,那么將會出現命名沖突的情況。因為這兩個片斷都包含了<table>元素,而這兩個table元素的定義與所包含的內容又各不相同。


    --------------------------------------------------------------------------------

    使用前綴解決命名沖突問題
    下面的XML文檔在table元素中攜帶了信息:

    <h:table>
    <h:tr>
    <h:td>Apples</h:td>
    <h:td>Bananas</h:td>
    </h:tr>
    </h:table>

    下面的XML文檔攜帶了家具table的信息:

    <f:table>
    <f:name>African Coffee Table</f:name>
    <f:width>80</f:width>
    <f:length>120</f:length>
    </f:table>

    現在已經沒有元素命名沖突的問題了,因為這兩個文檔對各自的table元素使用了不同的前綴,table元素在兩個文檔中分別是(<h:table> 和<f:table>)。

    通過使用前綴,我們創建了兩個不同的table元素。


    --------------------------------------------------------------------------------

    使用命名空間
    下面的XML文檔在table元素中攜帶了信息:

    <h:table xmlns:h="http://www.w3.org/TR/html4/">
    <h:tr>
    <h:td>Apples</h:td>
    <h:td>Bananas</h:td>
    </h:tr>
    </h:table>

    下面的XML文檔攜帶了家具table的信息:

    <f:table xmlns:f="http://www.w3schools.com/furniture">
    <f:name>African Coffee Table</f:name>
    <f:width>80</f:width>
    <f:length>120</f:length>
    </f:table>

    在上面兩個例子中除了使用前綴外,兩個table元素都使用了xmlns屬性,使元素和不同的命名空間關聯到一起。


    --------------------------------------------------------------------------------

    命名空間屬性
    命名空間屬性一般放置在元素的開始標記處,其使用語法如下所示:

    xmlns:namespace-prefix="namespace"

    在上面的例子中,命名空間定義了一個Internet 地址:

    xmlns:f="http://www.w3schools.com/furniture"

    W3C 命名規范聲明命名空間本身就是一個統一資源標示符,Uniform Resource Identifier (URI)。

    當我們在元素的開始標記處使用命名空間時,該元素所有的子元素都將通過一個前綴與同一個命名空間相互關聯。

    注意:用來標識命名空間的網絡地址并不被XML解析器調用,XML解析器不需要從這個網絡地址中查找信息,該網絡地址的作用僅僅是給命名空間一個唯一的名字,因此這個網絡地址也可以是虛擬的,然而又很多公司經常把這個網絡地址值象一個真實的Web頁面,這個地址包含了關于當前命名空間更詳細的信息。
    可以訪問http://www.w3.org/TR/html4/.


    --------------------------------------------------------------------------------

    統一資源標識符
    通用資源標識符(A Uniform Resource Identifier (URI))是一個標識網絡資源的字符串。最普通的URI應該是統一資源定位符Uniform Resource Locator (URL)。URL用于標識網絡主機的地址。另一方面,另一個不常用的URI是通用資源名字Universal Resource Name (URN)。在我們的例子中,一般使用的是URLs。

    既然前面的例子使用的URL地址來標識命名空間,我們可以確信這個命名空間是唯一的。


    --------------------------------------------------------------------------------

    默認的命名空間
    定義一個默認的XML命名空間使得我們在子元素的開始標記中不需要使用前綴。他的語法如下所示:

    <element xmlns="namespace">

    下面的XML文檔在table元素中包含了水果的信息:

    <table xmlns="http://www.w3.org/TR/html4/">
    <tr>
    <td>Apples</td>
    <td>Bananas</td>
    </tr>
    </table>

    下面的XML文檔包含了家具table的信息:

    <table xmlns="http://www.w3schools.com/furniture">
    <name>African Coffee Table</name>
    <width>80</width>
    <length>120</length>
    </table>

    --------------------------------------------------------------------------------

    使用命名空間
    檔開始使用XSL的時候,就會發現命名空間使用的是如此頻繁。XSL樣式單主要用于將XML文檔轉換成類似于HTML文件的格式。

    如果看一下下面的XSL文檔,就會發現有很多標記都是HTML標記。那些標記并不是HTML標記,是加了前綴的XSL,這個XSL前綴由命名空間"http://www.w3.org/TR/xsl"所標識:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/xsl">
    <xsl:template match="/">
    <html>
    <body>
    <table border="2" bgcolor="yellow">
    <tr>
    <th>Title</th>
    <th>Artist</th>
    </tr>
    <xsl:for-each select="CATALOG/CD">
    <tr>
    <td><xsl:value-of select="TITLE"/></td>
    <td><xsl:value-of select="ARTIST"/></td>
    </tr>
    </xsl:for-each>
    </table>
    </body>
    </html>
    </xsl:template>
    </xsl:stylesheet>


    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/yc_8301/archive/2008/11/19/3335738.aspx

    posted @ 2009-08-04 10:46 秋楓故事 閱讀(1323) | 評論 (0)編輯 收藏

    關于表單中的重置按鈕

    表單中有一個type=reset的button,可以將表單中的數據重置為初始表單的數據,但如果表單中有一些“單選”或“多選”框,其默認值是通過javascript腳本控制的;這種情況通過reset按鈕不會重置為初始狀態,所以不能簡單的調用reset自帶按鈕,解決方法:將重置按鈕設為普通按鈕,在onclick方法中,選調用form.reset()方法,然后再調用javascript腳本

    posted @ 2009-05-08 11:37 秋楓故事 閱讀(2520) | 評論 (1)編輯 收藏

    myeclipse連接oracle出現ora-12705錯誤的解決辦法

    我用的myeclipse 6.0版本,oracle是10g版本,在連接的時候出現了以下問題

     java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
    ORA-12705: Cannot access NLS data files or invalid environment specified

    一開始以為是驅動程序的問題,其實不是,只需在eclipse目錄下找到eclipse.ini文件,把

    Duser.language=en  改成 Duser.language=zh就行了。

    有可能大家出現的問題不一樣,按我的方法有可能不好使,我寫出來僅供大家參考,因為當時為解決這問題,花了不少時間,希望大家少走彎路

    posted @ 2009-04-28 17:40 秋楓故事 閱讀(205) | 評論 (0)編輯 收藏

    摘一部電影中的內容


        我有一把白色塑膠雨傘。買的時候喜歡它雪白可愛,瘦瘦長長,簡直像個鶴立雞群的美女。可惜這種美麗偏偏不耐看,風吹雨打久了,顏色變黃,還多了雀斑一樣的污跡。而且瘦長是沒用的,哪里像折傘這么善解人意。于是,我開始制造各種機會。 趁著下雨帶它出門,左擱一會兒,右放一下,希望一下子大意忘了拿,讓它自動消失,大家無痛分手。我就可以理直氣壯買一把新的,多好!
    失寵的人通常最敏感。 有一天,它突如其來消失了,完全不用花我任何心思。傘也有它的自尊。問題是,等一等,我還沒有準備好。不行,它不可以沒經我的同意就玩失蹤。我便一心一意要找它回來,花盡心思去想,到底在哪里弄丟的呢?書店,餐廳還是公共汽車地鐵呢?
    真是峰回路轉,沒想到在戲院把它找回來,小別重逢,它苦著副臉在等我來新發現。重拾舊歡,大團圓結局。 換一個角度來看,如果我失敗了,找不到它,它永遠消失了,淡淡的遺憾感覺,會不會更合我心意?
    人世間的破鏡重圓,大概都是一言難盡。

    posted @ 2009-04-23 09:15 秋楓故事 閱讀(210) | 評論 (0)編輯 收藏

    group by 。。。

     select t2.*,t3.ncount from 
    (select groupid, count(id) as ncount  from t_txlEmploy group by groupid) t3, t_txlgroup t2
    where  t2.id=t3.groupid(+)
    group by t2.id,t3.groupid

    構架一張t3表,字段為“集團編號”,“集團用戶數”

    然后用“集團表”和t3表再關聯

    posted @ 2009-04-22 16:37 秋楓故事 閱讀(235) | 評論 (0)編輯 收藏

    Spring獲取ApplicationContext的正確方式

    前兩天聯華對單系統頻頻出現out of memory的問題,經過層層分析,終于弄明白原來瓶頸出現在Spring獲取Bean那一步上。以前的做法是在delegate層ApplicationContext context = new ClassPathXmlApplicationContext("Compare.xml"); 這樣我把log4j的debug打開后發現,每做1步操作的時候系統都會重新加載這個xml,重新創建Bean的實例,重新獲取url-mapping,這無疑是個及其錯誤的方式。      研究后發現正確的使用方式是:      首先在web.xml里配置ApplicationContext      <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>/WEB-INF/applicationContext.xml</param-value>
         </context-param>     <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>     然后在Action中編寫如下代碼得到Context,(我是覆蓋了Struts Action的setServlet方法,也許還有更好的方法)。     public void setServlet(ActionServlet servlet){
             super.setServlet(servlet);
             ServletContext servletContext = servlet.getServletContext();
            WebApplicationContext wac =    WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
             // get yours beans     }     這樣在啟動服務時已經加載了xml中的配置,而不用每次都重新加載,大大提高了系統的效率

    posted @ 2009-04-17 16:45 秋楓故事 閱讀(1017) | 評論 (0)編輯 收藏

    suse硬盤安裝(網絡收集)

    事先,把你的硬盤劃出 10G左右的空閑空間!

    1.下載suse安裝光盤,準備好8G左右的空間,最好是ntfs格式的。現在有 10.1正式版和10.2的beta 2版,2006年12月7號,10.2就除正式版了!然后將五張光盤全部解壓,加壓到根目錄的一個文件夾下,比如X:\suse\

    2.找到解壓出的第一張光盤linux和initrd文件,放在根目錄下.

    32位的路徑應該是 x:\suse\SUSE-Linux-10.1-Remastered-x86_64-CD1\boot\i386\loader\

    64位的路徑是:X:\suse\SUSE-Linux-10.1-Remastered-x86_64-CD1\boot\x96_64\loader\

    3.下載Grub for dos。下載網址:http://download.it168.com/14/1411/33307/33307_4.shtml

    http://grub4dos.sourceforge.net

    4.將下載的grub for dos 解壓到C盤可能會提示覆蓋什么profile.sys文件,直接替換就行。

    5.改boot.ini文件,先把boot.ini文件的隱藏屬性給去掉!

    把boot.ini文件用記事本打開在最下添加這么一行

    C:\GRLDR="GRUB"

    然后保存,

    6.下一步就是重啟系統了,當要選擇要啟動的系統時,選擇grub,找到類似 commanderline ,按下enter,進入dos 提示符狀態下,

    輸入 find /linux 回車,此時會顯示

    hd(0,6)——(肯定會有不同,請看下面注釋

    kernel hd(0,6)/linux回車

    initrd hd(0,6)/initrd回車

    boot回車

    注釋:hd(0,6)   6是你的分區,根據你的分區不同,這個數字會不同,0表示是第一塊硬盤。)

    進入圖形界面,

    會提示類似 no cd in your cd drive的語句,不用管他,選擇back

    7.按照提示選擇,都是簡單的英語,完全可以搞定的(抄襲linuxsir.org幾位大俠的話。。呵呵)

    8.等到要你指定安裝文件的位置的時候,你把你剛才解壓的suse的幾張光盤的位置填進去就行了,然后回車,會提示選擇安裝語言,鍵盤鼠標什么的,按照提示選就ok了。大家安裝時候注意分區,不要采用它默認的分區方式,那樣的你的windows操作系統就會被它給刪掉了。

    再羅嗦一點,Suse的分區方式沒有fedora和ubuntu做的好,后面的兩個全部可以手動分區,而suse只有切換到專家模式下才能更改分區,剛開始,搞的我又點郁悶。

    等待安裝完成。。。。大約40 ~ 1個小時。不要著急!中間還要填root密碼和給機器命名,添加user等操作!

    9.安裝完成后,重啟,進入系統,user不用填密碼自動登錄系統(現在我還不知道怎么才能不讓它自動登錄)

    祝大家好運。。。。

    ——部分內容來自linuxsir.org,感謝Thruth大俠!

     

    posted @ 2008-11-25 13:51 秋楓故事 閱讀(441) | 評論 (0)編輯 收藏

    關于ORACLE中的DECODE

         摘要: 關于ORACLE中的DECODE- -                               ...  閱讀全文

    posted @ 2008-11-13 15:59 秋楓故事 閱讀(2928) | 評論 (0)編輯 收藏

    Spring MVC 入門(轉)

    如果你手上有一本《Spring in Action》, 那么你最好從第三部分"Spring 在 Web 層的應用--建立 Web 層"開始看, 否則那將是一場惡夢!

        首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 應用程序接收到 http://localhost:8088/hello.do(請求路徑為/hello.do) 的請求后, Spring 將這個請求交給一個名為 helloController 的程序進行處理, helloController 再調用 一個名為 hello.jsp 的 jsp 文件生成 HTML 代碼發給用戶的瀏覽器顯示. 上面的名稱(/hello.do, helloController, hello.jsp) 都是變量, 你可以更改.

        在 Spring MVC 中, jsp 文件中盡量不要有 Java 代碼, 只有 HTML 代碼和"迭代(forEach)"與"判斷(if)"兩個jstl標簽. jsp 文件只作為渲染(或稱為視圖 View)模板使用.

        好了, 我們開始吧. 首先我們需要一個放在 WEB-INF 目錄下的 web.xml 文件:

    web.xml:
     <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
     xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
     <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
       /WEB-INF/database.xml
       /WEB-INF/applicationContext.xml
      </param-value>
     </context-param>
     
     <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>
     
     <filter>
      <filter-name>EncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
      </init-param>
     </filter>
     
     <filter-mapping>
      <filter-name>EncodingFilter</filter-name>
      <url-pattern>*.do</url-pattern>
     </filter-mapping>
     
     <servlet>
      <servlet-name>test</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
     </servlet>
     
     <servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>*.do</url-pattern>
     </servlet-mapping>
     
     <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>index.html</welcome-file>
     </welcome-file-list>
     
     <jsp-config>
      <taglib>
       <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
       <taglib-location>/WEB-INF/c.tld</taglib-location>
      </taglib>
      <taglib>   
       <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
       <taglib-location>/WEB-INF/fmt.tld</taglib-location>
      </taglib>
     </jsp-config>
    </web-app>
    它配置了以下功能:
    • 配置 DispatcherServlet (servlet 標簽), 它是一個 Java Servlet 程序. 我們將它命名為 test. 然后我們再配置 Servlet 映射(test-mapping 標簽), 也就是你希望哪些請求被DispatcherServlet處理. 這里, 我們設置后綴名為 do(*.do) 的所有URL請求都被名為 test 的 DispatcherServlet 的程序處理. 選擇 .do 只是一個習慣,但是你不要選擇 .html! 雖然《Spring in Action》選擇了 .html, 但是那是一種非常糟糕的作法, 特別是你整合 ApacheTomcat 的時候.

    • 配置 CharacterEncodingFilter (filter 標簽), 否則你會發現中文亂碼. 因為我的 jsp 和 html 文件都是 UTF-8 編碼的, 所以我在 param-value 標簽中設置了 UTF-8. 估計你使用的是 GB2312 或者 GBK, 立即轉到 UTF-8 上來吧.

    • 分解配置文件. context-param 標簽指明我們的配置文件還有 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml. ContextLoaderListener(listener 標簽) 由此得知配置文件是哪些, 它會將它們載入.

    因為我們將 DispatcherServlet 命名為test, 所以我們在 WEB-INF 目錄下建立一個名為 test-servlet.xml 的文件:

    test-servlet.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/"/>
      <property name="suffix" value=".jsp"/>
     </bean>
     
     <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      <property name="mappings">
       <props>
        <prop key="/hello.do">helloController</prop>
       </props>
      </property>
     </bean>
     <bean id="helloController" class="com.ecnulxq.test.HelloController">
     </bean>
    </beans>
    它配置了以下功能:
    
    • 配置 InternalResourceViewResolver, 它是 jsp 渲染模板的處理器. 如果你告訴 InternalResourceViewResolver 處理一個名為 hello 的模板時, 它會渲染 /WEB-INF/jsp/hello.jsp 文件. 把 jsp 文件放到 /WEB-INF/jsp/ 目錄下是被鼓勵的, 這樣可以防止用戶不經過 Controller 直接訪問 jsp 文件從而出錯(有些頑皮的人很喜歡這樣做).

    • 配置 SimpleUrlHandlerMapping, 在上面的配置文件中, /hello.do 的請求將被 helloController 處理. "/hello.do"和"helloController" 是變量, 你可以更改. 但是你注意到了嗎, hello.do 以 .do 作為后綴名. 如果這里(本文的條件下)你不使用.do 作為后綴名, 就沒有程序來處理這個請求了. 因為 DispatcherServlet 將收到的請求轉交給 SimpleUrlHandlerMapping, DispatcherServlet 收不到的請求, SimpleUrlHandlerMapping 當然也收不到了. 你可以在 props 標簽內配置多個 prop 標簽.

    • 我們將在后面編寫com.ecnulxq.test.HelloController類.

    上面, 我們在 web.xml 文件中告訴 ContextLoaderListener, 我們還有另外兩個配置文件 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml.

    applicationContext.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>
     <bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="locations">
       <list>
        <value>/WEB-INF/jdbc.properties</value>
       </list>
      </property>
     </bean>

    </beans>

    它配置了以下功能:

    • 讀取 /WEB-INF/jdbc.properties 文件. 你可以在 list 標簽中配置多個 value 標簽.

    database.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ">
     
    <beans>
    <!-- Remove this if your database setting is fine.
      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </bean>
    -->
      <!-- Transaction manager for a single JDBC DataSource
      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>
       -->
      <!--
      <bean id="attributeManager" class="com.ideawu.core.AttributeManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>
      -->
    </beans>
    

    它配置了以下功能(不過,已經注釋掉了):

    • 配置數據庫連接. 類似${jbbc.url}是一種訪問變量的方法. 我們可以從 /WEB-INF/jdbc.properties 中找到這個變量的值. 如果你的數據庫已經配置好, 就將第一個注釋去掉.

    jdbc.properties:
    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8
    jdbc.username=root
    jdbc.password=root
    
    現在, 我們來編寫 Java 代碼吧.
     
    package com.ecnulxq.test;


    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;



    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;



    /**
     * @author lxq ecnulxq@163.com
     * @version 創建時間:Oct 12, 2007 類說明
     *
     */
    public class HelloController implements Controller {



     public ModelAndView handleRequest(HttpServletRequest request,
       HttpServletResponse response) throws Exception {
      request.setAttribute("hello_1", "你好!Spring!");
      request.setAttribute("hello_2", "Hello!Spring!");
      return new ModelAndView("hello");
     }



    }


    return new ModelAndView("hello"); 告訴 InternalResourceViewResolver jsp 模板的名字叫作 hello. request.setAttribute() 設置的對象我們可以在 jsp 文件中使用.

    hello.jsp:

    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>Hello World!</title>
     </head>
     <body>



      <h2>
       ${hello_1}
      </h2>



      <h2>
       ${hello_2}
      </h2>



     </body>
    </html>

    posted @ 2008-06-05 12:46 秋楓故事 閱讀(902) | 評論 (1)編輯 收藏

    JSTL詳解(一轉)

    7 Functions 標簽庫

            稱呼 Functions 標簽庫為標簽庫,倒不如稱呼其為函數庫來得更容易理解些。因為 Functions 標簽庫并沒有提供傳統的標簽來為 JSP 頁面的工作服務,而是被用于 EL 表達式語句中。在 JSP2.0 規范下出現的 Functions 標簽庫為 EL 表達式語句提供了許多更為有用的功能。 Functions 標簽庫分為兩大類,共 16 個函數。

    長度函數: fn:length

    字符串處理函數: fn:contains 、 fn:containsIgnoreCase 、 fn:endsWith 、 fn:escapeXml 、 fn:indexOf 、 fn:join 、 fn:replace 、 fn:split 、 fn:startsWith 、 fn:substring 、 fn:substringAfter 、 fn:substringBefore 、 fn:toLowerCase 、 fn:toUpperCase 、 fn:trim

    以下是各個函數的用途和屬性以及簡單示例。

    9.7.1  長度函數 fn:length 函數

         長度函數 fn:length 的出現有重要的意義。在 JSTL1.0 中,有一個功能被忽略了,那就是對集合的長度取值。雖然 java.util.Collection 接口定義了 size 方法,但是該方法不是一個標準的 JavaBean 屬性方法(沒有 get,set 方法),因此,無法通過 EL 表達式“ ${collection.size} ”來輕松取得。

    fn:length 函數正是為了解決這個問題而被設計出來的。它的參數為 input ,將計算通過該屬性傳入的對象長度。該對象應該為集合類型或 String 類型。其返回結果是一個 int 類型的值。下面看一個示例。

    <%ArrayList arrayList1 = new ArrayList();

                                arrayList1.add("aa");

                                arrayList1.add("bb");

                                arrayList1.add("cc");

    %>

    <%request.getSession().setAttribute("arrayList1", arrayList1);%>

    ${fn:length(sessionScope.arrayList1)}

    假設一個 ArrayList 類型的實例“ arrayList1 ”,并為其添加三個字符串對象,使用 fn:length 函數后就可以取得返回結果為“ 3 ”。

    9.7.2  判斷函數 fn:contains 函數

    fn:contains 函數用來判斷源字符串是否包含子字符串。它包括 string 和 substring 兩個參數,它們都是 String 類型,分布表示源字符串和子字符串。其返回結果為一個 boolean 類型的值。下面看一個示例。

    ${fn:contains("ABC", "a")}<br>

    ${fn:contains("ABC", "A")}<br>

    前者返回“ false ”,后者返回“ true ”。

    9.7.3 fn:containsIgnoreCase 函數

    fn:containsIgnoreCase 函數與 fn:contains 函數的功能差不多,唯一的區別是 fn:containsIgnoreCase 函數對于子字符串的包含比較將忽略大小寫。它與 fn:contains 函數相同,包括 string 和 substring 兩個參數,并返回一個 boolean 類型的值。下面看一個示例。

    ${fn:containsIgnoreCase("ABC", "a")}<br>

    ${fn:containsIgnoreCase("ABC", "A")}<br>

    前者和后者都會返回“ true ”。

    9.7.4  詞頭判斷函數 fn:startsWith 函數

    fn:startsWith 函數用來判斷源字符串是否符合一連串的特定詞頭。它除了包含一個 string 參數外,還包含一個 subffx 參數,表示詞頭字符串,同樣是 String 類型。該函數返回一個 boolean 類型的值。下面看一個示例。

    ${fn:startsWith ("ABC", "ab")}<br>

    ${fn:startsWith ("ABC", "AB")}<br>

    前者返回“ false ”,后者返回“ true ”。

    9.7.5  詞尾判斷函數 fn:endsWith 函數

    fn:endsWith 函數用來判斷源字符串是否符合一連串的特定詞尾。它與 fn:startsWith 函數相同,包括 string 和 subffx 兩個參數,并返回一個 boolean 類型的值。下面看一個示例。

    ${fn:endsWith("ABC", "bc")}<br>

    ${fn:endsWith("ABC", "BC")}<br>

    前者返回“ false ”,后者返回“ true ”。

    9.7.6  字符實體轉換函數 fn:escapeXml 函數

    fn:escapeXml 函數用于將所有特殊字符轉化為字符實體碼。它只包含一個 string 參數,返回一個 String 類型的值。

    9.7.8  字符匹配函數 fn:indexOf 函數

    fn:indexOf 函數用于取得子字符串與源字符串匹配的開始位置,若子字符串與源字符串中的內容沒有匹配成功將返回“ -1 ”。它包括 string 和 substring 兩個參數,返回結果為 int 類型。下面看一個示例。

    ${fn:indexOf("ABCD","aBC")}<br>

    ${fn:indexOf("ABCD","BC")}<br>

    前者由于沒有匹配成功,所以返回 -1 ,后者匹配成功將返回位置的下標,為 1 。

    posted @ 2008-06-05 09:49 秋楓故事 閱讀(224) | 評論 (0)編輯 收藏

    hibernate二級緩存的實現

         摘要: 對于Hibernate這類ORM而言,緩存顯的尤為重要,它是持久層性能提升的關鍵.簡單來講Hibernate就是對JDBC進行封裝,以實現內部狀態的管理,OR關系的映射等,但隨之帶來的就是數據訪問效率的降低,和性能的下降,而緩存就是彌補這一缺點的重要方法.     緩存就是數據庫數據在內存中的臨時容器,包括數據庫數據在內存中的臨時拷貝,它位于數據庫與數...  閱讀全文

    posted @ 2008-04-16 18:17 秋楓故事 閱讀(1760) | 評論 (1)編輯 收藏

    深入淺出SQL教程之Group By和Having

    在介紹GROUP BY 和 HAVING 子句前,我們必需先講講sql語言中一種特殊的函數:聚合函數,例如SUM, COUNT, MAX, AVG等。這些函數和其它函數的根本區別就是它們一般作用在多條記錄上。 

    SELECT SUM(population) FROM bbc 

    這里的SUM作用在所有返回記錄的population字段上,結果就是該查詢只返回一個結果,即所有國家的總人口數。 

    通過使用GROUP BY 子句,可以讓SUM 和 COUNT 這些函數對屬于一組的數據起作用。當你指定 GROUP BY region 時, 屬于同一個region(地區)的一組數據將只能返回一行值,也就是說,表中所有除region(地區)的字段,只能通過 SUM, COUNT等聚合函數運算后返回一個值。  HAVING子句可以讓我們篩選成組后的各組數據,WHERE子句在聚合前先篩選記錄.也就是說作用在GROUP BY 子句和HAVING子句前,而 HAVING子句在聚合后對組記錄進行篩選。 

    讓我們還是通過具體的實例來理解GROUP BY 和 HAVING 子句,還采用第三節介紹的bbc表。 

    SQL實例: 

    一、顯示每個地區的總人口數和總面積: 

    SELECT region, SUM(population), SUM(area)

    FROM bbc

    GROUP BY region

     

    先以region把返回記錄分成多個組,這就是GROUP BY的字面含義。分完組后,然后用聚合函數對每組中的不同字段(一或多條記錄)作運算。 

    二、 顯示每個地區的總人口數和總面積.僅顯示那些面積超過1000000的地區。 

    SELECT region, SUM(population), SUM(area)

    FROM bbc

    GROUP BY region

    HAVING SUM(area)>1000000

     

    在這里,我們不能用where來篩選超過1000000的地區,因為表中不存在這樣一條記錄。 

    相反,HAVING子句可以讓我們篩選成組后的各組數據。


    group by分組統計SQL語句(實例)

    用一條查詢語句,查出各姓名的數值余額.

    用戶表:
    姓名
    a
    b
    c
    ....

    扣費表:
    姓名 數值
    a 3.5
    b 5.2
    a 2
    ...

    充值表:
    姓名 數值
    b 10
    a 10
    a 10.5
    ...

    返回:
    姓名 差額(充值和-扣費和)

    測試通過

    select table1.TNAME,table1.TelName, (table3.充值-table2.扣費) as 差額
    from 用戶表 table1,(select TelName,sum(TelQryh)as 扣費 from 扣費表 group by TelName)table2,
    (select TelName,sum(TelQryc)as 充值 from 充值表 group by TelName)table3 where
    table1.TelName=table2.TelName and table1.TelName=table3.TelName

    posted @ 2008-04-12 19:32 秋楓故事 閱讀(143) | 評論 (0)編輯 收藏

    (轉)Struts Spring Hibernate 整合報空指針解決方法

    最近一直在弄WebWork,Struts都快忘了。今天又自己小試了一下SSH,結果每次都是報空指針異常,經過一番研究,發現,如果不把action的type改成

    org.springframework.web.struts.DelegatingActionProxy

    的話,就會報這個

    java.lang.NullPointerException

     com.test.struts.action.UserAction.show(UserAction.java:46)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)
    org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)
    org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
    org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
    org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
    org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    解決辦法:
    1.在struts-config.xml的action把type改成org.springframework.web.struts.DelegatingActionProxy,例如:
    <action attribute="userForm" input="/index.jsp" name="userForm"
              parameter="param" path="/user" scope="request"
              type="org.springframework.web.struts.DelegatingActionProxy"
              validate="false">
              <forward name="success" path="/success.jsp" />
    </action>
    2.在spring的配置文件(applicationContext.xml)里添加一些代碼:
    <bean id="transactionManager"
             class="org.springframework.orm.hibernate3.HibernateTransactionManager">
             <property name="sessionFactory">
              <ref bean="sessionFactory" />
             </property>
    </bean>
    給DAO加上代理
    <bean id="UserDAOIProxy"
             class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
             <property name="transactionManager">
              <ref bean="transactionManager" />
             </property>
             <property name="target">
              <ref bean="UserDao" />
             </property>
             <property name="transactionAttributes">
              <props>
               <prop key="create*">PROPAGATION_REQUIRED</prop>
               <prop key="update*">PROPAGATION_REQUIRED</prop>
               <prop key="delete*">PROPAGATION_REQUIRED</prop>
               <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
              </props>
             </property>
    </bean>
    3.更改Service的引用
     <bean name="UserService"
             class="com.test.service.impl.UserServiceImpl">
             <property name="userDao">
              <ref bean="
    UserDAOIProxy" />
             </property>
    </bean>
    這樣就不會報那個異常了,測試通過^_^
    我的配置文件代碼:
    applicationContext.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="dataSource"
             class="org.apache.commons.dbcp.BasicDataSource">
             <property name="driverClassName"
              value="oracle.jdbc.driver.OracleDriver">
             </property>
             <property name="url"
              value="jdbc:oracle:thin:@192.192.192.19:1521:orcl">
             </property>
             <property name="username" value="sunyu"></property>
             <property name="password" value="19830317"></property>
    </bean>
    <bean id="sessionFactory"
             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
             <property name="dataSource">
              <ref bean="dataSource" />
             </property>
             <property name="hibernateProperties">
              <props>
               <prop key="hibernate.dialect">
                org.hibernate.dialect.Oracle9Dialect
               </prop>
               <prop key="hibernate.show_sql">true</prop>
              </props>
             </property>
             <property name="mappingResources">
              <list>
               <value>com/test/model/TestUser.hbm.xml</value>
              </list>
             </property>
    </bean>
    <bean id="transactionManager"
             class="org.springframework.orm.hibernate3.HibernateTransactionManager">
             <property name="sessionFactory">
              <ref bean="sessionFactory" />
             </property>
    </bean>
    <bean name="UserDao" class="com.test.dao.impl.UserDaoImpl">
             <property name="sessionFactory">
              <ref bean="sessionFactory" />
             </property>
    </bean>
    <bean id="UserDAOIProxy"
             class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
             <property name="transactionManager">
              <ref bean="transactionManager" />
             </property>
             <property name="target">
              <ref bean="UserDao" />
             </property>
             <property name="transactionAttributes">
              <props>
               <prop key="create*">PROPAGATION_REQUIRED</prop>
               <prop key="update*">PROPAGATION_REQUIRED</prop>
               <prop key="delete*">PROPAGATION_REQUIRED</prop>
               <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
              </props>
             </property>
    </bean>
    <bean name="UserService"
             class="com.test.service.impl.UserServiceImpl">
             <property name="userDao">
              <ref bean="UserDAOIProxy" />
             </property>
    </bean>
    <bean name="/user" class="com.test.struts.action.UserAction">
             <property name="userService">
              <ref bean="UserService" />
             </property>
    </bean>
    </beans>
    struts-config.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "
    http://struts.apache.org/dtds/struts-config_1_2.dtd
    ">
    <struts-config>
    <data-sources />
    <form-beans>
             <form-bean name="userForm" type="com.test.struts.form.UserForm" />
    </form-beans>
    <global-exceptions />
    <global-forwards />
    <action-mappings>
             <action attribute="userForm" input="/index.jsp" name="userForm"
              parameter="param" path="/user" scope="request"
              type="org.springframework.web.struts.DelegatingActionProxy"
              validate="false">
              <forward name="success" path="/success.jsp" />
             </action>
    </action-mappings>
    <message-resources parameter="com.test.struts.ApplicationResources" />
    <plug-in
             className="org.springframework.web.struts.ContextLoaderPlugIn">
             <set-property property="contextConfigLocation"
              value="/WEB-INF/applicationContext.xml" />
    </plug-in>

    </struts-config>



    ------------------------------------------
    第二種方法,如果在struts-config.xml里面加上

    <controller>
    <set-property property="processorClass"
    value="org.springframework.web.struts.DelegatingRequestProcessor" />
    </controller>

    這樣action就不需要type屬性了
    ----------------------------------------------

    posted @ 2008-04-03 19:14 秋楓故事 閱讀(2443) | 評論 (0)編輯 收藏

    (轉)jboss部署ejb

    開發sessionbean EJB最少也需要三個class,remote interface,home interface,and bean implementation(bean行為).

    1. remote interface 用來揭示EJB對外的一些方法.

    package helloWorld; import javax.ejb.EJBObject;
    import java.rmi.RemoteException;
    public interface RemoteHello extends EJBObject
    { public String HelloEcho(String inputString) throws RemoteException; }
    2.home interface 是用來規定怎樣創建一個實現remote interface的bean.
    package helloWorld;
    import java.io.Serializable;
    import java.rmi.RemoteException;
    import javax.ejb.CreateException;
    import javax.ejb.EJBHome;
    public interface HomeHello extends EJBHome

    { RemoteHello create() throws RemoteException, CreateException; }

    3.bean implementation 是提供方法的實現,這些方法在上述兩種interface中都有規定了.

    package helloWorld;

    import java.rmi.RemoteException;

    import javax.ejb.SessionBean;

    import javax.ejb.SessionContext;

    public class HelloBean implements SessionBean{

       public String HelloEcho(String inputString) {

         System.out.println("Someone called 'Hello Echo Successed!'");

         return "*********" + inputString + "*********"; }

         /** Empty method body  */

         public void ejbCreate() {

            System.out.println("Ejb 4 is creating!...");}

         /** Every ejbCreate() method ALWAYS needs a corresponding   ejbPostCreate () method with exactly the same parameter types.   */

    public void ejbPostCreate() {}

    /** Empty method body   */

    public void ejbRemove() {

        System.out.println("Ejb 4 is removing!...");}

     /** Empty method body */

    public void ejbActivate() {

       System.out.println("Ejb 4 is activating!...");}

    /** Empty method body */

    public void ejbPassivate()

     {}

    /** Empty method body   */

    public void setSessionContext(SessionContext sc)

     {}

    }

    部署jar

    這些classes必須打包進一個JAR文件中,JAR文件中包含了目錄結構和包的層次.在本例中, 這些classes是在包helloworld,這樣他們需要在目錄helloWorld/ 下.

    部署發布描述器ejb-jar.XML和jboss.xml
    在JAR文檔創建之前,還需要一個叫META-INF的目錄,這是存放部署發布描述器的(一般叫ejb-jar.xml).

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD EntERPrise JavaBeans 2.0//EN" "
    http://java.sun.com/dtd/ejb-jar_2_0.dtd">
    <ejb-jar>
     <description>Neosue Helloworld Sample Application</description>
     <display-name>Helloworld EJB</display-name>
     <enterprise-beans>
      <session>
       <ejb-name>Helloworld</ejb-name>
       <!-- home interface -->
       <home>helloWorld.HomeHello</home>
       <!-- remote interface -->
       <remote>helloWorld.RemoteHello</remote>
       <!-- bean implementation -->
       <ejb-class>helloWorld.HelloBean</ejb-class>
       <session-type>Stateless</session-type>
       <transaction-type>Bean</transaction-type>
      </session>
     </enterprise-beans>
    </ejb-jar>

    jboss.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "
    http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
    <jboss>
     <enterprise-beans>
      <session>
       <ejb-name>Helloworld</ejb-name>
       <jndi-name>Helloworld/Hello</jndi-name>
      </session>
     </enterprise-beans>
    </jboss>
    雖然有了上面你的應用程序和JNDI name的梆定,但是一旦部署發布到JBoss服務器上,你還需要一個jndi.properties文件,以告訴調用你程序的客戶端請求到哪里去初始化JNDI naming service.

    測試程序:

    import javax.naming.Context;

    import javax.naming.InitialContext;

    import javax.rmi.PortableRemoteObject;

    import helloWorld.*;

    public class MyTest {

       public static void main(String[] args) {

          try{ Context ctx=new InitialContext();

               Object ref=ctx.lookup("Helloworld/Hello");

               HomeHello home=(HomeHello)PortableRemoteObject.narrow(ref,HomeHello.class);

               RemoteHello user=home.create(); System.out.println(user.HelloEcho("So easy!"));

            }catch(Exception e) {

              e.printStackTrace();

            }

       }

    }

    Jboss EJB 部署步驟 建立 remote interface-->home interface-->and bean implementation--> ejb-jar.xml-->jboss.xml--打包(package[jar cvf packageName.jar .])-->復制到jboss deploy目錄.

    ---------------------------------------------------------
    原文 URL
    http://blog.blogchina.com/refer.159508.html
    ---------------------------------------------------------
    補充說明如下:

    OS: windows 2000;
    JDK: 1.5.0rc;
    JBoss: 4.0

    HelloWorld.jar
    |--META-INF
    |      |--jboss.xml
    |      |--ejb-jar.xml
    |      |--MANIFEST.MF (自動生成)
    |--helloWorld
           |--RemoteHello.class
           |--jndi.properties
           |--HomeHello.class
           |--HelloBean.class


    其中 測試文件 MyTest.class 同目錄拷貝一份 jndi.properties 文件過來.

    jndi.properties 的內容如下:

    java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
    java.naming.provider.url=localhost:1099
    java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

    posted @ 2008-03-30 19:38 秋楓故事 閱讀(1053) | 評論 (0)編輯 收藏

    ( 轉)重寫自已的HashCode()方法

     大家都知道,在Java里對對象的操作是基于引用的。而當我們需要對一組對象操作的時候,  就需要有接收這一組引用的容器。平時我們最常用的就是數組。在Java里可以定義一個對象數組來完成許多操作。可是,數組長度是固定的,如果我們需要更 加靈活的解決方案該怎么辦呢?

           Java提供了container  classes來解決這一問題。container  classes包括兩個部分:Collection和Map。

    它們的結構是這樣的: 

           本文重點介紹HashMap。首先介紹一下什么是Map。在數組中我們是通過數組下標來對其內容索引的,  而在Map中我們通過對象來對對象進行索引,用來索引的對象叫做key,其對應的對象叫做value。  在下文中會有例子具體說明。

           再來看看HashMap和TreeMap有什么區別。HashMap通過hashcode對其內容進行快速查找,而TreeMap中所有的元素都保持著 某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。

    下面就要進入本文的主題了。先舉個例子說明一下怎樣使用HashMap:













    程序代碼:
    import java.util.*; 
    public class Exp1 { 
         public static void main(String[] args){ 
              HashMap h1=new HashMap(); 
              Random r1=new Random();     
              for(int i=0;i< 1000;i++){ 
                   Integer t=new Integer(r1.nextInt(20)); 
                   if(h1.containsKey(t)) 
                        ((Ctime)h1.get(t)).count++; 
                   else 
                        h1.put(t, new Ctime()); 
              } 
              System.out.println(h1); 
         } 

    class Ctime{ 
         int count=1; 
         public String toString(){ 
              return Integer.toString(count); 
         } 


               在HashMap中通過get()來獲取value,通過put()來插入value,ContainsKey()則用來檢驗對象是否已經存在。可以看 出,和ArrayList的操作相比,HashMap除了通過key索引其內容之外,別的方面差異并不大。

             前面介紹了,HashMap是基于HashCode的,在所有對象的超類Object中有一個HashCode()方法,  但是它和equals方法一樣,并不能適用于所有的情況,這樣我們就需要重寫自己的HashCode()方法。
    下面就舉這樣一個例子:













    程序代碼:
    import java.util.*; 
    public class Exp2 { 
         public static void main(String[] args){ 
              HashMap h2=new HashMap(); 
              for(int i=0;i< 10;i++) 
                   h2.put(new Element(i), new Figureout()); 
              System.out.println("h2:"); 
              System.out.println("Get the result for Element:"); 
              Element test=new Element(5); 
              if(h2.containsKey(test)) 
                   System.out.println((Figureout)h2.get(test)); 
              else 
                   System.out.println("Not found"); 
         } 

    class Element{ 
         int number; 
         public Element(int n){ 
              number=n; 
         } 

    class Figureout{ 
         Random r=new Random(); 
         boolean possible=r.nextDouble()>0.5; 
         public String toString(){ 
              if(possible) 
                   return "OK!"
              else 
                   return "Impossible!"
         } 

     
           在這個例子中,Element用來索引對象Figureout,也即Element為key,Figureout為value。  在Figureout中隨機生成一個浮點數,如果它比0.5大,打印“OK!”,否則打印“Impossible!”。  之后查看Element(5)對應的Figureout結果如何。  

           結果卻發現,無論你運行多少次,得到的結果都是“Not  found”。也就是說索引Element(5)并不在HashMap中。這怎么可能呢?

           原因得慢慢來說:Element的HashCode方法繼承自Object,而Object中的HashCode方法返回的HashCode對應于當前 的地址,也就是說對于不同的對象,即使它們的內容完全相同,用HashCode()返回的值也會不同。這樣實際上違背了我們的意圖。因為我們在使用 HashMap時,  希望利用相同內容的對象索引得到相同的目標對象,這就需要HashCode()在此時能夠返回相同的值。

           在上面的例子中,我們期望new  Element(i)  (i=5)與  Element  test=new  Element(5)是相同的,  而實際上這是兩個不同的對象,盡管它們的內容相同,但它們在內存中的地址不同。因此很自然的,  上面的程序得不到我們設想的結果。下面對Element類更改如下:













    程序代碼:
    class Element{ 
      int number; 
      public Element(int n){ 
        number=n; 
     } 
      public int hashCode(){ 
       return number; 
      } 
      public boolean equals(Object o){ 
       return (o instanceof Element) && (number==((Element)o).number); 
      } 


               在這里Element覆蓋了Object中的hashCode()和equals()方法。覆蓋hashCode()使其以number的值作為 hashcode返回,這樣對于相同內容的對象來說它們的hashcode也就相同了。而覆蓋equals()是為了在HashMap判斷兩個key是否 相等時使結果有意義(有關重寫equals()的內容可以參考我的另一篇文章《重新編寫Object類中的方法  》)。修改后的程序運行結果如下:

    h2:  
    Get  the  result  for  Element:  
    Impossible!  

    請記住:如果你想有效的使用HashMap,你就必須重寫在其的HashCode()。

    還有兩條重寫HashCode()的原則:

           不必對每個不同的對象都產生一個唯一的hashcode,只要你的HashCode方法使get()能夠得到put()放進去的內容就可以了。即“不為 一原則”。  生成hashcode的算法盡量使hashcode的值分散一些,  不要很多hashcode都集中在一個范圍內,這樣有利于提高HashMap的性能。即“分散原則”。  至于第二條原則的具體原因,有興趣者可以參考Bruce  Eckel的《Thinking  in  Java》,
    在那里有對HashMap內部實現原理的介紹,這里就不贅述了。

           掌握了這兩條原則,你就能夠用好HashMap編寫自己的程序了。不知道大家注意沒有,  java.lang.Object中提供的三個方法:clone(),equals()和hashCode()雖然很典型,  但在很多情況下都不能夠適用,它們只是簡單的由對象的地址得出結果。  這就需要我們在自己的程序中重寫它們,其實java類庫中也重寫了千千萬萬個這樣的方法。  利用面向對象的多態性——覆蓋,Java的設計者很優雅的構建了Java的結構,也更加體現了Java是一門純OOP語言的特性。

         Java提供的Collection和Map的功能是十分強大的,它們能夠使你的程序實現方式更為靈活,  執行效率更高。希望本文能夠對大家更好的使用HashMap有所幫助。

    posted @ 2008-03-28 11:17 秋楓故事 閱讀(250) | 評論 (0)編輯 收藏

    產生對象個數問題

    String a = "hello";
    String b = "world";
    String c = "ok";
    String d = "is";
    String result = a+b+c+d;
    問:共產生多少個對象?

    答:
    現在的編譯器早就對這些代碼作了優化,編譯成如下:
    String a = "hello";
    String b = "world";
    String c = "ok";
    String d = "is";
    String result = new StringBuffer().append(a),append(b),append(c).append(d).toString();
    因此產生了6個對象,其中5個字符串對象,一個StringBuffer臨時對象。

    posted @ 2008-03-28 10:39 秋楓故事 閱讀(310) | 評論 (0)編輯 收藏

    java 文件操作(拷貝一個文件)

    try
    {

      BufferedReader in = new BufferedReader(new FileReader("c:\\1.txt"));
      PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("c:\\2.txt")),true);
      String tmp = "";
      while((tmp=in.readLine()) != null)
      {
        writer.println(tmp);
      }
      writer.close();
      in.close();
    }
    catch(Exception e)
    {
    e.printStackTrace();
    }

    posted @ 2008-03-25 22:35 秋楓故事 閱讀(359) | 評論 (0)編輯 收藏

    [轉] 解析oracle的ROWNUM

    對于rownum來說它是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是1,第二行是2,依此類推,這個偽字段可以用于限制查詢返回的總行數,而且rownum不能以任何表的名稱作為前綴。
     舉例說明:
    例如表:student(學生)表,表結構為:
    ID       char(6)      --學號
    name    VARCHAR2(10)   --姓名
    create table student (ID char(6), name VARCHAR2(100));
    insert into sale values('200001',‘張一’);
    insert into sale values('200002',‘王二’);
    insert into sale values('200003',‘李三’);
    insert into sale values('200004',‘趙四’);
    commit;

    (1) rownum 對于等于某值的查詢條件
    如果希望找到學生表中第一條學生的信息,可以使用rownum=1作為條件。但是想找到學生表中第二條學生的信息,使用rownum=2結果查不到數據。因為rownum都是從1開始,但是1以上的自然數在rownum做等于判斷是時認為都是false條件,所以無法查到rownum = n(n>1的自然數)。
    SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回記錄條數的地方,保證不出錯,如:隱式游標)
    SQL> select rownum,id,name from student where rownum=1;
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------
             1 200001 張一
    SQL> select rownum,id,name from student where rownum =2;
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------

    (2)rownum對于大于某值的查詢條件
       如果想找到從第二行記錄以后的記錄,當使用rownum>2是查不出記錄的,原因是由于rownum是一個總是從1開始的偽列,Oracle 認為rownum> n(n>1的自然數)這種條件依舊不成立,所以查不到記錄
    SQL> select rownum,id,name from student where rownum >2;
    ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------
    那如何才能找到第二行以后的記錄呀。可以使用以下的子查詢方法來解決。注意子查詢中的rownum必須要有別名,否則還是不會查出記錄來,這是因為rownum不是某個表的列,如果不起別名的話,無法知道rownum是子查詢的列還是主查詢的列。
    SQL>select * from(select rownum no ,id,name from student) where no>2;
            NO ID     NAME
    ---------- ------ ---------------------------------------------------
             3 200003 李三
             4 200004 趙四
    SQL> select * from(select rownum,id,name from student)where rownum>2;
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------

    (3)rownum對于小于某值的查詢條件
    如果想找到第三條記錄以前的記錄,當使用rownum<3是能得到兩條記錄的。顯然rownum對于rownum<n((n>1的自然數)的條件認為是成立的,所以可以找到記錄。
    SQL> select rownum,id,name from student where rownum <3;
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------
            1 200001 張一
            2 200002 王二
    綜上幾種情況,可能有時候需要查詢rownum在某區間的數據,那怎么辦呀從上可以看出rownum對小于某值的查詢條件是人為true的,rownum對于大于某值的查詢條件直接認為是false的,但是可以間接的讓它轉為認為是true的。那就必須使用子查詢。例如要查詢rownum在第二行到第三行之間的數據,包括第二行和第三行數據,那么我們只能寫以下語句,先讓它返回小于等于三的記錄行,然后在主查詢中判斷新的rownum的別名列大于等于二的記錄行。但是這樣的操作會在大數據集中影響速度。
    SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;
            NO ID     NAME
    ---------- ------ ---------------------------------------------------
             2 200002 王二
             3 200003 李三

    (4)rownum和排序
    Oracle中的rownum的是在取數據的時候產生的序號,所以想對指定排序的數據去指定的rowmun行數據就必須注意了。
    SQL> select rownum ,id,name from student order by name;
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------
             3 200003 李三
             2 200002 王二
             1 200001 張一
             4 200004 趙四
    可以看出,rownum并不是按照name列來生成的序號。系統是按照記錄插入時的順序給記錄排的號,rowid也是順序分配的。為了解決這個問題,必須使用子查詢
    SQL> select rownum ,id,name from (select * from student order by name);
        ROWNUM ID     NAME
    ---------- ------ ---------------------------------------------------
             1 200003 李三
             2 200002 王二
             3 200001 張一
             4 200004 趙四
    這樣就成了按name排序,并且用rownum標出正確序號(有小到大)
    筆者在工作中有一上百萬條記錄的表,在jsp頁面中需對該表進行分頁顯示, 便考慮用rownum來作,下面是具體方法(每頁
    顯示20條):
      “select * from tabname where rownum<20 order by name" 但卻發現oracle卻不能按自己的意愿來執行,而是先隨便
    取20條記錄,然后再 order by,后經咨詢oracle,說rownum確實就這樣,想用的話,只能用子查詢 來實現先排序,后
    rownum,方法如下:
      "select * from (select * from tabname order by name) where  rownum<20",但這樣一來,效率會較低很多。
      后經筆者試驗,只需在order by 的字段上加主鍵或索引即可讓oracle先按 該字段排序,然后再rownum;方法不變:
       “select * from tabname where rownum<20 order by name"

    取得某列中第N大的行

    select column_name from
    (select table_name.*,dense_rank() over (order by column desc) rank from table_name)
    where rank = &N;
     假如要返回前5條記錄:

      select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)
    假如要返回第5-9條記錄:

    select * from tablename
    where …
    and rownum<10
    minus
    select * from tablename
    where …
    and rownum<5
    order by name
    選出結果后用name排序顯示結果。(先選再排序)

    注意:只能用以上符號(<、<=、!=)。

    select * from tablename where rownum != 10;返回的是前9條記錄。
    不能用:>,>=,=,Between...and。由于rownum是一個總是從1開始的偽列,Oracle 認為這種條件 不成立,查不到記錄.

    另外,這個方法更快:

    select * from (
    select rownum r,a from yourtable
    where rownum <= 20
    order by name )
    where r > 10
    這樣取出第11-20條記錄!(先選再排序再選)

    要先排序再選則須用select嵌套:內層排序外層選。
    rownum是隨著結果集生成的,一旦生成,就不會變化了;同時,生成的結果是依次遞加的,沒有1就永遠不會有2!
    rownum 是在 查詢集合產生的過程中產生的偽列,并且如果where條件中存在 rownum 條件的話,則:

    1: 假如 判定條件是常量,則:
    只能 rownum = 1, <= 大于1 的自然數, = 大于1 的數是沒有結果的, 大于一個數也是沒有結果的
    即 當出現一個 rownum 不滿足條件的時候則 查詢結束   this is stop key!

    2: 當判定值不是常量的時候
    若條件是 = var , 則只有當 var 為1 的時候才滿足條件,這個時候不存在 stop key ,必須進行 full scan ,對每個滿足其他where條件的數據進行判定
    選出一行后才能去選rownum=2的行…… 

    posted @ 2008-03-24 19:35 秋楓故事 閱讀(174) | 評論 (0)編輯 收藏

    Group By SQL

     

    我們現在回到函數上。記得我們用 SUM 這個指令來算出所有的 Sales (營業額)吧!如果我們的需求變成是要算出每一間店 (store_name) 的營業額 (sales),那怎么辦呢?在這個情況下,我們要做到兩件事:第一,我們對于 store_name 及 Sales 這兩個欄位都要選出。第二,我們需要確認所有的 sales 都要依照各個 store_name 來分開算。這個語法為:

    SELECT "欄位1", SUM("欄位2")
    FROM "表格名"
    GROUP BY "欄位1"

    在我們的示范上,

    Store_Information 表格
    store_name Sales Date
    Los Angeles $1500 Jan-05-1999
    San Diego $250 Jan-07-1999
    Los Angeles $300 Jan-08-1999
    Boston $700 Jan-08-1999

    我們就打入,

    SELECT store_name, SUM(Sales)
    FROM Store_Information
    GROUP BY store_name

    結果:

    store_name SUM(Sales)
    Los Angeles $1800
    San Diego $250
    Boston $700

    當我們選不只一個欄位,且其中至少一個欄位有包含函數的運用時,我們就需要用到 GROUP BY 這個指令。在這個情況下,我們需要確定我們有 GROUP BY 所有其他的欄位。換句話說,除了有包括函數的欄位外,我 們都需要將其放在 GROUP BY 的子句中。

    posted @ 2008-03-23 10:00 秋楓故事 閱讀(197) | 評論 (0)編輯 收藏

    java排序

    冒泡排序:
    /*
      * 冒泡排序:
      */
     public static void sort(int[] data) {
      for (int i = 0; i < data.length; i++) {
       for (int j = data.length - 1; j > i; j--) {
        if (data[j] < data[j - 1]) {
         
         int tmp = data[j];
         data[j] = data[j-1];
         data[j-1] = tmp;
        }
       }
      }
     }

    posted @ 2008-03-22 00:22 秋楓故事 閱讀(139) | 評論 (0)編輯 收藏

    為什么要使用“外連接”

    之前我們看到的左連接 (left join),又稱內部連接 (inner join)。在這個情況下,要兩個表格內都有同樣的值,那一筆資料才會被選出。那如果我們想要列出一個表格中每一筆的資料,無論它的值在另一個表格中有沒有出現,那該怎么辦呢?在這個時候,我們就需要用到 SQL OUTER JOIN (外部連接) 的指令。

    外部連接的語法是依數據庫的不同而有所不同的。舉例來說,在 Oracle 上,我們會在 WHERE 子句中要選出所有資料的那個表格之后加上一個 "(+)" 來代表說這個表格中的所有資料我們都要。

    假設我們有以下的兩個表格:

    Store_Information 表格
    store_name Sales Date
    Los Angeles $1500 Jan-05-1999
    San Diego $250 Jan-07-1999
    Los Angeles $300 Jan-08-1999
    Boston $700 Jan-08-1999

    Geography 表格
    region_name store_name
    East Boston
    East New York
    West Los Angeles
    West San Diego

    我們需要知道每一間店的營業額。如果我們用一個普通的連接,我們將會漏失掉 'New York'這個店,因為它并不存在于 Store_Information 這個表格。所以,在這個情況下,我們需要用外部連接來串聯這兩個表格:

    SELECT A1.store_name, SUM(A2.Sales) SALES
    FROM Georgraphy A1, Store_Information A2
    WHERE A1.store_name = A2.store_name (+)
    GROUP BY A1.store_name

    我們在這里是使用了 Oracle 的外部連接語法。

    如果換成了Mysql:
    select a1.store_name,sum(a2.sales) from geography a1 left join store_information a2
    on a1.store_name=a2.store_name group by a1.store_name;


    結果:

    store_name SALES
    Boston $700
    New York
    Los Angeles $1800
    San Diego $250

    請注意: 當第二個表格沒有相對的資料時,SQL 會傳回 NULL 值。在這一個例子中, 'New York' 并不存在于 Store_Information 表格,所以它的 "SALES" 欄位是 NULL。

    posted @ 2008-03-20 20:07 秋楓故事 閱讀(616) | 評論 (0)編輯 收藏

    內連接和外連接區別

    在之前,我對MSSQL中的內連接和外連接所得出的數據集不是很清楚。這幾天重新溫習了一下SQL的書本,現在的思路應該是很清楚了,現在把自己的理解發出來給大家溫習下。希望和我一樣對SQL的連接語句不太理解的朋友能夠有所幫助。(發這么菜的教程,各位大大們別笑話偶了,呵:D )

    有兩個表A和表B。
    表A結構如下:
    Aid:int;標識種子,主鍵,自增ID
    Aname:varchar

    數據情況,即用select * from A出來的記錄情況如下圖1所示:


    圖1:A表數據

    表B結構如下:
    Bid:int;標識種子,主鍵,自增ID
    Bnameid:int

    數據情況,即用select * from B出來的記錄情況如下圖2所示:



    圖2:B表數據

    為了把Bid和Aid加以區分,不讓大家有誤解,所以把Bid的起始種子設置為100。
    有SQL基本知識的人都知道,兩個表要做連接,就必須有個連接字段,從上表中的數據可以看出,在A表中的Aid和B表中的Bnameid就是兩個連接字段。
    下圖3說明了連接的所有記錄集之間的關系:



    圖3:連接關系圖

    現在我們對內連接和外連接一一講解。
    1.內連接:利用內連接可獲取兩表的公共部分的記錄,即圖3的記錄集C
    語句如下:Select * from A JOIN B ON A.Aid=B.Bnameid
    運行結果如下圖4所示:



    圖4:內連接數據

    其實select * from A,B where A.Aid=B.Bnameid與Select * from A JOIN B ON A.Aid=B.Bnameid的運行結果是一樣的。
    2.外連接:外連接分為兩種,一種是左連接(Left JOIN)和右連接(Right JOIN)
      (1)左連接(Left JOIN):即圖3公共部分記錄集C+表A記錄集A1。     
         語句如下:select * from A Left JOIN B ON A.Aid=B.Bnameid
         運行結果如下圖5所示:



    圖5:左連接數據

         說明:
               在語句中,A在B的左邊,并且是Left Join,所以其運算方式為:A左連接B的記錄=圖3公共部分記錄集C+表A記錄集A1
               在圖3中即記錄集C中的存在的Aid為:2 3 6 7 8           
               圖1中即表A所有記錄集A中存在的Aid為:1 2 3 4 5 6 7 8 9
               表A記錄集A1中存在的Aid=(圖1中即A表中所有Aid)-(圖3中即記錄集C中存在的Aid),最終得出為:1 4 5 9
               由此得出圖5中A左連接B的記錄=圖3公共部分記錄集C+表A記錄集A1,
               最終得出的結果圖5中可以看出Bnameid及Bid非NULL的記錄都為圖3公共部分記錄集C中的記錄;Bnameid及Bid為NULL的Aid為1 4 5 9的四筆記錄就是表A記錄集A1中存在的Aid。

      (2)右連接(Right JOIN):即圖3公共部分記錄集C+表B記錄集B1。
         語句如下:select * from A Right JOIN B ON A.Aid=B.Bnameid
         運行結果如下圖6所示:



    圖6:右連接數據

         說明:
               在語句中,A在B的左邊,并且是Right Join,所以其運算方式為:A右連接B的記錄=圖3公共部分記錄集C+表B記錄集B1
               在圖3中即記錄集C中的存在的Aid為:2 3 6 7 8           
               圖2中即表B所有記錄集B中存在的Bnameid為:2 3 6 7 8 11
               表B記錄集B1中存在的Bnameid=(圖2中即B表中所有Bnameid)-(圖3中即記錄集C中存在的Aid),最終得出為:11
               由此得出圖6中A右連接B的記錄=圖3公共部分記錄集C+表B記錄集B1,
               最終得出的結果圖6中可以看出Aid及Aname非NULL的記錄都為圖3公共部分記錄集C中的記錄;Aid及Aname為NULL的Aid為11的記錄就是表B記錄集B1中存在的Bnameid。
         
    總結:

    通過上面的運算解說,相信很多人已經想到,上面的情況(包括圖3的關系圖)說明的都只是A在B的左邊的情況,
    以下語句B在A的右邊的又會出現什么情況呢??
    select * from B Left JOIN A ON A.Aid=B.Bnameid
    select * from B Right JOIN A ON A.Aid=B.Bnameid

    其實對圖3左右翻轉一下就可以得出以下結論:
    select * from B Left JOIN A ON A.Aid=B.Bnameid和select * from A Right JOIN B ON A.Aid=B.Bnameid所得出的記錄集是一樣的

    select * from B Right JOIN A ON A.Aid=B.Bnameid和select * from A Left JOIN B ON A.Aid=B.Bnameid所得出的記錄集也是一樣的。

    posted @ 2008-03-20 17:06 秋楓故事 閱讀(3668) | 評論 (3)編輯 收藏

    用jdom解析xml文件時如何解決中文問題

    import java.io.*;

    public class DOMTest {

     private String outFile = "c:\\people.xml";

     public static void main(String args[]) {
      new DOMTest();
     }

     public DOMTest() {
      try {
       javax.xml.parsers.DocumentBuilder builder =

       javax.xml.parsers.DocumentBuilderFactory.newInstance()
         .newDocumentBuilder();
       org.w3c.dom.Document doc = builder.newDocument();
       org.w3c.dom.Element root = doc.createElement("老師");
       org.w3c.dom.Element wang = doc.createElement("王");
       wang.appendChild(doc.createTextNode("我是王老師"));
       root.appendChild(wang);
       doc.appendChild(root);
       javax.xml.transform.Transformer transformer = javax.xml.transform.TransformerFactory
         .newInstance().newTransformer();
       transformer.setOutputProperty(
         javax.xml.transform.OutputKeys.ENCODING, "gb2312");
       transformer.setOutputProperty(
         javax.xml.transform.OutputKeys.INDENT, "yes");

       transformer.transform(new javax.xml.transform.dom.DOMSource(doc),
         new

         javax.xml.transform.stream.StreamResult(outFile));
      } catch (Exception e) {
       System.out.println(e.getMessage());
      }
     }
    }

    posted @ 2008-03-19 16:59 秋楓故事 閱讀(859) | 評論 (0)編輯 收藏

    JAVA內部類

    public class Aqiang {

    // 靜態內部類
     static class Test
     {
      private int i ;
      public Test()
      {
       i = 2;
      }
     }
     class TestB
     {
      private int i = 3;
     }

     private int j;

     public static void main(String args[]) {
      
      // 靜態內部類(Inner Class)意味著1創建一個static內部類的對象,不需要一個外部類對象
      Aqiang.Test test = new Aqiang.Test();
      System.out.println("test" + test.i);
      
      // 而非靜態內部類,需要選創建一個外部類對象,然后才能創建內部內對象
      Aqiang aqiang = new Aqiang();
      Aqiang.TestB tb = aqiang.new TestB();
      System.out.println("testb" + tb.i);

     }
    }

    posted @ 2008-03-18 23:28 秋楓故事 閱讀(129) | 評論 (0)編輯 收藏

    Java IO中字節流和字符流的區別

     
    1
    流是一個有序的字節序列,可作為一個輸入源,也可作為一個輸出的目的地。
    字節流以字節為單位輸入輸出,字節流類名含有stream,字符流以字符為單位輸入輸出,字節流
    類名含有reader或writer.為了通用性,java中字符是16位的unicode字符,所以8位的字節流必
    須和16位的字符流進行轉換。字節流到字符流的轉換使用InputStreamReader類:
    public InputStreamReader(InputStream in);
    public InputStreamReader(InputStream in,String encoding);
    public OuputStreamWriter(OnputStream in);
    public OnputStreamWriter(OnputStream in,String encoding);
    Reader和Writer類允許用戶在程序中無縫的支持國際字符集,如果要讀區的文件是別國語言,
    要使用字符流。
    JavaI/O字節流與字符流就是java 實現輸入/輸出 數據 字節流是一個字節一個字節的輸入/輸出 數據 (兩個字節組成一個漢字)所以在用字節流讀一串漢字時會出現亂碼問題,
    同樣字符流是一個字符一個字符流(一個字符=兩個字節)的輸入/輸出 數據 用字符流讀一串漢字可以解決亂碼問題.

    posted @ 2008-03-18 18:24 秋楓故事 閱讀(5360) | 評論 (3)編輯 收藏

    實例:設備,設備類型,設備端口

    有以下三個對象:
    US設備對象:USDevie
    US設備類型對象:USDeviceModle
    US設備端口對象:USDevicePort
    class USDevice
    {
    ....
    // US設備類型
    USDeviceModel model;

    // US設備端口對象集合
    Set<USDevicePort> devicePortSet = new HashSet();

    }

    /**
    US設備類型說明每種設備都有不同的端口數目
    */
    class USDeviceModel
    {
    ....

    // 設備端口數目
    int deviceport;
    }

    class USDevicePort
    {
    private int deviceId;
    private int devicePort;
    }

                   1              :                    1                    :                    n
    一種US設備(device)----->設備類型(model)------>不同數目的設備端口
    US設備:設備類型:設備端口數目 = 1:1:n
    所以,如果新增設備的時候,要根據設備類型,得到相應的設備端口數目,
    然后在USDevicePort對應的數據庫表中插入記錄.
    編輯設備的時候,如果編輯了US設備類型,則相應的設備端口就會改變,這種
    情況除了更新USDevice對應的數據表中設備類型外,因為在USDevicePort表中
    存放在以前設備類型的端口記錄,所以應該先刪除之前的端口記錄,然后再插入
    現在類型所對應的端口記錄.
    其實只需:

    //這一步根據具體設備id,從數據庫中取出相應的設備對象
    USDevice device = .....

    // 得到US設備端口對象集合
    Set devicePortSet = device.getDevicePortSet();

    // 先清空以前所有的端口記錄
    devicePortSet.clear();

    // 根據編輯后類型ID,得到設備類型對象,并可以得到此種類型上的端口數目
    USDeviceModel usModle = ....


    // 根據上面得到的端口數據,構造"設備端口數目"對象,并把所有的設備端口對象添加到集合中

    //最后更新US設備


    這樣,每當編輯一個US設備的類型后,在設備端口表中,這種設備編輯之前的類型所對應的端口記錄
    就會被刪除,而保持只有新的設備類型端口記錄.

    注意在配置USDevice.hbm.xml文件時,要將<set name="devicePortSet " casecade="all-orphan-delete" .../>
    因為它會將和USDevice沒有關聯的對象從數據中刪除,這也與程序中devicePortSet.clear()相對應.

     

     

     


     

    posted @ 2008-03-14 23:53 秋楓故事 閱讀(378) | 評論 (0)編輯 收藏

    Hashtable真的能存儲對象嗎?

     

    看一看下面的很簡單的代碼,先是聲明了一個HashtableStringBuffer對象,然后分四次把StriingBuffer對象放入到Hashtable表中,在每次放入之前都對這個StringBuffer對象append()了一些新的字符串:

    package reference;

    import java.util.*;

    public class HashtableAdd{

        public static void main(String[] args){

            Hashtable ht = new Hashtable();

            StringBuffer sb = new StringBuffer();

            sb.append("abc,");

            ht.put("1",sb);    

            sb.append("def,");

            ht.put("2",sb);

            sb.append("mno,");

            ht.put("3",sb);

            sb.append("xyz.");

            ht.put("4",sb);

           

            int numObj=0;

            Enumeration it = ht.elements();

            while(it.hasMoreElements()){

                System.out.print("get StringBufffer "+(++numObj)+" from Hashtable: ");

                System.out.println(it.nextElement());

            }

        }

    }

    如果你認為輸出的結果是:
    get StringBufffer 1 from Hashtable: abc,
    get StringBufffer 2 from Hashtable: abc,def

    get StringBufffer 3 from Hashtable: abc,def,mno,
    get StringBufffer 4 from Hashtable: abc,def,mno,xyz.

    那么你就要回過頭再仔細看一看上一個問題了,把對象時作為入口參數傳給函數,實質上是傳遞了對象的引用,向Hashtable傳遞StringBuffer對象也是只傳遞了這個StringBuffer對象的引用!每一次向Hashtable表中put一次StringBuffer,并沒有生成新的StringBuffer對象,只是在Hashtable表中又放入了一個指向同一StringBuffer對象的引用而已。

    Hashtable表存儲的任何一個StringBuffer對象(更確切的說應該是對象的引用)的改動,實際上都是對同一個"StringBuffer"的改動。所以Hashtable并不能真正存儲能對象,而只能存儲對象的引用。也應該知道這條原則對與Hashtable相似的Vector, List, Map, Set等都是一樣的。

    上面的例程的實際輸出的結果是:

    /* RUN RESULT

    get StringBufffer 1 from Hashtable: abc,def,mno,xyz.

    get StringBufffer 2 from Hashtable: abc,def,mno,xyz.

    get StringBufffer 3 from Hashtable: abc,def,mno,xyz.

    get StringBufffer 4 from Hashtable: abc,def,mno,xyz.

    */

    posted @ 2008-03-14 10:45 秋楓故事 閱讀(573) | 評論 (0)編輯 收藏

    關于標簽

    在做編輯功能 的時候,往往會通過一個主鍵ID得到相應的對象信息,然后顯示到編輯頁面中。如果涉及到<html:select>標簽,
    表示點編輯的時候,選擇下拉框會顯示相應的選項。
    JSP頁面一般這樣顯示:
    <html:select property="busiSetId" style="width:120px;">
     <option value="">請選擇</option>
      <logic:present name="ret">
               <logic:iterate id="model" name="ret">
         <option value="<bean:write name="model" property="ID"/>"><bean:write name="model" property="name"/></option>
                </logic:iterate>
       </logic:present>
    </html:select>
    但這是樣子總是顯示第一條數據,解決這個問題最簡單的方法是在JSP頁面最后添加下面語句:
    <script language="javascript">
    document.all("busiSetId").value="<bean:write name='CustomerSetForm' property='busiSetId'/>";
    </script>

    因為這段代碼表示手動設置busiSetId元素,也就是<html:select>控件的值為要顯示的值,而且這個代碼是放到JSP最后面,
    每次都會執行。

    標簽嵌套使用注意事項:
    <logic:equal value="<bean:write name='customer' property='cusId'/>" >
    注意雙引號內只能使用單引號了。

    posted @ 2008-03-13 09:48 秋楓故事 閱讀(264) | 評論 (0)編輯 收藏

    項目中用到的JS代碼

    function addDev()
    {
     var sFeatures="dialogWidth:700px;dialogHeight:500px;scroll:no;";
     var customerId = document.all['cusId'].value;
     var result= window.showModalDialog('<%=appURL %>/businesspermit/DeviceSelectAction.do?formAction=toAddPage&customerId='+customerId,"",sFeatures);
     if(result!=null )
     {
      <logic:present name="edit" scope="request">
         document.CustomerSetForm.action="<%=appURL %>/businesspermit/CustomerSetAction.do?formAction=toEditBusi&showType=1";
      </logic:present>
       <logic:notPresent name="edit" scope="request">
       document.CustomerSetForm.action="<%=appURL %>/businesspermit/CustomerSetAction.do?formAction=getBusinessSet";
       </logic:notPresent>
      
      // window.location.reload();
      
      CustomerSetForm.submit();
     }
    }

    這個函數表示:添加新的設備JS函數,window.showModalDialog()會返回一個值result,如果result!=null,則刷新這個頁面。
    原來是用window.location.reload();刷新頁面的,但是這樣就不能保留之前頁面上輸入的數據,為了保留原來輸入的數據,換成了
    document.CustomerSetForm.action=“”;
    CustomerSetForm.submit();
    上面的語句表示:讓這個頁面重新指向另一個action地址,然后提交。這樣,用了Struts標簽后,以前四輸入的數據仍然會保留到返回后的頁面了。

    注意:在js代碼中,可能使用譬如說<logic:present>等標簽。

    posted @ 2008-03-13 09:37 秋楓故事 閱讀(291) | 評論 (0)編輯 收藏

    Comparator接口實例

    // 新建鏈表并加入元素
            List<Member> members=new ArrayList<Member>();  
            members.add(new Member("Andy",20));  
            members.add(new Member("Dell",23));
            members.add(new Member("Felex",24));
            members.add(new Member("Bill",21));
            members.add(new Member("Cindy",22));
            
            // 創建一個比較器匿名類
            Comparator comparator=new Comparator(){
              public int compare(Object op1,Object op2){
                Member memberOp1=(Member)op1;
                Member memberOp2=(Member)op2;
                
                // 按姓名排序
                return memberOp1.getName().compareTo(memberOp2.getName());
              }
            };
            
            // 排序
            Collections.sort(members,comparator);
            
            // 輸出排序后的鏈表
            for(Member member:members){
              System.out.println(member.getName() + ":" + member.getAge());
            }
             
          }

    輸出結果:
    Andy:20
    Bill:21
    Cindy:22
    Dell:23
    Felex:24

    posted @ 2008-03-12 17:25 秋楓故事 閱讀(321) | 評論 (0)編輯 收藏

    IE瀏覽器自動刷新

    當你做網頁時,是不是有的時候想讓你的網頁自動不停刷新,或者過一段時間自動跳轉到另外一個你自己設定的頁面?其實實現這個效果非常地簡單,而且這個效果甚至不能稱之為特效。你只要把如下代碼加入你的網頁中就可以了。

      1,頁面自動刷新:把如下代碼加入<head>區域中<meta http-equiv="refresh" content="20">,其中20指每隔20秒刷新一次頁面.

    posted @ 2008-03-12 17:20 秋楓故事 閱讀(1448) | 評論 (1)編輯 收藏

    關于window.opener

    window.opener 返回的是創建當前窗口的那個窗口的引用,比如點擊了a.htm上的一個鏈接而打開了b.htm,然后我們打算在b.htm上輸入一個值然后賦予a.htm上的一個id為“name”的textbox中,就可以寫為:

    window.opener.document.getElementById("name").value = "輸入的數據";

    posted @ 2008-03-12 17:15 秋楓故事 閱讀(178) | 評論 (0)編輯 收藏

    定時器改善

    以前的好像是用Timer類來實現的,后來的JDK有改善了:
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
      
      class RunnablTest implements Runnable
      {
       public void run()
       {
        System.out.println("ok");
       }
      }
      
        // 5秒后執行任務,每隔2秒執行一次任務:打印"ok"字符串
      executor.scheduleAtFixedRate(new RunnablTest(), 5, 2, TimeUnit.SECONDS);

    posted @ 2008-03-12 17:13 秋楓故事 閱讀(177) | 評論 (0)編輯 收藏

    many-to-many映射

    <class name="Person">
        <id name="id" column="personId">
            <generator class="native"/>
        </id>
        <set name="addresses" table="PersonAddress">
            <key column="personId"/>
            <many-to-many column="addressId"
                class="Address"/>
        </set>
    </class>

    <class name="Address">
        <id name="id" column="addressId">
            <generator class="native"/>
        </id>
    </class>
    create table Person ( personId bigint not null primary key )
    create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
    create table Address ( addressId bigint not null primary key )

    posted @ 2008-03-12 17:10 秋楓故事 閱讀(194) | 評論 (0)編輯 收藏

    java中棧(stack)與堆(heap)

     在java中內存分為“棧”和“堆”這兩種(Stack and Heap).基本數據類型存儲在“棧”中,對象引用類型實際存儲在“堆”中,在棧中只是保留了引用內存的地址值。
        順便說說“==”與“equals()方法”,以幫助理解兩者(Stack and Heap)的概念。
        在Java中利用"=="比較變量時候,系統使用變量在stack(棧)中所存的值來作為對比的依據,基本數據類型在stack中所存的值就是其內容值,而引用類型在stack中所存放的值是本身所指向Heap中對象的地址值。 Java.lang包中的Object類有public boolean equals (Object obj)方法。它比較兩個對象是否相等。僅當被比較的兩個引用指向同一對象時,對象的equals()方法返回true。(至于String類的equals()方法,是因為它重寫(override)equals()方法)

    posted @ 2008-03-12 17:06 秋楓故事 閱讀(321) | 評論 (0)編輯 收藏

    刪除HashMap中值注意事項

    java.util.Map m = new java.util.HashMap();
            m.put("aaa", "aaa ");
            m.put("bbb", " bbb");
            m.put("ccc", "ccc   ");

            Iterator iterator = m.keySet().iterator();
            while (iterator.hasNext())
            {
                String sessionId = (String) iterator.next();
                if ("aaa".equals(sessionId))
                {
                    // 這行代碼是關鍵
                    iterator.remove();
                }
            }

    posted @ 2008-03-12 16:57 秋楓故事 閱讀(355) | 評論 (0)編輯 收藏

    java初始化順序

    在一個類里,初始化的順序是由變量在類內的定義順序決定的。即使變量定義大量遍布于方法定義的中間,那些變量仍會在調用任何方法之前得到初始化——甚至在構建器調用之前。例如:
    class Tag {
      Tag(int marker) {
        System.out.println("Tag(" + marker + ")");
      }
    }

    class Card {
      Tag t1 = new Tag(1); // 先初始化t1
      Card() {
        // Indicate we're in the constructor:
        System.out.println("Card()");
        t3 = new Tag(33); // Re-initialize t3
      }
      Tag t2 = new Tag(2); // 然后初始化t2
      void f() {
        System.out.println("f()");
      }
      Tag t3 = new Tag(3); // 接著初始化t3
    }

    public class OrderOfInitialization {
      public static void main(String[] args) {
        Card t = new Card();
        t.f(); // Shows that construction is done
      }
    }

    它的輸入結果如下:
    "Tag(1)",
       "Tag(2)",
       "Tag(3)",
       "Card()",
       "Tag(33)",
       "f()"
    // 以下是人綜合例子:
    //總的原則:先靜態后動態,先定義初始化,后構造函數初始化
    /**
       * 實例化Child對象時
       * 先父類靜態成員初始化,后子類靜態成員初始化
       * 然后是父類成員,父類構造函數,最后是子類
       * 成員,子類構造函數
    */

    class Parent {
     private static int s = getS("父類靜態成員");

     private int num = getNum();

     public Parent() {
      System.out.println("父類構造函數");
     }

     private static int getS(String string) {
      System.out.println(string);
      return 47;
     }

     public int getNum() {
      System.out.println("父類私有成員");
      return num;
     }

     public static void setS(int s) {
      Parent.s = s;
     }

    }

    class Child extends Parent {
     private int num = prt("子類私有成員");

     private static int s = getS("子類靜態成員");

     public static void setS(int s) {
      Child.s = s;
     }

     public Child() {
      System.out.println("子類構造函數");
     }

     public void setNum(int num) {
      this.num = num;
     }

     private int prt(String string) {
      System.out.println(string);
      return 5;
     }

     public static int getS(String string) {
      System.out.println(string);
      return s;
     }
    }


    public class Tee {

     /**
      * @param args
      */
     public static void main(String[] args) {
      Child c = new Child();
      c.setNum(100);

      // 為什么輸出的是0
      System.out.print(c.getNum());

    //  Child cStatic = new Child();
    //  cStatic.setS(100);
    //  System.out.println(cStatic.getS("s"));
         


     }

    }

    最后輸出結果:
    父類靜態成員
    子類靜態成員
    父類私有成員
    父類構造函數
    子類私有成員
    子類構造函數
    父類私有成員
    0

    posted @ 2008-03-12 15:09 秋楓故事 閱讀(403) | 評論 (0)編輯 收藏

    JAVA集合類總結

     

    l       HashSet:如果集合中對象所屬的類重新定義了equals()方法,那么這個類也必須重新定義hashCode()方法,并且保證當兩個對象用equals()方法比較的結果為true時,這兩個對象的hashCode()方法的返回值相等。

    l       TreeSet:如果對集合中的對象進行自然排序,要求對象所屬的類實現Comparable接口,并且保證這個類的compareTo()equals()方法采用相同的比較規則來比較兩個對象是否相等。

    l       HashMap:如果集合中鍵對象所屬的類重新定義了equals()方法,那么這個類也必須重新定義hashCode()方法,并且保證當兩個鍵對象用equals()方法比較的結果為true時,這兩個鍵對象的hashCode()方法的返回值相等。

    l       TreeMap:如果對集合中的鍵對象進行自然排序,要求鍵對象所屬的類實現Comparable接口,并且保證這個類的compareTo()equals()方法采用相同的比較規則來比較兩個對象是否相等。

    由此可見,為了使應用程序更加健壯,在編寫JAVA類時不妨養這樣的編程習慣:

    l       如果JAVA類重新定義了equals()方法,那么這個類也必須重新定義hashCode()方法,并且保證當兩個對象用equals()方法比較的結果為true時,這兩個對象的hashCode()方法的返回值相等。

    l       如果JAVA類實現了Comparable接口,那么應該重新定義compareTo()equals()hashCode()方法,保證compareTo()equals()方法采用相同的比較規則來比較兩個對象是否相等,并且保證當兩個對象用equals()方法比較的結果為true時,這兩個對象的hashCode()方法的返回值相等。

    posted @ 2008-03-12 14:29 秋楓故事 閱讀(248) | 評論 (0)編輯 收藏

    (轉)使用java.text.SimpleDateFormat類進行文本日期和Date日期的轉換

    Date類內部既不存儲年月日也不存儲時分秒,而是存儲一個從1970年1月1日0點0分0秒開始的毫秒數,而真正有用的年月日時分秒毫秒都是從這個毫秒數轉化而來,這是它不容易被使用的地方,尤其是顯示和存儲的場合。但Date類的優勢在于方便計算和比較。
    另一點,日常生活中我們習慣用年月日時分秒這樣的文本日期來表示時間,它方便顯示和存儲,也容易理解,但不容易計算和比較。
    綜上所述,我們在程序中進行日期時間處理時經常需要在在文本日期和Date類之間進行轉換,為此我們需要借助java.text.SimpleDateFormat類來進行處理,下文列舉了它的幾個常用示例。

    1.將Date轉化為常見的日期時間字符串
    這里我們需要用到java.text.SimpleDateFormat類的format方法,其中可以指定年月日時分秒的模式字符串格式。
    Date date = new Date();
    Format formatter = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
    System.out.println("轉化的時間等于="+formatter.format(date));
    其中
    yyyy表示四位數的年份
    MM表示兩位數的月份
    dd表示兩位數的日期
    HH表示兩位數的小時
    mm表示兩位數的分鐘
    ss表示兩位數的秒鐘

    2.將文本日期轉化為Date以方便比較
    文本日期的優勢在于便于記憶,容易處理,但缺點是不方便比較,這時我們需要借助SimpleDateFormat的parse方法得到Date對象再進行比較,實例如下:
    String strDate1="2004年8月9日";
    String strDate2="2004年10月5日";

    SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");
    java.util.Date date1 = myFormatter.parse(strDate1);

    java.util.Date date2 = myFormatter.parse(strDate2);

    // Date比較能得出正確結果
    if(date2.compareTo(date1)>0){
          System.out.println(strDate2+">"+strDate1);
    }

    // 字符串比較得不出正確結果
    if(strDate2.compareTo(strDate1)>0){
          System.out.println(strDate2+">"+strDate1);
    }


    3.100天后的時間

           // 當前時間
            Date date = new Date();
            SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
            String str = formate.format(date);
            System.out.println("當前時間:"+str);
            Calendar c = Calendar.getInstance();
            c.setTime(date);

            // 100天后
            c.add(Calendar.DAY_OF_MONTH, 100);

            System.out.println("100天后時間:"+formate.format(c.getTime()));


    SimpleDateFormat 類字段:
    字母  日期或時間元素  表示  示例 
    G  Era 標志符  Text  AD 
    y  年  Year  1996; 96 
    M  年中的月份  Month  July; Jul; 07 
    w  年中的周數  Number  27 
    W  月份中的周數  Number  2 
    D  年中的天數  Number  189 
    d  月份中的天數  Number  10 
    F  月份中的星期  Number  2 
    E  星期中的天數  Text  Tuesday; Tue 
    a  Am/pm 標記  Text  PM 
    H  一天中的小時數(0-23)  Number  0 
    k  一天中的小時數(1-24)  Number  24 
    K  am/pm 中的小時數(0-11)  Number  0 
    h  am/pm 中的小時數(1-12)  Number  12 
    m  小時中的分鐘數  Number  30 
    s  分鐘中的秒數  Number  55 
    S  毫秒數  Number  978 
    z  時區  General time zone  Pacific Standard Time; PST; GMT-08:00 
    Z  時區  RFC 822 time zone  -0800 

    posted @ 2008-03-12 09:52 秋楓故事 閱讀(3323) | 評論 (0)編輯 收藏

    java面試基礎知識

    最近因為要換工作了,所以在網上找了一些java面試基礎知識:
    1.談談final, finally, finalize的區別
    final?修飾符(關鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。

      finally?在異常處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執行,然后控制就會進入 finally 塊(如果有的話)。

      finalize?方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。

    2.HashMap和Hashtable的區別
    HashMap與HashTable主要從三方面來說。
    一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
    二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
    三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value

    3.Collection 和 Collections的區別
    Collection是集合類的上級接口,繼承與他的接口主要有Set List.
    Collections
    是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作

    4.


    public class Hea {
     
     // 定義一個String沒有給予初始值,默認為null
     String a ;
     int i =3;
     
     // 覆蓋hashCode()方法
     public int hashCode() {
      
      return 12;
     }

     public static void main(String[] args) {
      Hea he = new Hea();
      
      // String數組默認為null
      String[] b = new String[3];
      
      System.out.println("a="+he.a);
      System.out.println(b[2]);
      
      System.out.println(he.hashCode());
      
      Object obj = (Object)he;
      
      Hea tmp = (Hea)obj;
      System.out.println(tmp.i);
      
      String h = "abc";
      String h2 = h;
      h = "bcd";
      System.out.println(h2);
     }
    }

    輸出結果:
    a=null
    null
    12
    3
    abc

    posted @ 2008-03-12 09:20 秋楓故事 閱讀(222) | 評論 (0)編輯 收藏

    <2008年3月>
    2425262728291
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    導航

    統計

    • 隨筆 - 63
    • 文章 - 0
    • 評論 - 14
    • 引用 - 0

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    新聞檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲中文字幕无码av在线| 免费看国产成年无码AV片| 好男人资源在线WWW免费| 婷婷国产偷v国产偷v亚洲| 亚洲av无码专区亚洲av不卡 | av无码久久久久不卡免费网站| 国产婷婷成人久久Av免费高清| 99在线免费视频| 中文无码成人免费视频在线观看| 怡红院免费全部视频在线视频| 中文字幕免费在线看电影大全| 成人免费一区二区三区| 最近免费mv在线观看动漫| 国产免费无码AV片在线观看不卡| a级毛片免费全部播放| 男人j进入女人j内部免费网站| 毛片在线全部免费观看| 18观看免费永久视频| 午夜宅男在线永久免费观看网| AV免费网址在线观看| 小小影视日本动漫观看免费 | 丝袜捆绑调教视频免费区| a国产成人免费视频| 日本免费一区二区三区 | 无码 免费 国产在线观看91| 精品多毛少妇人妻AV免费久久| 巨胸狂喷奶水视频www网站免费| 久久免费美女视频| 午夜免费1000部| 精品国产免费观看| 亚洲不卡AV影片在线播放| 人人狠狠综合久久亚洲婷婷| 久久亚洲国产成人精品性色| 亚洲中文字幕无码mv| 美女被爆羞羞网站在免费观看| 久久精品免费大片国产大片 | 自拍偷自拍亚洲精品偷一| 有码人妻在线免费看片| 免费91麻豆精品国产自产在线观看| 18级成人毛片免费观看| 免费va在线观看|