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

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

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

    posts - 55,comments - 89,trackbacks - 0
    oracle 10g默認需要微軟的網絡適配器配置。新建一個就行了。
    方法,打開控制面板,選者添加硬件—選擇是,我已經連接了此硬件,下一步選者最后一項添加新的硬件設備,下一步選擇 安裝我手動從列表選者的硬件(高級),下一步選者網絡適配器,下一步選者Microsoft Loopback
    Adapter,按向導提示下一步就行了。完成以后打開你的網上鄰居看看是不是多了一個網上連接(2),然后設置它的IP地址如。192.168.1.1.隨便就行了,這樣在安裝oracle的時候就可以用這一個假的網絡來連接,蒙騙一下 oracle了。一定可以驗證過去
    posted @ 2012-08-18 13:38 jiafang83 閱讀(915) | 評論 (0)編輯 收藏
        摘自:http://article.pchome.net/content-330924.html

           在過去幾年里,Hibernate不斷發展,幾乎成為Java數據庫持久性的事實標準。它非常強大、靈活,而且具備了優異的性能。在本文中,我們將了解如何使用Java 5 注釋來簡化Hibernate代碼,并使持久層的編碼過程變得更為輕松。

      傳統上,Hibernate的配置依賴于外部 XML 文件:數據庫映射被定義為一組 XML 映射文件,并且在啟動時進行加載。創建這些映射有很多方法,可以從已有數據庫模式或Java類模型中自動創建,也可以手工創建。無論如何,您最終將獲得大量的 Hibernate 映射文件。此外,還可以使用工具,通過javadoc樣式的注釋生成映射文件,盡管這樣會給您的構建過程增加一個步驟。

      在最近發布的幾個Hibernate版本中,出現了一種基于 Java 5 注釋的更為巧妙的新方法。借助新的 Hibernate Annotation 庫,即可一次性地分配所有舊映射文件——一切都會按照您的想法來定義——注釋直接嵌入到您的 Java 類中,并提供一種強大及靈活的方法來聲明持久性映射。籍由自動代碼完成和語法突出顯示功能,最近發布的Java IDE也為其提供了有力的支持。

      Hibernate Annotation還支持新的 EJB 3 持久性規范。這些規范旨在提供一種標準化的 Java 持久性機制。由于 Hibernate 3 還提供了一些擴展,因此您可以十分輕松地遵從這些標準,并使用 EJB 3 編程模型來對 Hibernate 持久層進行編碼。

      現在,讓我們來動手使用Hibernate Annotation。

    安裝 Hibernate Annotation

      要使用 Hibernate Annotation,您至少需要具備 Hibernate 3.2和Java 5。可以從 Hibernate 站點 下載 Hibernate 3.2 和 Hibernate Annotation庫。除了標準的 Hibernate JAR 和依賴項之外,您還需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。如果您正在使用 Maven,只需要向 POM 文件添加相應的依賴項即可,如下所示:

     ...
    
    org.hibernate
    hibernate
    3.2.1.ga
    
    
    org.hibernate
    hibernate-annotations
    3.2.0.ga
    
    
    javax.persistence
    persistence-api
    1.0
    
    ...
    

      下一步就是獲取 Hibernate 會話工廠。盡管無需驚天的修改,但這一工作與使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 類來建立會話工廠:

    sessionFactory = new
    AnnotationConfiguration().buildSessionFactory();

      盡管通常使用 元素來聲明持久性類,您還是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中聲明持久性類:

    
    
    
    
    
    
    

      近期的許多 Java 項目都使用了輕量級的應用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用 AnnotationSessionFactoryBean 類輕松建立一個基于注釋的 Hibernate 會話工廠,如下所示:

    
    
    
    
    
    
    
    org.hibernate.dialect.DerbyDialect
    create
    ...
    
    
    
    
    com.onjava.modelplanes.domain.PlaneType
    com.onjava.modelplanes.domain.ModelPlane
    ...
    
    
    
    

    第一個持久性類

      既然已經知道了如何獲得注釋所支持的 Hibernate 會話,下面讓我們來了解一下帶注釋的持久性類的情況:

      像在其他任何 Hibernate應用程序中一樣,帶注釋的持久性類也是普通 POJO。差不多可以說是。您需要向 Java 持久性 API (javax.persistence.*)添加依賴項,如果您正在使用任何特定于 Hibernate的擴展,那很可能就是 Hibernate Annotation 程序包(org.hibernate.annotations.*),但除此之外,它們只是具備了持久性注釋的普通 POJO 。下面是一個簡單的例子:

    @Entity
    public class ModelPlane {
    private Long id;
    private String name;
    @Id
    public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    }
    

      正像我們所提到的,這非常簡單。@Entity 注釋聲明該類為持久類。@Id 注釋可以表明哪種屬性是該類中的獨特標識符。事實上,您既可以保持字段(注釋成員變量),也可以保持屬性(注釋getter方法)的持久性。后文中將使用基于屬性的注釋。基于注釋的持久性的優點之一在于大量使用了默認值(最大的優點就是 “慣例優先原則(convention over configuration)”)。例如,您無需說明每個屬性的持久性——任何屬性都被假定為持久的,除非您使用 @Transient 注釋來說明其他情況。這簡化了代碼,相對使用老的 XML 映射文件而言也大幅地減少了輸入工作量。

    生成主鍵

      Hibernate 能夠出色地自動生成主鍵。Hibernate/EBJ 3 注釋也可以為主鍵的自動生成提供豐富的支持,允許實現各種策略。下面的示例說明了一種常用的方法,其中 Hibernate 將會根據底層數據庫來確定一種恰當的鍵生成策略:

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
    return id;
    }
    

    定制表和字段映射

      默認情況下,Hibernate 會將持久類以匹配的名稱映射到表和字段中。例如,前一個類可以與映射到以如下代碼創建的表中:

    CREATE TABLE MODELPLANE
    (
    ID long,
    NAME varchar
    )
    

      如果您是自己生成并維護數據庫,那么這種方法很有效,通過省略代碼可以大大簡化代碼維護。然而,這并不能滿足所有人的需求。有些應用程序需要訪問外部數據庫,而另一些可能需要遵從公司的數據庫命名慣例。如果有必要,您可以使用 @Table 和 @Column 注釋來定制您自己的持久性映射,如下所示:

    @Entity
    @Table(name="T_MODEL_PLANE")
    public class ModelPlane {
    private Long id;
    private String name;
    @Id
    @Column(name="PLANE_ID")
    public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }
    @Column(name="PLANE_NAME")
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    }
    

      該內容將映射到下表中:

    CREATE TABLE T_MODEL_PLANE
    (
    PLANE_ID long,
    PLANE_NAME varchar
    )
    

      也可以使用其他圖和列的屬性來定制映射。這使您可以指定諸如列長度、非空約束等詳細內容。Hibernate支持大量針對這些注釋的屬性。下例中就包含了幾種屬性:

     ...
    @Column(name="PLANE_ID", length=80, nullable=true)
    public String getName() {
    return name;
    }
    ...
    

    映射關系

      Java 持久性映射過程中最重要和最復雜的一環就是確定如何映射表間的關系。像其他產品一樣, Hibernate 在該領域中提供了高度的靈活性,但卻是以復雜度的增加為代價。我們將通過研究幾個常見案例來了解如何使用注釋來處理這一問題。

      其中一種最常用的關系就是多對一的關系。假定在以上示例中每個 ModelPlane 通過多對一的關系(也就是說,每個飛機模型只與一種飛機類型建立聯系,盡管指定的飛機類型可以與七種飛機模型建立聯系)來與 PlaneType 建立聯系。可如下進行映射:

     @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    public PlaneType getPlaneType() {
    return planeType;
    }
    

      CascadeType 值表明 Hibernate 應如何處理級聯操作。

      另一種常用的關系與上述關系相反:一對多再對一關系,也稱為集合。在老式的 Hibernate 版本中進行映射或使用注釋時,集合令人頭疼,這里我們將簡要加以探討,以使您了解如何處理集合,例如,在以上示例中每個 PlaneType 對象都可能會包含一個 ModelPlanes 集合。可映射如下:

     @OneToMany(mappedBy="planeType",
    cascade=CascadeType.ALL,
    fetch=FetchType.EAGER)
    @OrderBy("name")
    public List getModelPlanes() {
    return modelPlanes;
    }
    

    命名查詢

      Hibernate 最優秀的功能之一就在于它能夠在您的映射文件中聲明命名查詢。隨后即可通過代碼中的名稱調用此類查詢,這使您可以專注于查詢,而避免了 SQL 或者 HQL 代碼分散于整個應用程序中的情況。

      也可以使用注釋來實現命名查詢,可以使用 @NamedQueries 和 @NamedQuery 注釋,如下所示:

    @NamedQueries(
    {
    @NamedQuery(
    name="planeType.findById",
    query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
    ),
    @NamedQuery(
    name="planeType.findAll",
    query="select p from PlaneType p"
    ),
    @NamedQuery(
    name="planeType.delete",
    query="delete from PlaneType where id=:id"
    )
    }
    )
    

      一旦完成了定義,您就可以像調用其他任何其他命名查詢一樣來調用它們。

    結束語

      Hibernate 3 注釋提供了強大而精致的 API,簡化了 Java 數據庫中的持久性代碼,本文中只進行了簡單的討論。您可以選擇遵從標準并使用 Java 持久性 API,也可以利用特定于 Hibernate的擴展,這些功能以損失可移植性為代價提供了更為強大的功能和更高的靈活性。無論如何,通過消除對 XML 映射文件的需求,Hibernate 注釋將簡化應用程序的維護,同時也可以使您對EJB 3 有初步認識。來試試吧!

    posted @ 2009-07-26 14:00 jiafang83 閱讀(333) | 評論 (0)編輯 收藏
    摘自:http://www.javaeye.com/topic/95822

    school和userMember是一對多關系:

    SchoolInfo.java

     1import javax.persistence.CascadeType;   
     2import javax.persistence.Column;   
     3import javax.persistence.Entity;   
     4import javax.persistence.FetchType;   
     5import javax.persistence.GeneratedValue;   
     6import javax.persistence.Id;   
     7import javax.persistence.OneToMany;   
     8import javax.persistence.Table;   
     9import javax.persistence.Temporal;   
    10import javax.persistence.TemporalType;   
    11   
    12import org.hibernate.annotations.Formula;   
    13import org.hibernate.annotations.GenericGenerator;   
    14   
    15@Entity   
    16@Table(name = "school_info")   
    17public class SchoolInfo implements java.io.Serializable {   
    18   
    19    @Id   
    20    @GeneratedValue(generator = "system-uuid")   
    21    @GenericGenerator(name = "system-uuid", strategy = "uuid")   
    22    private String id;//hibernate的uuid機制,生成32為字符串   
    23   
    24    @Column(name = "actcodeId", updatable = false, nullable = true, length = 36)   
    25    private String actcodeId;   
    26   
    27    @Formula("select COUNT(*) from school_info")   
    28    private int count;   
    29   
    30    @Temporal(TemporalType.TIMESTAMP)//不用set,hibernate會自動把當前時間寫入   
    31    @Column(updatable = false, length = 20)   
    32    private Date createTime;   
    33   
    34    @Temporal(TemporalType.TIMESTAMP)   
    35    private Date updateTime;// 剛開始我默認insertable=false,但會讀取出錯提示如下:   
    36    // Value '0000-00-00' can not be represented as java.sql.Timestamp   
    37   
    38    // mappedBy="school"就相當于inverse=true,(mappedBy指定的是不需要維護關系的一端)   
    39    // 應該注意的是mappedBy值對應@ManyToOne標注的屬性,我剛開始寫成"schoolId",讓我郁悶了好一會 
    40    @OneToMany(mappedBy = "school", cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = UserMember.class)   
    41    // 用范性的話,就不用targetEntity了   
    42    private List<usermember> users = </usermember>new ArrayList<usermember>();  </usermember> 
    43       
    44}
       
    45

    @GeneratedValue(strategy=GenerationType.AUTO)我們常用的自增長機制,我這里采用的是hibernate的uuid生成機制.
    需要注意的是import javax.xx.Entity ,而不是org.hibernate.xx.Entity。

    郁悶的是我上面用到@Formula,生成的sql竟然是'select COUNT(*) from school_info as formula0_ from school_info schoolinfo0_,當然不能執行了,尋求正解中~!!!!!!!!!

    UserMember.java(前面引入的包已經貼過了,下面就不貼了)
     1 @Entity   
     2 @Table(name = "teacher_info")//實體類和數據庫表名不一致時,才用這個   
     3 public class UserMember implements java.io.Serializable {   
     4    
     5     @Id   
     6     @GeneratedValue(generator = "system-uuid")   
     7     @GenericGenerator(name = "system-uuid", strategy = "uuid")   
     8     private String id;   
     9    
    10     @Column(updatable = false, nullable = false, length = 20)   
    11     private String logonName;   
    12        
    13     @Temporal(TemporalType.TIMESTAMP)   
    14     @Column(updatable = false, length = 20)   
    15     private Date createTime;   
    16    
    17     @Temporal(TemporalType.TIMESTAMP)   
    18     private Date updateTime;   
    19    
    20     @ManyToOne(cascade = { CascadeType.MERGE })   
    21     @JoinColumn(name = "schoolId")   
    22     private SchoolInfo school;   
    23     //注意該類就不用聲明schoolId屬性了,如果不用@JoinColumn指明關聯的字段,hibernate默認會是school_id.   
    24    
    25 }   

    posted @ 2009-07-26 13:40 jiafang83 閱讀(3185) | 評論 (1)編輯 收藏
    posted @ 2009-07-20 22:31 jiafang83 閱讀(257) | 評論 (0)編輯 收藏
    轉載:http://www.cnblogs.com/Truly/archive/2006/12/31/608896.html

    JSON定義

        JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,易于閱讀和編寫,同時也易于機器解析和生成。它基于ECMA262語言規范(1999-12第三版)中JavaScript編程語言的一個子集。 JSON采用與編程語言無關的文本格式,但是也使用了類C語言(包括C, C++, C#, Java, JavaScript, Perl, Python等)的習慣,這些特性使JSON成為理想的數據交換格式。

    JSON的結構基于下面兩點

    • 1. "名稱/值"對的集合 不同語言中,它被理解為對象(object),記錄(record),結構(struct),字典(dictionary),哈希表(hash table),鍵列表(keyed list)等
    • 2. 值的有序列表 多數語言中被理解為數組(array)
    JSON使用

    JSON以一種特定的字符串形式來表示 JavaScript 對象。如果將具有這樣一種形式的字符串賦給任意一個 JavaScript 變量,那么該變量會變成一個對象引用,而這個對象就是字符串所構建出來的,好像有點拗口,我們還是用實例來說明。

     這里假設我們需要創建一個User對象,并具有以下屬性

  • 用戶ID
  • 用戶名
  • 用戶Email

    您可以使用以下JSON形式來表示User對象:

    {"UserID":11, "Name":"Truly", "Email":"zhuleipro◎hotmail.com"};

    然后如果把這一字符串賦予一個JavaScript變量,那么就可以直接使用對象的任一屬性了。

    完整代碼:

    <script>
    var User = {"UserID":11, "Name":"Truly", "Email":"zhuleipro◎hotmail.com"}; alert(User.Name); </script>

    實際使用時可能更復雜一點,比如我們為Name定義更詳細的結構,使它具有FirstName和LastName:

    {"UserID":11, "Name":{"FirstName":"Truly","LastName":"Zhu"}, "Email":"zhuleipro◎hotmail.com"}

    完整代碼:

    <script>
    var User = {"UserID":11, "Name":{"FirstName":"Truly","LastName":"Zhu"}, "Email":"zhuleipro◎hotmail.com"}; alert(User.Name.FirstName); </script>

    現在我們增加一個新的需求,我們某個頁面需要一個用戶列表,而不僅僅是一個單一的用戶信息,那么這里就需要創建一個用戶列表數組。
    下面代碼演示了使用JSON形式定義這個用戶列表:

    [
    {"UserID":11, "Name":{"FirstName":"Truly","LastName":"Zhu"}, "Email":"zhuleipro◎hotmail.com"},
    {"UserID":12, "Name":{"FirstName":"Jeffrey","LastName":"Richter"}, "Email":"xxx◎xxx.com"},
    {"UserID":13, "Name":{"FirstName":"Scott","LastName":"Gu"}, "Email":"xxx2◎xxx2.com"}
    ]


    完整代碼:

    <script>
    var UserList = [
    {"UserID":11, "Name":{"FirstName":"Truly","LastName":"Zhu"}, "Email":"zhuleipro◎hotmail.com"},
    {"UserID":12, "Name":{"FirstName":"Jeffrey","LastName":"Richter"}, "Email":"xxx◎xxx.com"},
    {"UserID":13, "Name":{"FirstName":"Scott","LastName":"Gu"}, "Email":"xxx2◎xxx2.com"}
    ];
    alert(UserList[0].Name.FirstName);
    </script>

    事實上除了使用"."引用屬性外,我們還可以使用下面語句:

    alert(UserList[0]["Name"]["FirstName"]); 或者 alert(UserList[0].Name["FirstName"]); 

    現在讀者應該對JSON的使用有點認識了,歸納為以下幾點:

  • 對象是屬性、值對的集合。一個對象的開始于“{”,結束于“}”。每一個屬性名和值間用“:”提示,屬性間用“,”分隔。
  • 數組是有順序的值的集合。一個數組開始于"[",結束于"]",值之間用","分隔。
  • 值可以是引號里的字符串、數字、true、false、null,也可以是對象或數組。這些結構都能嵌套。
  • 字符串和數字的定義和C或Java基本一致。

    小節

    本文通過一個實例演示,初步了解了JSON 的強大用途。可以歸結如下:

  • JSON 提供了一種優秀的面向對象的方法,以便將元數據緩存到客戶機上。
  • JSON 幫助分離了驗證數據和邏輯。
  • JSON 幫助為 Web 應用程序提供了 Ajax 的本質。
  • posted @ 2009-06-16 01:03 jiafang83 閱讀(330) | 評論 (0)編輯 收藏
     轉載:http://blog.csdn.net/sdlcn/

    前提 OS: WIN2000
         tomcat已經配置好(tomcat可以到http://jakarta.apache.org/tomcat 下載)
    開始實戰啦
    1.準備jstl
       到http://apache.towardex.com/jakarta/taglibs/standard/下載jakarta-taglibs-standard-current.zip
    解壓后成為jakarta-taglibs-standard-1.1.1

    2.準備web開發目錄
       比如我的web目錄為h:\webapp\myweb\(當然可以把你的web應用放在%tomcat_home%\webapps\),稱為工作目錄Working folder,在工作目錄h:\webapp\myweb\下建立WEB-INF\lib,WEB-INF\classes

    3.拷貝.jar文件
       將jakarta-taglibs-standard-1.1.1\lib\下的兩個jar文件:standard.jar和jstl.jar文件拷貝到\WEB-INF\lib\下

    4.拷貝.tld文件
     將jakarta-taglibs-standard-1.1.1\tld\下的8個tld類型文件拷到"Working folder\WEB-INF\"下

    5.在\WEB-INF\下建立web.xml文件:
      <?xml version="1.0" encoding="ISO-8859-1"?>

    <web-app 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"
        version="2.4">
     
      <taglib>
        <taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>
        <taglib-location>/WEB-INF/fmt.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/fmt-rt</taglib-uri>
        <taglib-location>/WEB-INF/fmt-rt.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
        <taglib-location>/WEB-INF/c.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/core-rt</taglib-uri>
        <taglib-location>/WEB-INF/c-rt.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/sql</taglib-uri>
        <taglib-location>/WEB-INF/sql.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/sql-rt</taglib-uri>
        <taglib-location>/WEB-INF/sql-rt.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/x</taglib-uri>
        <taglib-location>/WEB-INF/x.tld</taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>http://java.sun.com/jstl/x-rt</taglib-uri>
        <taglib-location>/WEB-INF/x-rt.tld</taglib-location>
    </taglib>

    </web-app>
    6.建立一個名為test.jsp文件
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <%@ page contentType="text/html;charset=GB2312" %>
    <%@ taglib prefix="c" uri="
    http://java.sun.com/jsp/jstl/core"%>
    <html>
    <head>
    <title>測試你的第一個使用到JSTL 的網頁</title>
    </head>
    <body>
    <c:out value="歡迎測試你的第一個使用到JSTL 的網頁"/>
    </br>你使用的瀏覽器是:</br>
    <c:out value="${header['User-Agent']}"/>
    <c:set var="a" value="David O'Davies" />
    <c:out value="David O'Davies" escapeXml="true"/>
    </body>
    </html>

    7.開啟tomcat,進行調試,我的輸出結果是

    歡迎測試你的第一個使用到JSTL 的網頁
    你使用的瀏覽器是:
    Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) David O'Davies

    posted @ 2009-06-14 18:02 jiafang83 閱讀(856) | 評論 (0)編輯 收藏

    轉載:http://blog.csdn.net/mtzai/archive/2009/05/24/4212490.aspx

    在大多數情況下,為事件處理函數返回false,可以防止默認的事件行為.例如,默認情況下點擊一個<a>元素,頁面會跳轉到該元素href屬性指定的頁.
     Return False 就相當于終止符,Return True 就相當于執行符。

    在js中return false的作用一般是用來取消默認動作的。比如你單擊一個鏈接除了觸發你的
    onclick時間(如果你指定的話)以外還要觸發一個默認事件就是執行頁面的跳轉。所以如果
    你想取消對象的默認動作就可以return false。return false應用比較多的場合有:
    <form name="form1"  onsubmIT="return youfunction();">...... </form>
    <a href="www.***.com" onclick="...;return false;">dddd </a>    .

    <script>
    function test()
    {
      alert("test");
      return false();
    }
    </script>

    </head>

    <body>
    1, <a href='a.JSP' onclick='test();'>超級鏈接 </a>
    2, <input type="button" onclick='test()' value="提交">
    3, <form name="form1"  onsubmIT="return test();">
    內容
    <input type="submIT" value="提交">
    </form>
    </body>

    <a href="xxxx.do?....." target=dolink>連接abcd </a>
    <iframe id=dolink src=about:blank style=display:none> </iframe>

     
    點了上面的那個連接后,dolink幀執行頁面處理的事情(xxxx.do?...然傳遞參數到服務器),頁面不會跳轉。    .

    最近做的項目,通過綁定在 button 的 onclick 事件的函數提交表單。發現 return false 也是很重要的。比如:

     <input type="submit" onclick="submitAction(); return false;" />

     submitAction 方法里面有提交表單的動作。如果不加 return false,在執行完 submitAction 之后,submit 按鈕還會繼續執行它的默認事件,就會再次提交表單。這可能就是很多錯誤的根源。

    的確,return false的含義不是阻止事件繼續向頂層元素傳播,而是阻止瀏覽器對事件的默認處理。你可以這樣試驗:首先將所有的js腳本注釋掉,在IE瀏覽器中嘗試拖動一下圖片,你會發現鼠標會成為禁止操作的樣式,圖片是被禁止拖動的,它是瀏覽器針對mousemove事件所提供的默認行為。return false就是為了去掉這種行為,否則就會出現你描述的中斷事件連續執行。

    另外,和return false等效的語句為:window.event.returnValue = false,你可以把return false替換為此語句并進行驗證。

    最后說明一下,此種方式只適用于IE瀏覽器。

    <html>
    <head>
    <script language="javascript">
    function verifyForm(){
    var ass=document.getElementsByName("assetName");
    if(ass[0].value.length==0){
    alert("名稱輸入為空!");
    return false;
    }

    if(ass[0].value.length>15){
    alert("名稱輸入長度不能超過15個字符!");
    return false;
    }
    }
    </script>
    </head>
    <body>
    <form name="xx">
    <input name="assetName" type="text"/>
                            <--根據return 返回值的TRUE或FALSE 判定是否提交表單--->
    <input type="submit" onclick="return verifyForm()"/>
    </form>
    </body>
    </html>

    潛水看了眾大蝦的精彩帖子,今也貢獻一點心得。其聞共欣賞,疑義相與析。有不對之處請不吝拍磚。

    眾所周知,在表單中加上onsubmit="return false;"可以阻止表單提交。
    下面是簡單的一小段代碼:

    view plaincopy to clipboardprint?
    <form action="index.jsp" method="post" onsubmit="submitTest();;">  
        <INPUT value="www">  
        <input type="submit" value="submit">  
    </form>  
     
    <SCRIPT LANGUAGE="JavaScript">  
    <!--  
        function submitTest(); {  
            // 一些邏輯判斷  
         return false;  
        }  
    //-->  
    </SCRIPT> 

    <form action="index.jsp" method="post" onsubmit="submitTest();;">
        <INPUT value="www">
        <input type="submit" value="submit">
    </form>

    <SCRIPT LANGUAGE="JavaScript">
    <!--
        function submitTest(); {
            // 一些邏輯判斷
         return false;
        }
    //-->
    </SCRIPT>
    大家判斷像上面的寫法,點擊submit按鈕該表單是否提交?

    若答案為是,就不用往下看了。

    若答案為否,錯了。實際情況是表單正常提交,若想它不提交,應該將

    view plaincopy to clipboardprint?
    <form action="index.jsp" method="post" onsubmit="submitTest();;"> 

    <form action="index.jsp" method="post" onsubmit="submitTest();;">改為

    view plaincopy to clipboardprint?
    <form action="index.jsp" method="post" onsubmit="return submitTest();;"> 

    <form action="index.jsp" method="post" onsubmit="return submitTest();;">

    為何?

    原來onsubmit屬性就像是<form>這個html對象的一個方法名,其值(一字符串)就是其方法體,默認返回true;

    和Java一樣,在該方法體中你可以寫任意多個語句,包括內置函數和自定義函數,如

    view plaincopy to clipboardprint?
    onsubmit="  
        alert('haha');; // 內置函數   
        submitTest();;  // 自定義函數  
        alert(this.tagName);; // 用到了this關鍵詞  
        ......(任意多條語句);      
        return false;  

    onsubmit="
        alert('haha');; // 內置函數
        submitTest();;  // 自定義函數
        alert(this.tagName);; // 用到了this關鍵詞
        ......(任意多條語句);   
        return false;
    "
    就相當于

    view plaincopy to clipboardprint?
    Form.prototype.onsubmit = function(); {  
        alert('haha');; // 內置函數  
        submitTest();;  // 自定義函數  
        alert(this.tagName);; // 用到了this關鍵詞  
        ......(任意多條語句);      
        return false;  
    }; 

    Form.prototype.onsubmit = function(); {
        alert('haha');; // 內置函數
        submitTest();;  // 自定義函數
        alert(this.tagName);; // 用到了this關鍵詞
        ......(任意多條語句);   
        return false;
    };
    這樣的話你就覆寫了(override)其默認方法(默認返回true)
    大家注意到方法體中可以用this這個關鍵詞,這里即代表了<form>的對象實例。

    經過這樣的分析后,以上情況就不難理解了:

    view plaincopy to clipboardprint?
    <form action="index.jsp" method="post" onsubmit="submitTest();;"> 

    <form action="index.jsp" method="post" onsubmit="submitTest();;">這樣寫,override方法的效果為:

    view plaincopy to clipboardprint?
    Form.prototype.onsubmit = function(); {  
        submitTest();;  
    }; 

    Form.prototype.onsubmit = function(); {
        submitTest();;
    };
    在這里submitTest()雖然返回false,但我們只執行了此函數,沒有對其結果進行任何處理。而

    view plaincopy to clipboardprint?
    <form action="index.jsp" method="post" onsubmit="return submitTest();;"> 

    <form action="index.jsp" method="post" onsubmit="return submitTest();;">
    override方法的效果為:

    view plaincopy to clipboardprint?
    Form.prototype.onsubmit = function(); {  
        return submitTest();;  
    }; 

    Form.prototype.onsubmit = function(); {
        return submitTest();;
    };
    這樣,我們利用到了它的返回值,達到了預期效果。
    這樣理解的話我想印象會深刻得多,就不易出錯了

    結論:
    我們可以用Java里的思維方式來思考模擬JavaScript中的類似情況(JavaScript中基于prototype的面向對象技術也確實是這樣做的),但他們畢竟還是有本質上的區別,如Java是強類型的,有嚴格的語法限制,而JavaScript是松散型的。象上述方法:

    view plaincopy to clipboardprint?
    Form.prototype.onsubmit = function(); {    
    }; 

    Form.prototype.onsubmit = function(); { 
    };
    既可以有返回值,又可以沒有返回值,在Java里是通不過的,畢竟Java里面不能靠方法的返回值不同來重載(overload)方法,而JavaScript中的重載要松散得多。

    posted @ 2009-06-13 23:52 jiafang83 閱讀(1347) | 評論 (0)編輯 收藏

    一、 簡單的對比

    request.getParameter用的比較多,相對熟悉

    request.getParameterValues(String   name)是獲得如checkbox類(名字相同,但值有多個)的數據。   接收數組變量 ,如checkobx類型    
    request.getParameter(String   name)是獲得相應名的數據,如果有重復的名,則返回第一個的值 . 接收一般變量 ,如text類型

    例:

    1. 三個名字相同的text標簽


    <input type="text" name="test" value="1" />
    <input type="text" name="test" value="2" />
    <input type="text" name="test" value="3" />

    request.getParameterValues("test")   ----------------- [1, 2, 3]

    request.getParameter("test")             ------------------ 1

    ${paramValues.test}

    ${param.test}

    2. checkbox

     <input type="checkbox" name="habit" value="read">看書

     <input type="checkbox" name="habit" value="movie">電影

     <input type="checkbox" name="habit" value="game">游戲

    request.getParameterValues("habit")

    二、與此相關的話題------隱含對象

    1. JSP隱含對象(Implicit Object)


         所謂隱含對象,是指當編寫jsp網頁時,不必做任何聲明就可以直接使用的對象。 JSP2.0定義了九個隱含對象

    request response pageContext session application out conifg page exception

    這里只提一下request 和 response 兩個對象

           request 對象表示客戶端請求的內容,比如我們從request中取得了用戶輸入的內容,實現了javax.servlet.http.HttpServletRequest接口

          response對象表示響應客戶端的結果。

    上面我們使用了request的兩個方法getParameter 和 getParameterValues,其實request還有其他幾個比較重要的方法,這里只涉及幾個獲取請求參數的方法

    String getParameter(String name)                     取得name的參數值

    String[] getParameterValues(String name)        取得所有name的參數值

    Enumeration getParameterNames()                  取得所有的參數名稱

    Map<String, String[]> getParameterMap()        取得request的所有參數的一個映射

    //

    Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.
    Returns:
    an immutable java.util.Map containing parameter names as keys and parameter values as map values. The keys in the parameter map are of type String. The values in the parameter map are of type String array.
    //

    response等其他幾個隱含對象也有非常重要的身份,有機會專門整理一下,宣揚一下它們的顯赫地位。

    2. EL隱含對象

    EL即Experssion Language,自JSP2.0后正式成為JSP的標準規范之一,支持Servlet2.4/JSP2.0的Container也就相應的支持EL語法。

    一個常見的形式如,<c:out value="${ 3 + 7 * 4}" />

    EL的隱藏對象有11個 PageContext PageScope RequestScope sessionScope applicationScope

    param paramValues header headerValues cookie initParam

    其中param 和 paramValues即對相應ServletRequest.getParameter(String name)和ServletRequest.getParameterValues(String name)

     

    轉載:http://blog.csdn.net/moreorless/archive/2009/05/18/4199677.aspx

    posted @ 2009-06-12 14:53 jiafang83 閱讀(745) | 評論 (0)編輯 收藏

    轉載:http://www.sucai.com/Tech/List2/17830.htm

    javascript是弱類型的語言,所以強制類型轉換還是比較重要的,下面看一下它的幾個強制轉換的函數:

    1. Boolean(value):把值轉換成Boolean類型;

    2. Nnumber(value):把值轉換成數字(整型或浮點數);

    3. String(value):把值轉換成字符串。

    我們先來看Boolean():在要轉換的值為“至少有一字符的字符串”、“非0的數字”或“對象”,那么Boolean()將返回true,如果要轉換的值為“空字符串”、“數字0”、“undefined”,“null”這些話,那么Boolean()會返回false。你可以用以下代碼來測試

    var t1 = Boolean("");//返回false,空字符串
    var t2 = Boolean("s");//返回true,非空字符串
    var t3 = Boolean(0);//返回false,數字0
    var t3 = Boolean(1),t4 = Boolean(-1);//返回true,非0數字
    var t5 = Boolean(null),t6 = Boolean(undefined);//返回false
    var t7 = Boolean(new Object());//返回true,對象

    再來看看Number():Number()與parseInt()和parseFloat()類似,它們區別在于Number()轉換是整個值,而parseInt()和parseFloat()則可以只轉換開頭的數字部分,例如:Number("1.2.3"),Number("123abc")會返回NaN,而parseInt("1.2.3")返回1、parseInt("123abc")返回123、parseFloat("1.2.3")返回1.2、parseFloat("123abc")返回123。Number()會先判斷要轉換的值能否被完整的轉換,然后再判斷是調用parseInt()或parseFloat()。下面列了一些值調用Number()之后的結果:

    Number(false)  0
    Number(true)  1
    Number(undefined)  NaN
    Number(null)  0
    Number("1.2")  1.2

    Number("12")  12
    Number("1.2.3")  NaN
    Number(new Object())  NaN
    Number(123)  123

    最后是String():這個以比較簡單了,它可以把所有類型的數據轉換成字符串,如:String(false)---"false"、String(1)---"1"。它和toString()方法有些不同,區別在于:

    var t1 = null;
    var t2 = String(t1);//t2的值 "null"
    var t3 = t1.toString();//這里會報錯
    var t4;
    var t5 = String(t4);//t5的值 "undefined"
    var t6 = t4.toString();//這里會報錯

    posted @ 2009-06-09 16:03 jiafang83 閱讀(9629) | 評論 (2)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-06-08 14:28 jiafang83 閱讀(2192) | 評論 (3)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-06-05 15:52 jiafang83 閱讀(21690) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-06-02 16:58 jiafang83 閱讀(1741) | 評論 (0)編輯 收藏
         摘要:   閱讀全文
    posted @ 2009-06-02 16:50 jiafang83 閱讀(1562) | 評論 (0)編輯 收藏
    轉載:http://www.javaeye.com/topic/53526

    1、使用JdbcTemplate的execute()方法執行SQL語句
    Java代碼 復制代碼
    1. jdbcTemplate.execute("CREATE TABLE USER (user_id integer, name varchar(100))");  

    2、如果是UPDATE或INSERT,可以用update()方法。
    Java代碼 復制代碼
    1. jdbcTemplate.update("INSERT INTO USER VALUES('"  
    2.            + user.getId() + "', '"  
    3.            + user.getName() + "', '"  
    4.            + user.getSex() + "', '"  
    5.            + user.getAge() + "')");  

    3、帶參數的更新
    Java代碼 復制代碼
    1. jdbcTemplate.update("UPDATE USER SET name = ? WHERE user_id = ?"new Object[] {name, id});  

    Java代碼 復制代碼
    1. jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)"new Object[] {user.getId(), user.getName(), user.getSex(), user.getAge()});  

    4、使用JdbcTemplate進行查詢時,使用queryForXXX()等方法
    Java代碼 復制代碼
    1. int count = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM USER");  


    Java代碼 復制代碼
    1. String name = (String) jdbcTemplate.queryForObject("SELECT name FROM USER WHERE user_id = ?"new Object[] {id}, java.lang.String.class);  


    Java代碼 復制代碼
    1. List rows = jdbcTemplate.queryForList("SELECT * FROM USER");  


    Java代碼 復制代碼
    1. List rows = jdbcTemplate.queryForList("SELECT * FROM USER");   
    2. Iterator it = rows.iterator();   
    3. while(it.hasNext()) {   
    4.     Map userMap = (Map) it.next();   
    5.     System.out.print(userMap.get("user_id") + "\t");   
    6.     System.out.print(userMap.get("name") + "\t");   
    7.     System.out.print(userMap.get("sex") + "\t");   
    8.     System.out.println(userMap.get("age") + "\t");   
    9. }  


       JdbcTemplate將我們使用的JDBC的流程封裝起來,包括了異常的捕捉、SQL的執行、查詢結果的轉換等等。spring大量使用Template Method模式來封裝固定流程的動作,XXXTemplate等類別都是基于這種方式的實現。
        除了大量使用Template Method來封裝一些底層的操作細節,spring也大量使用callback方式類回調相關類別的方法以提供JDBC相關類別的功能,使傳統的JDBC的使用者也能清楚了解spring所提供的相關封裝類別方法的使用。

    JDBC的PreparedStatement
    Java代碼 復制代碼
    1. final String id = user.getId();   
    2. final String name = user.getName();   
    3. final String sex = user.getSex() + "";   
    4. final int age = user.getAge();   
    5.   
    6. jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)",   
    7.                      new PreparedStatementSetter() {   
    8.                          public void setValues(PreparedStatement ps) throws SQLException {   
    9.                              ps.setString(1, id);   
    10.                              ps.setString(2, name);             
    11.                              ps.setString(3, sex);   
    12.                              ps.setInt(4, age);   
    13.                          }   
    14.                      });  


    Java代碼 復制代碼
    1. final User user = new User();   
    2. jdbcTemplate.query("SELECT * FROM USER WHERE user_id = ?",   
    3.                     new Object[] {id},   
    4.                     new RowCallbackHandler() {   
    5.                         public void processRow(ResultSet rs) throws SQLException {   
    6.                             user.setId(rs.getString("user_id"));   
    7.                             user.setName(rs.getString("name"));   
    8.                             user.setSex(rs.getString("sex").charAt(0));   
    9.                             user.setAge(rs.getInt("age"));   
    10.                         }   
    11.                     });  




    Java代碼 復制代碼
    1. class UserRowMapper implements RowMapper {   
    2.     public Object mapRow(ResultSet rs, int index) throws SQLException {   
    3.         User user = new User();   
    4.   
    5.         user.setId(rs.getString("user_id"));   
    6.         user.setName(rs.getString("name"));   
    7.         user.setSex(rs.getString("sex").charAt(0));   
    8.         user.setAge(rs.getInt("age"));   
    9.   
    10.         return user;   
    11.     }   
    12. }   
    13.   
    14. public List findAllByRowMapperResultReader() {   
    15.     String sql = "SELECT * FROM USER";   
    16.     return jdbcTemplate.query(sql, new RowMapperResultReader(new UserRowMapper()));   
    17. }  


    在getUser(id)里面使用UserRowMapper
    Java代碼 復制代碼
    1. public User getUser(final String id) throws DataAccessException {   
    2.     String sql = "SELECT * FROM USER WHERE user_id=?";   
    3.     final Object[] params = new Object[] { id };   
    4.     List list = jdbcTemplate.query(sql, params, new RowMapperResultReader(new UserRowMapper()));   
    5.   
    6.     return (User) list.get(0);   
    7. }  


    網上收集
    org.springframework.jdbc.core.PreparedStatementCreator 返回預編譯SQL   不能于Object[]一起用
    Java代碼 復制代碼
    1. public PreparedStatement createPreparedStatement(Connection con) throws SQLException {   
    2.  return con.prepareStatement(sql);   
    3. }  

    1.增刪改
    org.springframework.jdbc.core.JdbcTemplate   類(必須指定數據源dataSource)
    Java代碼 復制代碼
    1. template.update("insert into web_person values(?,?,?)",Object[]);  

      或
    Java代碼 復制代碼
    1. template.update("insert into web_person values(?,?,?)",new PreparedStatementSetter(){ 匿名內部類 只能訪問外部最終局部變量   
    2.   
    3.  public void setValues(PreparedStatement ps) throws SQLException {   
    4.   ps.setInt(index++,3);   
    5. });  

    org.springframework.jdbc.core.PreparedStatementSetter 接口 處理預編譯SQL
    Java代碼 復制代碼
    1. public void setValues(PreparedStatement ps) throws SQLException {   
    2.  ps.setInt(index++,3);   
    3. }  

    2.查詢JdbcTemplate.query(String,[Object[]/PreparedStatementSetter],RowMapper/RowCallbackHandler)
    org.springframework.jdbc.core.RowMapper   記錄映射接口  處理結果集
    Java代碼 復制代碼
    1. public Object mapRow(ResultSet rs, int arg1) throws SQLException {   int表當前行數   
    2.   person.setId(rs.getInt("id"));   
    3. }   
    4. List template.query("select * from web_person where id=?",Object[],RowMapper);  

    org.springframework.jdbc.core.RowCallbackHandler  記錄回調管理器接口 處理結果集
    Java代碼 復制代碼
    1. template.query("select * from web_person where id=?",Object[],new RowCallbackHandler(){   
    2.  public void processRow(ResultSet rs) throws SQLException {   
    3.   person.setId(rs.getInt("id"));   
    4. });  
    posted @ 2009-05-26 15:06 jiafang83| 編輯 收藏

        DecimalFormatNumberFormat 的一個具體子類,用于格式化十進制數字。該類設計有各種功能,使其能夠分析和格式化任意語言環境中的數,包括對西方語言、阿拉伯語和印度語數字的支持。它還支持不同類型的數,包括整數 (123)、定點數 (123.4)、科學記數法表示的數 (1.23E4)、百分數 (12%) 和金額 ($123)。所有這些內容都可以本地化。

     1截取double類型的小數位:
     2public class Test {
     3   public static void main(String[] args){
     4      double a = 1.999999999999;
     5      //保留a的兩位小數,注意不是四舍五入
     6      DecimalFormat df = new DecimalForma("#.00");
     7      a = Double.parseDouble(df.format(a));//format方法返回的是字符串類型
     8      System.out.println(a);
     9   }

    10}
    posted @ 2009-04-16 09:04 jiafang83 閱讀(244) | 評論 (0)編輯 收藏
    轉載:
    1.web打印控件的三種實現方法:http://www.tkk7.com/midstr/archive/2009/03/13/256597.html   ----“歲月如歌”的博客
    2.IEWebBrowser組件的execWB方法:http://dev.csdn.net/article/16/16938.shtm  ------haley_hj 的 Blog
    3.WEB打印大全:http://www.fangxun.net/tech/techfile/prog/asp/200610/2612.htm
    4.14個經典的JavaScript代碼:http://www.vikecn.com/Skins/Skin3/blogview.asp?153078-27932.html
    posted @ 2009-04-15 14:42 jiafang83| 編輯 收藏
    轉載:http://hi.baidu.com/xeelytech/blog/item/b8e42cfdac841d1508244d42.html



    iframe 父窗口和子窗口的調用方法
    父窗口調用子窗口
    iframe_name.iframe_document_object.object_attribute = attribute_value
    例子:onClick="iframe_text.myH1.innerText='http://www.pint.com';"
    子窗口調用父窗口parent.parent_document_object.object_attribute = attribute_value
    例子:onclick="parent.myH1.innerText='http://www.pint.com';"
    上面在IE下沒有問題,但在firefox下不正常。在firefox下,應該是
    父窗口調用子窗口
    window.frames["iframe_name"].document.getElementById("iframe_document_object"-).object_attribute = attribute_value
    例子
    window.frames["iframe_text"].document.getElementById("myH1").innerHTML= " 子窗口調用父窗口
    parent.document.getElementById("parent_document_object").object_attribute = attribute_value
    例子
    parent.document.getElementById("myH1").innerHTML = "

     

    完整例子:
    start.html

    <html>
    <script type="text/javascript">
    function b(){
        alert(
    "父窗口編輯子窗口的內容。。。");
        window.frames[
    "floater"].document.getElementById("bb").innerHTML="父窗口改變子窗口內容";
        
    //下句只適合IE瀏覽器
        //floater.bb.innerText="父窗口修改子窗口內容。。。";
    }

    </script>
    <body>
    <IFRAME name="floater" src="three.html" width=1000 height=600 hspace=20 vspace=20 align=right frameborder=1>
    </IFRAME><BR>
    <img src="星球大戰.jpg" /><br>
    <id="aa" href="one.html" target="floater">Show one.htm</A><P> 
    <form id="a" action="#" method="post">
    <input type=button value="修改子窗口內容" onclick="b()">
    </form>
    </body>
    </html>

    one.html

    <html>
    one.html
    </html>

    three.html

    <html>
    <script typt="text/javascript">
    function a(){
        alert(
    "子窗口編輯父窗口內容parent表示父窗口");
        
    //下句只適合IE瀏覽器
        //parent.aa.innerText="ppppppppppppp";
        parent.document.getElementById("aa").innerHTML="修改父窗口內容";
        
    //parent.frames["iframe的名稱"].document.getElementById("aa").innerText="修改父窗口內容。。。。";
        //子窗口修改父窗口的另一個子窗口的內容
    }

    </script>
    <body onload="a()">
    <h1 id="bb">改變父窗口的元素值。</h1>
    </body>
    </html>
    posted @ 2009-03-29 15:53 jiafang83| 編輯 收藏
    轉載:http://hi.baidu.com/wukongafei/blog/item/9e92e800923eca14728b6596.html

    把subversion加入windows服務
    sc create svnserver binPath= "E:\Program Files\Subversion\bin\svnserve.exe --service -r E:\cjf\repository" DisplayName= "subversion" depend= Tcpip start= auto
    posted @ 2009-03-23 09:01 jiafang83| 編輯 收藏
    轉載:
    http://blog.sina.com.cn/s/blog_49ee6e040100awbe.html

    posted @ 2009-03-23 09:00 jiafang83| 編輯 收藏

     

     1import java.util.ArrayList;
     2
     3public class Test01 {
     4    
     5    Test01() { }
     6
     7    /**
     8     * 除去字符串數組中重復次數超過整數n的數組元素.使用時請使用try{}catch(){}包含.或是使用throws聲明拋出異常
     9     */

    10    public String[] execute(String[] args, int n) throws Exception {
    11        //Arrays.sort(args); // 此行代碼可以不使用,使用得話會使數組工整,排序數據.
    12        ArrayList<String> list = new ArrayList<String>(args.length);
    13        //count變量,記錄數組元素的重復次數
    14        int count = 0;
    15        for (int i = 0; i < args.length; i++{
    16            count = 0;
    17            for (int j = 0; j < args.length; j++{
    18                if (args[i].equals(args[j])) {
    19                    count++;
    20                }

    21            }

    22            //把重復次數小于等于n的數組元素放進集合List中
    23            if (count <= n) {
    24                list.add(args[i]);
    25            }

    26
    27        }

    28        //新建一個數組,數組的長度為集合list的長度
    29        String[] retStrs = new String[list.size()];
    30        //然后把集合list的元素按照順序賦給新建的數組
    31        for (int i = 0; i < list.size(); i++{
    32            retStrs[i] = (String) list.get(i);
    33        }

    34        //返回該數組
    35        return retStrs;
    36    }

    37
    38    public static void main(String[] arguments) throws Exception {
    39
    40        String[] t = new Test01().execute(new String[] "aaaaa""ccccc",
    41                "aaaaa""aaaaa""ccccc""ddddd""ddddd""eeeee""aaaaa",
    42                "fffff""ddddd""fffff""ddddd" }
    3);
    43        for (String x : t) {
    44            System.out.println(x);
    45        }

    46    }

    47}

     

    posted @ 2009-03-11 21:17 jiafang83 閱讀(675) | 評論 (0)編輯 收藏
    轉載:http://zhidao.baidu.com/question/35054792.html

    Eclipse插件的安裝有兩種方法

    1、在eclipse的主目錄(ECLIPSE_HOME,比如在我的機器上安裝的目錄是:D:\JavaDev\3.1)有一個plugins的目錄,這種方法的插件安裝非常簡單,只要將插件copy到這個目錄下就可以了。比如我有一個weblogic的插件(bea站點上可以下載),解壓縮之后得到得到一個目錄:【com.bea.eclipse.weblogic_1.1.1】,我就將這個目錄直接放到%ECLIPSE_HOME%\plugins目錄下,重新啟動eclipse之后就看到Run->“Start Weblogic”的菜單。安裝之后,weblogic插件的全路徑為:D:\JavaDev\3.1\plugins\com.bea.eclipse.weblogic_1.1.1]

    2、在eclipse目錄(ECLIPSE_HOME)下創建一個links目錄,然后將你自己的插件放在你想放的任何地方,這個時候你放插件的目錄我稱她為插件目錄(PLUGIN_HOME),然后在你的%ECLIPSE_HOME%\links\目錄下創建一個link文件,比如我要安裝一個vss插件,我就在我的links目錄下創建了:VSS_1.6.1.link文件。而這個VSS_1.6.1.link文件則是指向的我的插件目錄(PLUGIN_HOME,比如在我的機器上插件目錄為D:\JavaDev\plugins)。VSS_1.6.1.link文件的內容是:

    path=D:\\JavaDev\\plugins\\vssplugin_1.6.1

    第二種安裝插件的時候需要注意,如果你是一個單獨的jar文件,則最好在link文件指定的目錄下創建這樣級別的目錄:eclipse\plugins\xxx.xxx(插件名稱和版本號),然后將jar文件放在這個目錄下即可。比如vss插件在我的機器上的目錄是D:\JavaDev\plugins\vssplugin_1.6.1\eclipse\plugins\org.vssplugin_1.6.1,下有一個文件:vssplugin.jar

    兩種方法的插件安裝之后需要重新啟動eclipse才能看到插件。如果某一個插件已經安裝了想要重新安裝,只要將文件替換或者修改link文件的路徑即可。如果發現認不到插件,可能是你的插件不支持你的當前eclipse版本,請檢查。也有可能是系統配置引起的,我出現過一次,我的解決方法是將ECLIPSE_HOME下的configuration目錄下的所有文件刪除,剩下config.ini文件。

    13.Eclipse插件使用links目錄的用法:
    假設把插件安裝在d:\myplugin目錄中,則myplugin的目錄結構一定要是這樣的:
    d:\\myplugin\\eclipse\\plugins\\插件 及 d:\\myplugin\\eclipse\\features\\插件
    例如安裝EclipseME插件到d:\myplugin目錄中,則目錄結構

    d:\\myplugin\\eclipse\\plugins\\eclipseme_0.4.5。
    再假設eclipse安裝在d:\eclipse目錄中,則在eclipse目錄中創建名稱為links的目錄,在links目

    錄中建立一個link文件,比如myplugin.link,該文件內容為path=d:\\myplugin。
    啟動eclipse,插件即安裝上了,如果想暫時不啟動插件,只需把myplugin.link文件刪除即可。
    補充說明:
    1. 插件可以分別安裝在多個自定義的目錄中。
    2. 一個自定義目錄可以安裝多個插件。
    3. link文件的文件名及擴展名可以取任意名稱,比如myplugin.txt,goodplugin都可以。
    4. link文件可以有多行path=插件目錄,對應多個自定義插件目錄,每一行的path參數都將生效。
    5. 在links目錄也可以有多個link文件,每個link文件中的path參數都將生效。
    6. 插件目錄可以使用相對路徑,如果我們把myplugin目錄創建在eclipse安裝目錄中,如上例中的

    d:\eclipse目錄中,則只需設置path=myplugin即可。
    posted @ 2009-02-18 21:36 jiafang83 閱讀(136) | 評論 (0)編輯 收藏
    http://hi.baidu.com/menglinxi%5Fa/blog/item/cf492e4532f85821cffca383.html

    1. 介紹

    1)DOM(JAXP Crimson解析器)
            DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點或信息片斷的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構,然后才能做任何工作。由于它是基于信息層次的,因而DOM被認為是基于樹或基于對象的。DOM以及廣義的基于樹的處理具有幾個優點。首先,由于樹在內存中是持久的,因此可以修改它以便應用程序能對數據和結構作出更改。它還可以在任何時候在樹中上下導航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。

    2)SAX

            SAX處理的優點非常類似于流媒體的優點。分析能夠立即開始,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時檢查數據,因此不需要將數據存儲在內存中。這對于大型文檔來說是個巨大的優點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多。
      選擇DOM還是選擇SAX? 對于需要自己編寫代碼來處理XML文檔的開發人員來說, 選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM采用建立樹形結構的方式訪問XML文檔,而SAX采用的事件模型。

      DOM解析器把XML文檔轉化為一個包含其內容的樹,并可以對樹進行遍歷。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然后利用navigation APIs訪問所需的樹節點來完成任務。可以很容易的添加和修改樹中的元素。然而由于使用DOM解析器的時候需要處理整個XML文檔,所以對性能和內存的要求比較高,尤其是遇到很大的XML文件的時候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務中。

      SAX解析器采用了基于事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標簽已經找到。SAX對內存的要求通常會比較低,因為它讓開發人員自己來決定所要處理的tag。特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX這種擴展能力得到了更好的體現。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同數據。

    3)JDOM          http://www.jdom.org/

              JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實現更快。由于是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過“Java規范請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經開始了JDOM開發。

      JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經熟悉這些類的Java開發者的使用。

      JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據學習曲線假定為20%)。JDOM對于大多數Java/XML應用程序來說當然是有用的,并且大多數開發者發現API比DOM容易理解得多。JDOM還包括對程序行為的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM接口都更有意義的工作。

      JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(盡管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發布的開放源碼。

    4)DOM4J http://dom4j.sourceforge.net/
                
            雖然DOM4J代表了完全獨立的開發結果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM接口具有并行訪問功能。從2000下半年開始,它就一直處于開發之中。

      為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價,但是它提供了比JDOM大得多的靈活性。

      在添加靈活性、XPath集成和對大文檔處理的目標時,DOM4J的目標與JDOM是一樣的:針對Java開發者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實現在本質上處理所有Java/XML問題的目標。在完成該目標時,它比JDOM更少強調防止不正確的應用程序行為。

      DOM4J是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J。

    2.. 比較

    1)DOM4J性能最好,連Sun的JAXM也在用DOM4J。目前許多開源項目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.

    2)JDOM和DOM在性能測試時表現不佳,在測試10M文檔時內存溢出。在小文檔情況下還值得考慮使用DOM和JDOM。雖然JDOM的開發者已經說明他們期望在正式發行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用于多種編程語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基于非標準的Java模型相對),所以在某些類型的項目中可能也需要它(如在JavaScript中使用DOM)。

    3)SAX表現較好,這要依賴于它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但并沒有載入到內存(當然當XML流被讀入時,會有部分文檔暫時隱藏在內存中)。

    3. 四種xml操作方式的基本使用方法

    xml文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <Result>
       <VALUE>
           <NO DATE="2005">A1</NO>
           <ADDR>GZ</ADDR>
       </VALUE>
       <VALUE>
           <NO DATE="2004">A2</NO>
           <ADDR>XG</ADDR>
    </VALUE>
    </Result>

    1)DOM

    import java.io.*;
    import java.util.*;
    import org.w3c.dom.*;
    import javax.xml.parsers.*;

    public class MyXMLReader{
     public static void main(String arge[]){

      long lasting =System.currentTimeMillis();
      try{
       File f=new File("data_10k.xml");
       DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
       DocumentBuilder builder=factory.newDocumentBuilder();
       Document doc = builder.parse(f);
       NodeList nl = doc.getElementsByTagName("VALUE");
       for (int i=0;i<nl.getLength();i++){
        System.out.print("車牌號碼:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
        System.out.println("車主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
       }
      }catch(Exception e){
       e.printStackTrace();
    }

    2)SAX

    import org.xml.sax.*;
    import org.xml.sax.helpers.*;
    import javax.xml.parsers.*;

    public class MyXMLReader extends DefaultHandler {

     java.util.Stack tags = new java.util.Stack();
     public MyXMLReader() {
      super();
       }

     public static void main(String args[]) {
      long lasting = System.currentTimeMillis();
      try {
       SAXParserFactory sf = SAXParserFactory.newInstance();
       SAXParser sp = sf.newSAXParser();
       MyXMLReader reader = new MyXMLReader();
       sp.parse(new InputSource("data_10k.xml"), reader);
      } catch (Exception e) {
       e.printStackTrace();
      }

      System.out.println("運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");}
      public void characters(char ch[], int start, int length) throws SAXException {
      String tag = (String) tags.peek();
      if (tag.equals("NO")) {
       System.out.print("車牌號碼:" + new String(ch, start, length));
        }
        if (tag.equals("ADDR")) {
      System.out.println("地址:" + new String(ch, start, length));
        }
       }

      public void startElement(String uri,String localName,String qName,Attributes attrs) {
      tags.push(qName);}
    }

    3) JDOM

    import java.io.*;
    import java.util.*;
    import org.jdom.*;
    import org.jdom.input.*;

    public class MyXMLReader {

     public static void main(String arge[]) {
      long lasting = System.currentTimeMillis();
      try {
       SAXBuilder builder = new SAXBuilder();
       Document doc = builder.build(new File("data_10k.xml"));
       Element foo = doc.getRootElement();
       List allChildren = foo.getChildren();
       for(int i=0;i<allChildren.size();i++) {
        System.out.print("車牌號碼:" + ((Element)allChildren.get(i)).getChild("NO").getText());
        System.out.println("車主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());
       }
      } catch (Exception e) {
       e.printStackTrace();
    }

    }

    4)DOM4J

    import java.io.*;
    import java.util.*;
    import org.dom4j.*;
    import org.dom4j.io.*;

    public class MyXMLReader {

     public static void main(String arge[]) {
      long lasting = System.currentTimeMillis();
      try {
       File f = new File("data_10k.xml");
       SAXReader reader = new SAXReader();
       Document doc = reader.read(f);
       Element root = doc.getRootElement();
       Element foo;
       for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
        foo = (Element) i.next();
        System.out.print("車牌號碼:" + foo.elementText("NO"));
        System.out.println("車主地址:" + foo.elementText("ADDR"));
       }
      } catch (Exception e) {
       e.printStackTrace();
        }
    }

    posted @ 2009-02-18 21:27 jiafang83 閱讀(337) | 評論 (1)編輯 收藏
    http://hi.baidu.com/lc2tp/blog/item/477c3601aac1ca011c9583dc.html

    要使用dom4j讀寫XML文檔,需要先下載dom4j包,dom4j官方網站在 http://www.dom4j.org/
    目前最新dom4j包下載地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip

    解開后有兩個包,僅操作XML文檔的話把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的話還需要加入包jaxen-1.1-beta-7.jar.

    以下是相關操作:

    一.Document對象相關

    1.讀取XML文件,獲得document對象.
                SAXReader reader = new SAXReader();
                Document document = reader.read(new File("input.xml"));

    2.解析XML形式的文本,得到document對象.
                String text = "<members></members>";
                Document document = DocumentHelper.parseText(text);
    3.主動創建document對象.
                Document document = DocumentHelper.createDocument();
                Element root = document.addElement("members");// 創建根節點
    二.節點相關

    1.獲取文檔的根節點.
    Element rootElm = document.getRootElement();
    2.取得某節點的單個子節點.
    Element memberElm=root.element("member");// "member"是節點名
    3.取得節點的文字
    String text=memberElm.getText();
    也可以用:
    String text=root.elementText("name");這個是取得根節點下的name字節點的文字.

    4.取得某節點下名為"member"的所有字節點并進行遍歷.
    List nodes = rootElm.elements("member");

    for (Iterator it = nodes.iterator(); it.hasNext();) {
       Element elm = (Element) it.next();
       // do something
    }
    5.對某節點下的所有子節點進行遍歷.
                for(Iterator it=root.elementIterator();it.hasNext();){
                    Element element = (Element) it.next();
                    // do something
                }
    6.在某節點下添加子節點.
    Element ageElm = newMemberElm.addElement("age");
    7.設置節點文字.
    ageElm.setText("29");
    8.刪除某節點.
    parentElm.remove(childElm);// childElm是待刪除的節點,parentElm是其父節點
    三.屬性相關.
    1.取得某節點下的某屬性
                Element root=document.getRootElement();   
                Attribute attribute=root.attribute("size");// 屬性名name
    2.取得屬性的文字
                String text=attribute.getText();
    也可以用:
    String text2=root.element("name").attributeValue("firstname");這個是取得根節點下name字節點的屬性firstname的值.

    3.遍歷某節點的所有屬性
                Element root=document.getRootElement();   
                for(Iterator it=root.attributeIterator();it.hasNext();){
                    Attribute attribute = (Attribute) it.next();
                    String text=attribute.getText();
                    System.out.println(text);
                }
    4.設置某節點的屬性和文字.
    newMemberElm.addAttribute("name", "sitinspring");
    5.設置屬性的文字
                Attribute attribute=root.attribute("name");
                attribute.setText("sitinspring");
    6.刪除某屬性
                Attribute attribute=root.attribute("size");// 屬性名name
                root.remove(attribute);
    四.將文檔寫入XML文件.
    1.文檔中全為英文,不設置編碼,直接寫入的形式.
    XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
    writer.write(document);
    writer.close();
    2.文檔中含有中文,設置編碼格式寫入的形式.
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding("GBK");    // 指定XML編碼       
                XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
               
                writer.write(document);
                writer.close();
    五.字符串與XML的轉換
    1.將字符串轉化為XML
    String text = "<members> <member>sitinspring</member> </members>";
    Document document = DocumentHelper.parseText(text);
    2.將文檔或節點的XML轉化為字符串.
                SAXReader reader = new SAXReader();
                Document document = reader.read(new File("input.xml"));           
                Element root=document.getRootElement();               
                String docXmlText=document.asXML();
                String rootXmlText=root.asXML();
                Element memberElm=root.element("member");
                String memberXmlText=memberElm.asXML();
    六.使用XPath快速找到節點.
    讀取的XML文檔示例
    <?xml version="1.0" encoding="UTF-8"?>
    <projectDescription>
    <name>MemberManagement</name>
    <comment></comment>
    <projects>
        <project>PRJ1</project>
        <project>PRJ2</project>
        <project>PRJ3</project>
        <project>PRJ4</project>
    </projects>
    <buildSpec>
        <buildCommand>
          <name>org.eclipse.jdt.core.javabuilder</name>
          <arguments>
          </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
    </projectDescription>

    使用XPath快速找到節點project.
    public static void main(String[] args){
        SAXReader reader = new SAXReader();
       
        try{
          Document doc = reader.read(new File("sample.xml"));
         
          List projects=doc.selectNodes("/projectDescription/projects/project");
         
          Iterator it=projects.iterator();
         
          while(it.hasNext()){
            Element elm=(Element)it.next();      
            System.out.println(elm.getText());
          }
         
        }
        catch(Exception ex){
           ex.printStackTrace();
        }
    }

    posted @ 2009-02-18 21:25 jiafang83 閱讀(1026) | 評論 (1)編輯 收藏
    轉載:http://hi.baidu.com/flyx100/blog/item/ca403e2f8d73233f1f3089a7.html

    Eclipse的編輯功能非常強大,掌握了Eclipse快捷鍵功能,能夠大大提高開發效率。Eclipse中有如下一些和編輯相關的快捷鍵。
       1. 【ALT+/】
       此快捷鍵為用戶編輯的好幫手,能為用戶提供內容的輔助,不要為記不全方法和屬性名稱犯愁,當記不全類、方法和屬性的名字時,多體驗一下【ALT+/】快捷鍵帶來的好處吧。

       2. 【Ctrl+O】
       顯示類中方法和屬性的大綱,能快速定位類的方法和屬性,在查找Bug時非常有用。

       3. 【Ctrl+/】
       快速添加注釋,能為光標所在行或所選定行快速添加注釋或取消注釋,在調試的時候可能總會需要注釋一些東西或取消注釋,現在好了,不需要每行進行重復的注釋。

       4. 【Ctrl+D】
       刪除當前行,這也是筆者的最愛之一,不用為刪除一行而按那么多次的刪除鍵。

       5. 【Ctrl+M】
       窗口最大化和還原,用戶在窗口中進行操作時,總會覺得當前窗口小(尤其在編寫代碼時),現在好了,試試【Ctrl+M】快捷鍵。

       查看和定位快捷鍵

       在程序中,迅速定位代碼的位置,快速找到Bug的所在,是非常不容易的事,Eclipse提供了強大的查找功能,可以利用如下的快捷鍵幫助完成查找定位的工作。

       1. 【Ctrl+K】、【Ctrl++Shift+K】
       快速向下和向上查找選定的內容,從此不再需要用鼠標單擊查找對話框了。

       2. 【Ctrl+Shift+T】
       查找工作空間(Workspace)構建路徑中的可找到Java類文件,不要為找不到類而痛苦,而且可以使用“*”、“?”等通配符。

       3. 【Ctrl+Shift+R】
       和【Ctrl+Shift+T】對應,查找工作空間(Workspace)中的所有文件(包括Java文件),也可以使用通配符。

       4. 【Ctrl+Shift+G】
       查找類、方法和屬性的引用。這是一個非常實用的快捷鍵,例如要修改引用某個方法的代碼,可以通過【Ctrl+Shift+G】快捷鍵迅速定位所有引用此方法的位置。

       5. 【Ctrl+Shift+O】
    快速生成import,當從網上拷貝一段程序后,不知道如何import進所調用的類,試試【Ctrl+Shift+O】快捷鍵,一定會有驚喜。

       6. 【Ctrl+Shift+F】
       格式化代碼,書寫格式規范的代碼是每一個程序員的必修之課,當看見某段代碼極不順眼時,選定后按【Ctrl+Shift+F】快捷鍵可以格式化這段代碼,如果不選定代碼則默認格式化當前文件(Java文件)。

       7. 【ALT+Shift+W】
       查找當前文件所在項目中的路徑,可以快速定位瀏覽器視圖的位置,如果想查找某個文件所在的包時,此快捷鍵非常有用(特別在比較大的項目中)。

       8. 【Ctrl+L】
       定位到當前編輯器的某一行,對非Java文件也有效。

       9. 【Alt+←】、【Alt+→】
       后退歷史記錄和前進歷史記錄,在跟蹤代碼時非常有用,用戶可能查找了幾個有關聯的地方,但可能記不清楚了,可以通過這兩個快捷鍵定位查找的順序。

       10. 【F3】
    快速定位光標位置的某個類、方法和屬性。

       11. 【F4】
       顯示類的繼承關系,并打開類繼承視圖。

       調試快捷鍵

       Eclipse中有如下一些和運行調試相關的快捷鍵。

       1. 【Ctrl+Shift+B】:在當前行設置斷點或取消設置的斷點。
       2. 【F11】:調試最后一次執行的程序。
       3. 【Ctrl+F11】:運行最后一次執行的程序。
       4. 【F5】:跟蹤到方法中,當程序執行到某方法時,可以按【F5】鍵跟蹤到方法中。
       5. 【F6】:單步執行程序。
       6. 【F7】:執行完方法,返回到調用此方法的后一條語句。
       7. 【F8】:繼續執行,到下一個斷點或程序結束。

       常用編輯器快捷鍵

       通常文本編輯器都提供了一些和編輯相關的快捷鍵,在Eclipse中也可以通過這些快捷鍵進行文本編輯。
       1. 【Ctrl+C】:復制。
       2. 【Ctrl+X】:剪切。
       3. 【Ctrl+V】:粘貼。
       4. 【Ctrl+S】:保存文件。
       5. 【Ctrl+Z】:撤銷。
       6. 【Ctrl+Y】:重復。
       7. 【Ctrl+F】:查找。

       其他快捷鍵

       Eclipse中還有很多快捷鍵,無法一一列舉,可以通過幫助文檔找到它們的使用方式,另外還有幾個常用的快捷鍵如下。
       1. 【Ctrl+F6】:切換到下一個編輯器。
       2. 【Ctrl+Shift+F6】:切換到上一個編輯器。
       3. 【Ctrl+F7】:切換到下一個視圖。
       4. 【Ctrl+Shift+F7】:切換到上一個視圖。
       5. 【Ctrl+F8】:切換到下一個透視圖。
       6. 【Ctrl+Shift+F8】:切換到上一個透視圖。

       Eclipse中快捷鍵比較多,可以通過幫助文檔找到所有快捷鍵的使用,但要掌握所有快捷鍵的使用是不可能的,也沒有必要,如果花點時間熟悉本節列舉的快捷鍵,
    --------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    1幾個最重要的快捷鍵

    代碼助手:Ctrl+Space(簡體中文操作系統是Alt+/)
    快速修正:Ctrl+1
    單詞補全:Alt+/
    打開外部Java文檔:Shift+F2

    顯示搜索對話框:Ctrl+H
    快速Outline:Ctrl+O
    打開資源:Ctrl+Shift+R
    打開類型:Ctrl+Shift+T
    顯示重構菜單:Alt+Shift+T

    上一個/下一個光標的位置:Alt+Left/Right
    上一個/下一個成員(成員對象或成員函數):Ctrl+Shift+Up/Down
    選中閉合元素:Alt+Shift+Up/Down/Left/Right
    刪除行:Ctrl+D
    在當前行上插入一行:Ctrl+Shift+Enter
    在當前行下插入一行: Shift+Enter
    上下移動選中的行:Alt+Up/Down


    組織導入:Ctrl+Shift+O

    2 定位
    2.1行內定位
    行末/行首:End/Home
    前一個/后一個單詞:Ctrl+Right/Left
    2.2文件內定位
    跳到某行:Ctrl+L
    上下滾屏:Ctrl+Up/Down
    上一個/下一個成員(成員對象或成員函數):Ctrl+Shift+Up/Down
    快速Outline:Ctrl+O
    2.3跨文件定位
    打開聲明:F3
    打開資源:Ctrl+Shift+R
    打開類型:Ctrl+Shift+T
    在workspace中搜索選中元素的聲明:Ctrl+G
    在workspace中搜索選中的文本:Ctrl+Alt+G
    在workspace中搜索選中元素的引用:Ctrl+Shift+G
    打開調用層次結構:Ctrl+Alt+H
    快速層次結構:Ctrl+T
    反悔:Ctrl+Z
    2.4其它
    上一個/下一個光標所在位置:Alt+Left/Right
    上一個編輯的位置:Ctrl+Q

     

    3 選中
    3.1行內選中
    選中到行末/行首:Shift+End/Home
    選中上一個/下一個單詞:Ctrl+Shift+Left/Right
    3.2文件內選中
    選中閉合元素:Alt+Shift+Up
    恢復到上一個選中:Alt+Shift+Down
    選中下一個/上一個元素:Alt+Shift+Right/Left

     

    4 定位/選中/操作同時
    刪除行:Ctrl+D
    刪除下一個/上一個單詞:Ctrl+Delete/Backspace
    刪除到行末:Ctrl+Shift+Delete
    在當前行上插入一行:Ctrl+Shift+Enter
    在當前行下插入一行: Shift+Enter
    上下移動選中的行:Alt+Up/Down
    拷貝選中的行:Ctrl+Alt+Up/Down

     

    5其它的代碼編輯類快捷鍵
    保存:Ctrl+S
    保存所有:Ctrl+Shift+S
    下一個命中的項(搜索之后):Ctrl+.
    注釋:Ctrl+/
    添加導入:Ctrl+Shift+M
    顯示快捷鍵幫助:Ctrl+Shift+L
    變為大/小寫:Ctrl+Shift+X/Y

     

    6 重構
    顯示重構菜單:Alt+Shift+T
    重構-改變方法簽名:Alt+Shift+C
    重構-移動:Alt+Shift+V
    重構-重命名:Alt+Shift+R

     

    7 編輯器、視圖、透視圖切換
    下一個編輯器:Ctrl+F6
    下一個視圖:Ctrl+F7
    下一個透視圖:Ctrl+F8
    最大化當前視圖或編輯器:Ctrl+M
    激活編輯器:F12

     

    8 Debug
    F5:Step Into(debug)
    F6:Step over(debug)
    F7:Step return(debug)
    F8:Resume(debug)
    F11:debug上一個應用(debug)

     

    9 Up/Down/Right/Left類快捷鍵
    Ctrl
    前一個/后一個單詞:Ctrl+Right/Left
    上下滾屏:Ctrl+Up/Down
    Alt
    上一個/下一個光標的位置:Alt+Left/Right
    上下移動選中的行:Alt+Up/Down
    Shift
    選中上一個/下一個字符:Shift+Left/Right
    選中上一行/下一行(從當前光標位置開始):Shift+Up/Down
    Ctrl+Shift
    上一個/下一個成員(成員對象或成員函數):Ctrl+Shift+Up/Down
    選中上一個/下一個單詞:Ctrl+Shift+Left/Right
    Alt+Shift
    選中閉合元素:Alt+Shift+Up
    恢復到上一個選中:Alt+Shift+Down
    選中下一個/上一個元素:Alt+Shift+Right/Left
    拷貝選中的行:Ctrl+Alt+Up/Down
    Ctrl+Alt
    拷貝選中的行:Ctrl+Alt+Up/Down

     

    10 F類快捷鍵
    F2:顯示提示/重命名
    F3:打開選中元素的聲明
    F4:打開選中元素的類型繼承結構
    F5:刷新
    F5:Step Into(debug)
    F6:Step over(debug)
    F7:Step return(debug)
    F8:Resume(debug)
    F11:debug上一個應用(debug)
    F12:激活編輯器
    ================================================================
    ================================================================
    MyEclipse使用技巧和快捷鍵2008-01-23 09:22Eclipse本身很快的,但是加上了myeclipse后,就狂占內存,而且速度狂慢,那如何讓Eclipse拖著myeclipse狂飚呢?這里提供一個技巧:取消自動validation
            validation有一堆,什么xml、jsp、jsf、js等等,我們沒有必要全部都去自動校驗一下,只是需要的時候才會手工校驗一下,速度立馬提升好幾個檔次!
    取消方法: windows-->perferences-->myeclipse-->validation
            除開Manual下面的復選框全部選中之外,其他全部不選
            手工驗證方法:
            在要驗證的文件上,單擊鼠標右鍵-->myeclipse-->run validation

    程序代碼自動排版:Ctrl+Shift+F,會自動把代碼進行格式化的排版,非常方便
    快速執行程序:Ctrl + F11第一次執行時,它會詢問您執行模式,設置好后,以后只要按這個熱鍵,它就會快速執行。

    Ctrl+Shift+/ 加上段注釋/**/

    Ctrl+Shift+\ 取消段注釋/**/

    Ctrl+/ 加上行注釋或取消行注釋

    自動匯入所需要的類別:Ctrl+Shift+M Ctrl+Shift+O 好象使用Ctrl+Shift+O 也可以

    按new Remote Site,Name填 svn , URL填http://subclipse.tigris.org/update,一直next到finished為止

    MyEclipse 快捷鍵
    (1)Ctrl+M切換窗口的大小
    (2)Ctrl+Q跳到最后一次的編輯處
    (3)F2當鼠標放在一個標記處出現Tooltip時候按F2則把鼠標移開時Tooltip還會顯示即Show Tooltip Description。
    F3跳到聲明或定義的地方。
    F5單步調試進入函數內部。
    F6單步調試不進入函數內部,如果裝了金山詞霸2006則要把“取詞開關”的快捷鍵改成其他的。
    F7由函數內部返回到調用處。
    F8一直執行到下一個斷點。
    (4)Ctrl+Pg~對于XML文件是切換代碼和圖示窗口
    (5)Ctrl+Alt+I看Java文件中變量的相關信息
    (6)Ctrl+PgUp對于代碼窗口是打開“Show List”下拉框,在此下拉框里顯示有最近曾打開的文件
    (7)Ctrl+/ 在代碼窗口中是這種//~注釋。
    Ctrl+Shift+/ 在代碼窗口中是這種/*~*/注釋,在JSP文件窗口中是<!--~-->。
    (8)Alt+Shift+O(或點擊工具欄中的Toggle Mark Occurrences按鈕) 當點擊某個標記時可使本頁面中其他地方的此標記黃色凸顯,并且窗口的右邊框會出現白色的方塊,點擊此方塊會跳到此標記處。
    (9)右擊窗口的左邊框即加斷點的地方選Show Line Numbers可以加行號。
    (10)Ctrl+I格式化激活的元素Format Active Elements。
    Ctrl+Shift+F格式化文件Format Document。
    (11)Ctrl+S保存當前文件。
    Ctrl+Shift+S保存所有未保存的文件。
    (12)Ctrl+Shift+M(先把光標放在需導入包的類名上) 作用是加Import語句。
    Ctrl+Shift+O作用是缺少的Import語句被加入,多余的Import語句被刪除。
    (13)Ctrl+Space提示鍵入內容即Content Assist,此時要將輸入法中Chinese(Simplified)IME-Ime/Nonlme Toggle的快捷鍵(用于切換英文和其他文字)改成其他的。
    Ctrl+Shift+Space提示信息即Context Information。
    (14)雙擊窗口的左邊框可以加斷點。
    (15)Ctrl+D刪除當前行

    posted @ 2008-12-10 14:30 jiafang83 閱讀(4782) | 評論 (0)編輯 收藏
    轉載:http://join-18.javaeye.com/blog/183051

    1.介紹
    1)DOM(JAXP Crimson解析器)
    DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點或信息片斷的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構,然后才能做任何工作。由于它是基于信息層次的,因而DOM被認為是基于樹或基于對象的。DOM以及廣義的基于樹的處理具有幾個優點。首先,由于樹在內存中是持久的,因此可以修改它以便應用程序能對數據和結構作出更改。它還可以在任何時候在樹中上下導航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。
    2)SAX
    SAX處理的優點非常類似于流媒體的優點。分析能夠立即開始,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時檢查數據,因此不需要將數據存儲在內存中。這對于大型文檔來說是個巨大的優點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多。
    選擇DOM還是選擇SAX? 對于需要自己編寫代碼來處理XML文檔的開發人員來說, 選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM采用建立樹形結構的方式訪問XML文檔,而SAX采用的事件模型。
    DOM解析器把XML文檔轉化為一個包含其內容的樹,并可以對樹進行遍歷。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然后利用navigation APIs訪問所需的樹節點來完成任務。可以很容易的添加和修改樹中的元素。然而由于使用DOM解析器的時候需要處理整個XML文檔,所以對性能和內存的要求比較高,尤其是遇到很大的XML文件的時候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務中。
    SAX解析器采用了基于事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標簽已經找到。SAX對內存的要求通常會比較低,因為它讓開發人員自己來決定所要處理的tag.特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX這種擴展能力得到了更好的體現。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同數據。
    3)JDOM http://www.jdom.org
    JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實現更快。由于是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過“Java規范請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經開始了JDOM開發。
    JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經熟悉這些類的Java開發者的使用。
    JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據學習曲線假定為20%)。JDOM對于大多數Java/XML應用程序來說當然是有用的,并且大多數開發者發現API比DOM容易理解得多。JDOM還包括對程序行為的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM接口都更有意義的工作。
    JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(盡管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發布的開放源碼。
    4)DOM4J http://dom4j.sourceforge.net
    雖然DOM4J代表了完全獨立的開發結果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM接口具有并行訪問功能。從2000下半年開始,它就一直處于開發之中。
    為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價,但是它提供了比JDOM大得多的靈活性。
    在添加靈活性、XPath集成和對大文檔處理的目標時,DOM4J的目標與JDOM是一樣的:針對Java開發者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實現在本質上處理所有Java/XML問題的目標。在完成該目標時,它比JDOM更少強調防止不正確的應用程序行為。
    DOM4J是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J.
    2、比較
    1)DOM4J性能最好,連Sun的JAXM也在用DOM4J.目前許多開源項目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.
    2)JDOM和DOM在性能測試時表現不佳,在測試10M文檔時內存溢出。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開發者已經說明他們期望在正式發行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用于多種編程語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基于非標準的Java模型相對),所以在某些類型的項目中可能也需要它(如在JavaScript中使用DOM)。
    3)SAX表現較好,這要依賴于它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但并沒有載入到內存(當然當XML流被讀入時,會有部分文檔暫時隱藏在內存中)。

    3.四種XML操作方式的基本使用方法
    xml文件:
    <?xml version="1.0" encoding="GB2312"?>
    <RESULT>
    <VALUE>
    <NO>A1234</NO>
    <ADDR>四川省XX縣XX鎮XX路X段XX號</ADDR>
    </VALUE>
    <VALUE>
    <NO>B1234</NO>
       <ADDR>四川省XX市XX鄉XX村XX組</ADDR>
    </VALUE>
    </RESULT>
    1)DOM
    import java.io.*;
    import java.util.*;
    import org.w3c.dom.*;
    import javax.xml.parsers.*;
    public class MyXMLReader{
     public static void main(String arge[]){
    long lasting =System.currentTimeMillis();
    try{
     File f=new File("data_10k.xml");
     DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
     DocumentBuilder builder=factory.newDocumentBuilder();
     Document doc = builder.parse(f);
     NodeList nl = doc.getElementsByTagName("VALUE");
     for (int i=0;i<nl.getLength();i++){
    System.out.print("車牌號碼:" +
    doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
    System.out.println("車主地址:" +
    doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
       }
    }catch(Exception e){
     e.printStackTrace();
    }
    2)SAX
    import org.xml.sax.*;
    import org.xml.sax.helpers.*;
    import javax.xml.parsers.*;
    public class MyXMLReader extends DefaultHandler {
     java.util.Stack tags = new java.util.Stack();
     public MyXMLReader() {
    super();
    }
     public static void main(String args[]) {
    long lasting = System.currentTimeMillis();
    try {
     SAXParserFactory sf = SAXParserFactory.newInstance();
     SAXParser sp = sf.newSAXParser();
     MyXMLReader reader = new MyXMLReader();
     sp.parse(new InputSource("data_10k.xml"), reader);
    } catch (Exception e) {
     e.printStackTrace();
    }
    System.out.println("運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");}
    public void characters(char ch[], int start, int length) throws SAXException {
    String tag = (String) tags.peek();
    if (tag.equals("NO")) {
     System.out.print("車牌號碼:" + new String(ch, start, length));
    }
    if (tag.equals("ADDR")) {
    System.out.println("地址:" + new String(ch, start, length));
    }
    }
    public void startElement(String uri,String localName,String qName,Attributes attrs) {
    tags.push(qName);}
    }
    3)JDOM
    import java.io.*;
    import java.util.*;
    import org.jdom.*;
    import org.jdom.input.*;
    public class MyXMLReader {
     public static void main(String arge[]) {
    long lasting = System.currentTimeMillis();
    try {
     SAXBuilder builder = new SAXBuilder();
     Document doc = builder.build(new File("data_10k.xml"));
     Element foo = doc.getRootElement();
     List allChildren = foo.getChildren();
     for(int i=0;i<allChildren.size();i++) {
    System.out.print("車牌號碼:" +
    ((Element)allChildren.get(i)).getChild("NO").getText());
    System.out.println("車主地址:" +
    ((Element)allChildren.get(i)).getChild("ADDR").getText());
     }
    } catch (Exception e) {
     e.printStackTrace();
    }
    }
    4)DOM4J
    import java.io.*;
    import java.util.*;
    import org.dom4j.*;
    import org.dom4j.io.*;
    public class MyXMLReader {
     public static void main(String arge[]) {
    long lasting = System.currentTimeMillis();
    try {
     File f = new File("data_10k.xml");
     SAXReader reader = new SAXReader();
     Document doc = reader.read(f);
     Element root = doc.getRootElement();
     Element foo;
     for (Iterator i = root.elementIterator("VALUE"); i.hasNext() {
    foo = (Element) i.next();
    System.out.print("車牌號碼:" + foo.elementText("NO"));
    System.out.println("車主地址:" + foo.elementText("ADDR"));
     }
    } catch (Exception e) {
     e.printStackTrace();
    }
    )
    posted @ 2008-12-10 09:38 jiafang83 閱讀(184) | 評論 (0)編輯 收藏
        類Object是類層次結構的根類,每一個類都使用Object作為超類,所有對象(包括數組)都實現這個類的方法。jdk1.5中,描述了該類中的11個方法

    1.getClass

    public final Class<? extends Object> getClass()
    返回一個對象的運行時類。該 Class 對象是由所表示類的 static synchronized 方法鎖定的對象。

     

    返回:
    表示該對象的運行時類的 java.lang.Class 對象。此結果屬于類型 Class<? extends X>,其中 X 表示清除表達式中的靜態類型,該表達式調用 getClass

    2.hashCode

    public int hashCode()
    返回該對象的哈希碼值。支持該方法是為哈希表提供一些優點,例如,java.util.Hashtable 提供的哈希表。

    hashCode 的常規協定是:

    • 在 Java 應用程序執行期間,在同一對象上多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是對象上 equals 比較中所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
    • 如果根據 equals(Object) 方法,兩個對象是相等的,那么在兩個對象中的每個對象上調用 hashCode 方法都必須生成相同的整數結果。
    • 以下情況 是必需的:如果根據 equals(java.lang.Object) 方法,兩個對象不相等,那么在兩個對象中的任一對象上調用 hashCode 方法必定會生成不同的整數結果。但是,程序員應該知道,為不相等的對象生成不同整數結果可以提高哈希表的性能。

    實際上,由 Object 類定義的 hashCode 方法確實會針對不同的對象返回不同的整數。(這一般是通過將該對象的內部地址轉換成一個整數來實現的,但是 JavaTM 編程語言不需要這種實現技巧。)

     

    返回:
    此對象的一個哈希碼值。

    3.equals

    public boolean equals(Object obj)
    指示某個其他對象是否與此對象“相等”。

    equals 方法在非空對象引用上實現相等關系:

    • 自反性:對于任何非空引用值 xx.equals(x) 都應返回 true
    • 對稱性:對于任何非空引用值 xy,當且僅當 y.equals(x) 返回 true 時,x.equals(y) 才應返回 true
    • 傳遞性:對于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 應返回 true
    • 一致性:對于任何非空引用值 xy,多次調用 x.equals(y) 始終返回 true 或始終返回 false,前提是對象上 equals 比較中所用的信息沒有被修改。
    • 對于任何非空引用值 xx.equals(null) 都應返回 false

    Object 類的 equals 方法實現對象上差別可能性最大的相等關系;即,對于任何非空引用值 xy,當且僅當 xy 引用同一個對象時,此方法才返回 truex == y 具有值 true)。

    注意:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定聲明相等對象必須具有相等的哈希碼。

     

    參數:
    obj - 要與之比較的引用對象。
    返回:
    如果此對象與 obj 參數相同,則返回 true;否則返回 false

    4.clone

    protected Object clone()
    throws CloneNotSupportedException
    創建并返回此對象的一個副本。“副本”的準確含義可能依賴于對象的類。一般來說,對于任何對象 x,如果表達式:
    x.clone() != x
    是正確的,則表達式:
    x.clone().getClass() == x.getClass()
    將為 true,但這些不是絕對條件。一般情況下是:
    x.clone().equals(x)
    將為 true,但這不是絕對條件。

    按照慣例,返回的對象應該通過調用 super.clone 獲得。如果一個類及其所有的超類(Object 除外)都遵守此約定,則 x.clone().getClass() == x.getClass()

    按照慣例,此方法返回的對象應該獨立于該對象(正被克隆的對象)。要獲得此獨立性,在 super.clone 返回對象之前,有必要對該對象的一個或多個字段進行修改。這通常意味著要復制包含正在被克隆對象的內部“深層結構”的所有可變對象,并使用對副本的引用替換對這些對象的引用。如果一個類只包含基本字段或對不變對象的引用,那么通常不需要修改 super.clone 返回的對象中的字段。

    Object 類的 clone 方法執行特定的克隆操作。首先,如果此對象的類不能實現接口 Cloneable,則會拋出 CloneNotSupportedException。注意:所有的數組都被視為實現接口 Cloneable。否則,此方法會創建此對象的類的一個新實例,并像通過分配那樣,嚴格使用此對象相應字段的內容初始化該對象的所有字段;這些字段的內容沒有被自我克隆。所以,此方法執行的是該對象的“淺表復制”,而不“深層復制”操作。

    Object 類本身不實現接口 Cloneable,所以在類為 Object 的對象上調用 clone 方法將會導致在運行時拋出異常。

     

    返回:
    此實例的一個克隆。
    拋出:
    CloneNotSupportedException - 如果對象的類不支持 Cloneable 接口,則重寫 clone 方法的子類也會拋出此異常,以指示無法克隆某個實例。

    5.toString

    public String toString()
    返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。結果應是一個簡明但易于讀懂。建議所有子類都重寫此方法。

    Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at 標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等于:

    getClass().getName() + '@' + Integer.toHexString(hashCode())
    

     

    返回:
    該對象的字符串表示形式。

    6.notify

    public final void notify()
    喚醒在此對象監視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的,并在對實現做出決定時發生。線程通過調用其中一個 wait 方法,在對象的監視器上等待。

    直到當前的線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。

    此方法只應由作為此對象監視器的所有者的線程來調用。通過以下三種方法之一,線程可以成為此對象監視器的所有者:

    • 通過執行此對象的同步 (Sychronized) 實例方法。
    • 通過執行在此對象上進行同步的 synchronized 語句的正文。
    • 對于 Class 類型的對象,可以通過執行該類的同步靜態方法。

    一次只能有一個線程擁有對象的監視器。

     

    拋出:
    IllegalMonitorStateException - 如果當前的線程不是此對象監視器的所有者。

    7.notifyAll

    public final void notifyAll()
    喚醒在此對象監視器上等待的所有線程。線程通過調用其中一個 wait 方法,在對象的監視器上等待。

    直到當前的線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。

    此方法只應由作為此對象監視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監視器所有者的方法的描述。

     

    拋出:
    IllegalMonitorStateException - 如果當前的線程不是此對象監視器的所有者。

    8.finalize

    protected void finalize()
    throws Throwable
    當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。子類重寫 finalize 方法,以配置系統資源或執行其他清除。

    finalize 的常規協定是:當 JavaTM 虛擬機已確定尚未終止的任何線程無法再通過任何方法訪問此對象時,將調用此方法,除非由于準備終止的其他某個對象或類的終結操作執行了某個操作。finalize 方法可以采取任何操作,其中包括再次使此對象對其他線程可用;不過,finalize 的主要目的是在不可撤消地丟棄對象之前執行清除操作。例如,表示輸入/輸出連接的對象的 finalize 方法可執行顯式 I/O 事務,以便在永久丟棄對象之前中斷連接。

    Object 類的 finalize 方法執行非特殊性操作;它僅執行一些常規返回。Object 的子類可以重寫此定義。

    Java 編程語言不保證哪個線程將調用某個給定對象的 finalize 方法。但可以保證在調用 finalize 時,調用 finalize 的線程將不會持有任何用戶可見的同步鎖定。如果 finalize 方法拋出未捕獲的異常,那么該異常將被忽略,并且該對象的終結操作將終止。

    在啟用某個對象的 finalize 方法后,將不會執行進一步操作,直到 Java 虛擬機再次確定尚未終止的任何線程無法再通過任何方法訪問此對象,其中包括由準備終止的其他對象或類執行的可能操作,在執行該操作時,對象可能被丟棄。

    對于任何給定對象,Java 虛擬機最多只調用一次 finalize 方法。

    finalize 方法拋出的任何異常都會導致此對象的終結操作停止,但可以通過其他方法忽略它。

     

    拋出:
    Throwable - 此方法拋出的 Exception

    9.wait

    public final void wait(long timeout)
    throws InterruptedException
    導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量。

    當前的線程必須擁有此對象監視器。

    此方法導致當前線程(稱之為 T)將其自身放置在對象的等待集中,然后放棄此對象上的所有同步要求。出于線程調度目的,線程 T 被禁用,且處于休眠狀態,直到發生以下四種情況之一:

    • 其他某個線程調用此對象的 notify 方法,并且線程 T 碰巧被任選為被喚醒的線程。
    • 其他某個線程調用此對象的 notifyAll 方法。
    • 其他某個線程中斷線程 T
    • 已經到達指定的實際時間。但是,如果 timeout 為零,則不考慮實際時間,該線程將一直等待,直到獲得通知。
    然后,從對象的等待集中刪除線程 T,并重新進行線程調度。然后,該線程以常規方式與其他線程競爭,以獲得在該對象上同步的權利;一旦獲得對該對象的控制權,該對象上的所有其同步聲明都將被還原到以前的狀態 - 這就是調用 wait 方法時的情況。然后,線程 Twait 方法的調用中返回。所以,從 wait 方法返回時,該對象和線程 T 的同步狀態與調用 wait 方法時的情況完全相同。

    在沒有被通知、中斷或超時的情況下,線程還可以喚醒一個所謂的虛假喚醒 (spurious wakeup)。雖然這種情況在實踐中很少發生,但是應用程序必須通過以下方式防止其發生,即對應該導致該線程被提醒的條件進行測試,如果不滿足該條件,則繼續等待。換句話說,等待應總是發生在循環中,如下面的示例:

    synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(timeout);
    ... // Perform action appropriate to condition
    }
    
    (有關這一主題的更多信息,請參閱 Doug Lea 撰寫的《Concurrent Programming in Java (Second Edition)》(Addison-Wesley, 2000) 中的第 3.2.3 節或 Joshua Bloch 撰寫的《Effective Java Programming Language Guide》(Addison-Wesley, 2001) 中的第 50 項。

    如果當前線程在等待時被其他線程中斷,則會拋出 InterruptedException。在按上述形式恢復此對象的鎖定狀態時才會拋出此異常。

    注意,由于 wait 方法將當前的線程放入了對象的等待集中,所以它只能解除此對象的鎖定;可以同步當前線程的任何其他對象在線程等待時仍處于鎖定狀態。

    此方法只應由作為此對象監視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監視器所有者的方法的描述。

     

    參數:
    timeout - 要等待的最長時間(以毫秒為單位)。
    拋出:
    IllegalArgumentException - 如果超時值為負。
    IllegalMonitorStateException - 如果當前的線程不是此對象監視器的所有者。
    InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,另一個線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態 被清除。

    10.wait

    public final void wait(long timeout,
    int nanos)
    throws InterruptedException
    導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量。

    此方法類似于一個參數的 wait 方法,但它允許更好地控制在放棄之前等待通知的時間量。用毫微秒度量的實際時間量可以通過以下公式計算出來:

    1000000*timeout+nanos

    在其他所有方面,此方法執行的操作與帶有一個參數的 wait(long) 方法相同。需要特別指出的是,wait(0, 0)wait(0) 相同。

    當前的線程必須擁有此對象監視器。該線程發布對此監視器的所有權,并等待下面兩個條件之一發生:

    • 其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監視器上等待的線程醒來。
    • timeout 毫秒值與 nanos 毫微秒參數值之和指定的超時時間已用完。

    然后,該線程等到重新獲得對監視器的所有權后才能繼續執行。

    對于某一個參數的版本,實現中斷和虛假喚醒是有可能的,并且此方法應始終在循環中使用:

    synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(timeout, nanos);
    ... // Perform action appropriate to condition
    }
    
    此方法只應由作為此對象監視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監視器所有者的方法的描述。

     

    參數:
    timeout - 要等待的最長時間(以毫秒為單位)。
    nanos - 額外時間(以毫微秒為單位,范圍是 0-999999)。
    拋出:
    IllegalArgumentException - 如果超時值是負數,或者毫微秒值不在 0-999999 范圍內。
    IllegalMonitorStateException - 如果當前線程不是此對象監視器的所有者。
    InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,其他線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態 被清除。

    11.wait

    public final void wait()
    throws InterruptedException
    導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。換句話說,此方法的行為就好像它僅執行 wait(0) 調用一樣。

    當前的線程必須擁有此對象監視器。該線程發布對此監視器的所有權并等待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監視器上等待的線程醒來。然后該線程將等到重新獲得對監視器的所有權后才能繼續執行。

    對于某一個參數的版本,實現中斷和虛假喚醒是可能的,而且此方法應始終在循環中使用:

    synchronized (obj) {
    while (<condition does not hold>)
    obj.wait();
    ... // Perform action appropriate to condition
    }
    
    此方法只應由作為此對象監視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監視器所有者的方法的描述。

     

    拋出:
    IllegalMonitorStateException - 如果當前的線程不是此對象監視器的所有者。
    InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,另一個線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態 被清除。
    posted @ 2008-12-05 10:25 jiafang83 閱讀(8166) | 評論 (0)編輯 收藏

        今天忽然想起這么個問題:在eclipse下運行的java程序,它們的字節碼文件跑哪去啦,怎么在項目中看不到呢?在網上查了一下,終于找到了原因所在。
        原來classes文件夾所在的目錄是程序編譯輸出的路徑,只有在eclipse下的Resource透視圖下,才能顯示出來,在其它透視圖下都不能顯示。

                     
    posted @ 2008-12-05 10:02 jiafang83 閱讀(3363) | 評論 (0)編輯 收藏
         摘要: 轉載:http://download.csdn.net/source/245338   1. Jdbc的六個編程步驟 1. 注冊一個驅動 注冊驅動程序有三種方式:                &nbs...  閱讀全文
    posted @ 2008-12-01 17:00 jiafang83 閱讀(1037) | 評論 (0)編輯 收藏
         摘要:   轉載:http://www.builder.com.cn/2007/1211/678982.shtml 目前,國內外信息化建設已經進入基于Web應用為核心的階段, Java作為應用于網絡的最好語言,前景無限看好。然而,就算用Java建造一個不是很煩瑣的web應用,也不是件輕松的事情。概括一下,實施Java的WEB項目需要掌握的技術如下: l  &...  閱讀全文
    posted @ 2008-12-01 16:23 jiafang83 閱讀(195) | 評論 (0)編輯 收藏
         摘要: 轉載:http://www.tkk7.com/rongxh7      分頁顯示一直是web開發中一大煩瑣的難題,傳統的網頁設計只在一個JSP或者ASP頁面中書寫所有關于數據庫操作的代碼,那樣做分頁可能簡單一點,但當把網站分層開發后,分頁就比較困難了,下面是我做Spring+Hibernate+Struts2項目時設計的分頁代碼,與大家分享交流。 ...  閱讀全文
    posted @ 2008-12-01 14:08 jiafang83 閱讀(1410) | 評論 (2)編輯 收藏
    轉載:http://peak.javaeye.com/blog/52606

    1、 PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域OutOfMemoryError: PermGen space從表面上看就是內存益出,解決方法也一定是加大內存。說說為什么會內存益出:這一部分用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。

    改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
    2、

    在tomcat中redeploy時出現outofmemory的錯誤.

    可以有以下幾個方面的原因:

    1,使用了proxool,因為proxool內部包含了一個老版本的cglib.

    2, log4j,最好不用,只用common-logging

    3, 老版本的cglib,快點更新到最新版。

    4,更新到最新的hibernate3.2


    3、

    這里以tomcat環境為例,其它WEB服務器如jboss,weblogic等是同一個道理。
    一、java.lang.OutOfMemoryError: PermGen space
    PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域,
    這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space中,
    它和存放類實例(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對
    PermGen space進行清理,所以如果你的應用中有很多CLASS的話,就很可能出現PermGen space錯誤,
    這種錯誤常見在web服務器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小
    超過了jvm默認的大小(4M)那么就會產生此錯誤信息了。
    解決方法: 手動設置MaxPermSize大小

    修改TOMCAT_HOME/bin/catalina.sh
    在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:
    JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
    建議:將相同的第三方jar文件移置到tomcat/shared/lib目錄下,這樣可以達到減少jar 文檔重復占用內存的目的。

    二、java.lang.OutOfMemoryError: Java heap space
    Heap size 設置
    JVM堆的設置是指java程序運行過程中JVM可以調配使用的內存空間的設置.JVM在啟動的時候會自動設置Heap size的值,
    其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)是物理內存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等選項可
    進行設置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
    提示:在JVM中如果98%的時間是用于GC且可用的Heap size 不足2%的時候將拋出此異常信息。
    提示:Heap Size 最大不要超過可用物理內存的80%,一般的要將-Xms和-Xmx選項設置為相同,而-Xmn為1/4的-Xmx值。
    解決方法:手動設置Heap size
    修改TOMCAT_HOME/bin/catalina.sh
    在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:
    JAVA_OPTS="-server -Xms800m -Xmx800m   -XX:MaxNewSize=256m"

    三、實例,以下給出1G內存環境下java jvm 的參數設置參考:

    JAVA_OPTS="-server -Xms800m -Xmx800m  -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "


    三、相關資料

    http://www.tot.name/show/3/7/20061112220131.htm

    http://www.tot.name/show/3/7/20061112220054.htm

    http://www.tot.name/show/3/7/20061112220201.htm

    題外話:經常看到網友抱怨tomcat的性能不如...,不穩定等,其實根據筆者幾年的經驗,從"互聯星空“到現在的房產門戶網,我們
    均使用tomcat作為WEB服務器,每天訪問量百萬多,tomcat仍然運行良好。建議大家有問題多從自己程序入手,多看看java的DOC文檔
    并詳細了解JVM的知識。這樣開發的程序才會健壯。

    JVM 性能調整的一些基本概念
    http://www.wujianrong.com/archives/2007/02/jvm_1.html#more
    apache+Tomcat負載平衡設置詳解

    http://www.wujianrong.com/archives/2006/11/apachetomcat.html
    java - the Java application launcher

    http://java.sun.com/j2se/1.3/docs/tooldocs/linux/java.html
    posted @ 2008-11-21 17:16 jiafang83 閱讀(161) | 評論 (0)編輯 收藏

     
    轉自:http://www.java-cn.com/technology/tech/4310.html

    本文闡述了怎么使用DBMS存儲過程。我闡述了使用存儲過程的基本的和高級特性,比如返回ResultSet。本文假設你對DBMS和JDBC已經非常熟悉,也假設你能夠毫無障礙地閱讀其它語言寫成的代碼(即不是Java的語言),但是,并不要求你有任何存儲過程的編程經歷。

    存儲過程是指保存在數據庫并在數據庫端執行的程序。你可以使用特殊的語法在Java類中調用存儲過程。在調用時,存儲過程的名稱及指定的參數通過JDBC連接發送給DBMS,執行存儲過程并通過連接(如果有)返回結果。
    使用存儲過程擁有和使用基于EJB或CORBA這樣的應用服務器一樣的好處。區別是存儲過程可以從很多流行的DBMS中免費使用,而應用服務器大都非常昂貴。這并不只是許可證費用的問題。使用應用服務器所需要花費的管理、編寫代碼的費用,以及客戶程序所增加的復雜性,都可以通過DBMS中的存儲過程所整個地替代。

    你可以使用Java,Python,Perl或C編寫存儲過程,但是通常使用你的DBMS所指定的特定語言。Oracle使用PL/SQL,PostgreSQL使用pl/pgsql,DB2使用Procedural SQL。這些語言都非常相似。在它們之間移植存儲過程并不比在Sun的EJB規范不同實現版本之間移植Session Bean困難。并且,存儲過程是為嵌入SQL所設計,這使得它們比Java或C等語言更加友好地方式表達數據庫的機制。

    因為存儲過程運行在DBMS自身,這可以幫助減少應用程序中的等待時間。不是在Java代碼中執行4個或5個SQL語句,而只需要在服務器端執行1個存儲過程。網絡上的數據往返次數的減少可以戲劇性地優化性能。

    使用存儲過程

    簡單的老的JDBC通過CallableStatement類支持存儲過程的調用。該類實際上是PreparedStatement的一個子類。假設我們有一個poets數據庫。數據庫中有一個設置詩人逝世年齡的存儲過程。下面是對老酒鬼Dylan Thomas(old soak Dylan Thomas,不指定是否有關典故、文化,請批評指正。譯注)進行調用的詳細代碼:


    try{ 
    int age = 39;

    String poetName = "dylan thomas";

    CallableStatement proc = connection.prepareCall("{ call set_death_age(?, ?) }");

    proc.setString(1, poetName);

    proc.setInt(2, age);

    cs.execute();

    }catch (SQLException e){ // ....}



    傳給prepareCall方法的字串是存儲過程調用的書寫規范。它指定了存儲過程的名稱,?代表了你需要指定的參數。
    和JDBC集成是存儲過程的一個很大的便利:為了從應用中調用存儲過程,不需要存根(stub)類或者配置文件,除了你的DBMS的JDBC驅動程序外什么也不需要。

    當這段代碼執行時,數據庫的存儲過程就被調用。我們沒有去獲取結果,因為該存儲過程并不返回結果。執行成功或失敗將通過例外得知。失敗可能意味著調用存儲過程時的失敗(比如提供的一個參數的類型不正確),或者一個應用程序的失敗(比如拋出一個例外指示在poets數據庫中并不存在“Dylan Thomas”)

    結合SQL操作與存儲過程

    映射Java對象到SQL表中的行相當簡單,但是通常需要執行幾個SQL語句;可能是一個SELECT查找ID,然后一個INSERT插入指定ID的數據。在高度規格化(符合更高的范式,譯注)的數據庫模式中,可能需要多個表的更新,因此需要更多的語句。Java代碼會很快地膨脹,每一個語句的網絡開銷也迅速增加。
    將這些SQL語句轉移到一個存儲過程中將大大簡化代碼,僅涉及一次網絡調用。所有關聯的SQL操作都可以在數據庫內部發生。并且,存儲過程語言,例如PL/SQL,允許使用SQL語法,這比Java代碼更加自然。下面是我們早期的存儲過程,使用Oracle的PL/SQL語言編寫:


    create procedure set_death_age(poet VARCHAR2, poet_age NUMBER) 

    poet_id NUMBER;

    begin SELECT id INTO poet_id FROM poets WHERE name = poet;

    INSERT INTO deaths (mort_id, age) VALUES (poet_id, poet_age);

    end set_death_age;



    很獨特?不。我打賭你一定期待看到一個poets表上的UPDATE。這也暗示了使用存儲過程實現是多么容易的一件事情。set_death_age幾乎可以肯定是一個很爛的實現。我們應該在poets表中添加一列來存儲逝世年齡。Java代碼中并不關心數據庫模式是怎么實現的,因為它僅調用存儲過程。我們以后可以改變數據庫模式以提高性能,但是我們不必修改我們代碼。

    下面是調用上面存儲過程的Java代碼:


    public static void setDeathAge(Poet dyingBard, int age) throws SQLException{ 

    Connection con = null;

    CallableStatement proc = null;

    try {

    con = connectionPool.getConnection();

    proc = con.prepareCall("{ call set_death_age(?, ?) }");

    proc.setString(1, dyingBard.getName());

    proc.setInt(2, age);

    proc.execute();

    }

    finally {

    try { proc.close(); }

    catch (SQLException e) {}

    con.close();

    }

    }



    為了確保可維護性,建議使?孟裾舛?庋??tatic方法。這也使得調用存儲過程的代碼集中在一個簡單的模版代碼中。如果你用到許多存儲過程,就會發現僅需要拷貝、粘貼就可以創建新的方法。因為代碼的模版化,甚至也可以通過腳本自動生產調用存儲過程的代碼。

    Functions

    存儲過程可以有返回值,所以CallableStatement類有類似getResultSet這樣的方法來獲取返回值。當存儲過程返回一個值時,你必須使用registerOutParameter方法告訴JDBC驅動器該值的SQL類型是什么。你也必須調整存儲過程調用來指示該過程返回一個值。

    下面接著上面的例子。這次我們查詢Dylan Thomas逝世時的年齡。這次的存儲過程使用PostgreSQL的pl/pgsql:


    create function snuffed_it_when (VARCHAR) returns integer 'declare 

    poet_id NUMBER;

    poet_age NUMBER;

    begin

    --first get the id associated with the poet.

    SELECT id INTO poet_id FROM poets WHERE name = $1;

    --get and return the age.

    SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id;

    return age;

    end;' language 'pl/pgsql';



    另外,注意pl/pgsql參數名通過Unix和DOS腳本的$n語法引用。同時,也注意嵌入的注釋,這是和Java代碼相比的另一個優越性。在Java中寫這樣的注釋當然是可以的,但是看起來很凌亂,并且和SQL語句脫節,必須嵌入到Java String中。

    下面是調用這個存儲過程的Java代碼:


    connection.setAutoCommit(false); 

    CallableStatement proc = connection.prepareCall("{ ? = call snuffed_it_when(?) }");

    proc.registerOutParameter(1, Types.INTEGER);

    proc.setString(2, poetName);

    cs.execute();

    int age = proc.getInt(2);



    如果指定了錯誤的返回值類型會怎樣?那么,當調用存儲過程時將拋出一個RuntimeException,正如你在ResultSet操作中使用了一個錯誤的類型所碰到的一樣。

    復雜的返回值

    關于存儲過程的知識,很多人好像就熟悉我們所討論的這些。如果這是存儲過程的全部功能,那么存儲過程就不是其它遠程執行機制的替換方案了。存儲過程的功能比這強大得多。
    當你執行一個SQL查詢時,DBMS創建一個叫做cursor(游標)的數據庫對象,用于在返回結果中迭代每一行。ResultSet是當前時間點的游標的一個表示。這就是為什么沒有緩存或者特定數據庫的支持,你只能在ResultSet中向前移動。

    某些DBMS允許從存儲過程中返回游標的一個引用。JDBC并不支持這個功能,但是Oracle、PostgreSQL和DB2的JDBC驅動器都支持在ResultSet上打開到游標的指針(pointer)。

    設想列出所有沒有活到退休年齡的詩人,下面是完成這個功能的存儲過程,返回一個打開的游標,同樣也使用PostgreSQL的pl/pgsql語言:


    create procedure list_early_deaths () return refcursor as 'declare 

    toesup refcursor;

    begin

    open toesup for SELECT poets.name, deaths.age FROM poets, deaths
    -- all entries in deaths are for poets. -- but the table might become generic. 

    WHERE poets.id = deaths.mort_id AND deaths.age < 60;

    return toesup;

    end;' language 'plpgsql';



    下面是調用該存儲過程的Java方法,將結果輸出到PrintWriter:


    PrintWriter: 

    static void sendEarlyDeaths(PrintWriter out){

    Connection con = null;

    CallableStatement toesUp = null;

    try {

    con = ConnectionPool.getConnection();

    // PostgreSQL needs a transaction to do this... con.

    setAutoCommit(false); // Setup the call.

    CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }");

    toesUp.registerOutParameter(1, Types.OTHER);

    toesUp.execute();

    ResultSet rs = (ResultSet) toesUp.getObject(1);

    while (rs.next()) {

    String name = rs.getString(1);

    int age = rs.getInt(2);

    out.println(name + " was " + age + " years old.");

    }

    rs.close();

    }

    catch (SQLException e) { // We should protect these calls. toesUp.close(); con.close();

    }

    }



    因為JDBC并不直接支持從存儲過程中返回游標,我們使用Types.OTHER來指示存儲過程的返回類型,然后調用getObject()方法并對返回值進行強制類型轉換。

    這個調用存儲過程的Java方法是mapping的一個好例子。Mapping是對一個集上的操作進行抽象的方法。不是在這個過程上返回一個集,我們可以把操作傳送進去執行。本例中,操作就是把ResultSet打印到一個輸出流。這是一個值得舉例的很常用的例子,下面是調用同一個存儲過程的另外一個方法實現:


    public class ProcessPoetDeaths{ 

    public abstract void sendDeath(String name, int age);

    }

    static void mapEarlyDeaths(ProcessPoetDeaths mapper){

    Connection con = null;

    CallableStatement toesUp = null;

    try {

    con = ConnectionPool.getConnection();

    con.setAutoCommit(false);

    CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }");

    toesUp.registerOutParameter(1, Types.OTHER);

    toesUp.execute();

    ResultSet rs = (ResultSet) toesUp.getObject(1);

    while (rs.next()) {

    String name = rs.getString(1);

    int age = rs.getInt(2);

    mapper.sendDeath(name, age);

    }

    rs.close();

    } catch (SQLException e) { // We should protect these calls. toesUp.close();

    con.close();

    }

    }



    這允許在ResultSet數據上執行任意的處理,而不需要改變或者復制獲取ResultSet的方法:


    static void sendEarlyDeaths(final PrintWriter out){ 

    ProcessPoetDeaths myMapper = new ProcessPoetDeaths() {

    public void sendDeath(String name, int age) {

    out.println(name + " was " + age + " years old.");

    }

    };

    mapEarlyDeaths(myMapper);

    }



    這個方法使用ProcessPoetDeaths的一個匿名實例調用mapEarlyDeaths。該實例擁有sendDeath方法的一個實現,和我們上面的例子一樣的方式把結果寫入到輸出流。當然,這個技巧并不是存儲過程特有的,但是和存儲過程中返回的ResultSet結合使用,是一個非常強大的工具。

    結論

    存儲過程可以幫助你在代碼中分離邏輯,這基本上總是有益的。這個分離的好處有:
    ?6?1 快速創建應用,使用和應用一起改變和改善的數據庫模式。
    ?6?1 數據庫模式可以在以后改變而不影響Java對象,當我們完成應用后,可以重新設計更好的模式。
    ?6?1 存儲過程通過更好的SQL嵌入使得復雜的SQL更容易理解。
    ?6?1 編寫存儲過程比在Java中編寫嵌入的SQL擁有更好的工具--大部分編輯器都提供語法高亮!
    ?6?1 存儲過程可以在任何SQL命令行中測試,這使得調試更加容易。

    并不是所有的數據庫都支持存儲過程,但是存在許多很棒的實現,包括免費/開源的和非免費的,所以移植并不是一個問題。Oracle、PostgreSQL和DB2都有類似的存儲過程語言,并且有在線的社區很好地支持。
    存儲過程工具很多,有像TOAD或TORA這樣的編輯器、調試器和IDE,提供了編寫、維護PL/SQL或pl/pgsql的強大的環境。

    存儲過程確實增加了你的代碼的開銷,但是它們和大多數的應用服務器相比,開銷小得多。

    posted @ 2008-11-20 15:25 jiafang83 閱讀(186) | 評論 (0)編輯 收藏
    首先建立兩個存儲過程:
    存儲過程p_1----從cell表中取出數據
    create proc p_1
    as
    select * from cell
    go
    存儲過程p_2----往cell表里插入數據
    create proc p_2
        @name varchar(40),
        @remark varchar(40)
    as
    insert into cell(name,remark) values(@name,@remark)
    go
    調用存儲過程p_1:
    import java.sql.*;

    /**
     * jdbc中調用存儲過程
     * @author jiafang83
     *
     */
    public class Procedure2 {

        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=fish";
            String user = "bm";
            String pwd = "bm";
            Connection conn = null;
            CallableStatement proc = null;//執行sql存儲過程的接口
            ResultSet rs = null;

    //        調用存儲過程p_1:從Cell表中取出數據
            try{
                Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
                conn = DriverManager.getConnection(url,user,pwd);
                proc = conn.prepareCall("{? = call p_1 ()}");
                proc.registerOutParameter(1, Types.REAL);
                rs = proc.executeQuery();//取得結果集
                while(rs.next()){
                    System.out.println(rs.getString("name"));
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(rs!=null) rs.close();
                if(proc!=null)proc.close();
                if(conn!=null)conn.close();
            }
        }

    }

    調用存儲過程p_2:
    import java.sql.*;

    /**
     * jdbc中調用存儲過程
     * @author jiafang83
     *
     */
    public class Procedure {

        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=fish";
            String user = "bm";
            String pwd = "bm";
            Connection conn = null;
            CallableStatement proc = null;//執行sql存儲過程的接口
           
    //        調用存儲過程p_2:向Cell表中插入數據
            try{
                Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
                conn = DriverManager.getConnection(url,user,pwd);
                proc = conn.prepareCall("{call p_2 (?,?)}");
                proc.setString(1, "測試");
                proc.setString(2, "測試");
                proc.execute();
                System.out.println("成功調用存儲過程,插入數據!");
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(proc!=null)proc.close();
                if(conn!=null)conn.close();
            }
        }



    posted @ 2008-11-20 14:25 jiafang83 閱讀(3020) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 丰满亚洲大尺度无码无码专线 | 亚洲综合激情九月婷婷| 在线观看午夜亚洲一区| 亚洲AV伊人久久青青草原 | 无码人妻丰满熟妇区免费| 色www永久免费| 在线观看免费视频网站色| 久久久精品国产亚洲成人满18免费网站| 九九全国免费视频| 99久久精品毛片免费播放| 国产精成人品日日拍夜夜免费| 免费日本一区二区| 1000部禁片黄的免费看 | 亚洲阿v天堂在线2017免费| 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲heyzo专区无码综合| 青草久久精品亚洲综合专区| 特级毛片免费观看视频| 久久精品免费大片国产大片| 成人无码WWW免费视频| 2015日韩永久免费视频播放| 色婷婷7777免费视频在线观看| 成人毛片免费观看| 夜色阁亚洲一区二区三区| 国产成人精品日本亚洲专区61 | 亚洲日韩精品一区二区三区无码 | 日韩a在线观看免费观看| 亚洲第一页综合图片自拍| 亚洲成A人片在线观看WWW| 亚洲乱码卡一卡二卡三| 激情无码亚洲一区二区三区| 国产日韩AV免费无码一区二区三区| 无码少妇精品一区二区免费动态| 嫖丰满老熟妇AAAA片免费看| 国产成人涩涩涩视频在线观看免费 | h视频在线观看免费| 最近最好最新2019中文字幕免费| 18禁超污无遮挡无码免费网站国产| 免费人成年轻人电影| 亚洲成AV人片在线观看无码| 亚洲avav天堂av在线网爱情|