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

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

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

    posts - 120,  comments - 19,  trackbacks - 0
     

    最近身體不太好,轉(zhuǎn)貼一則文章,提醒自己多多休息和鍛煉。

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

     只要踏入在我們IT這個行業(yè), 過不了幾年身體就是亞健康狀態(tài),過渡的話就可能會“過勞死”,要想防止“過勞死”,就必須了解身體為我們發(fā)出的“過勞死”信號。

    ??? 研究者認為:在這27項癥狀和因素中占有7項以上,即是有過度疲勞危險者,占10項以上就可能在任何時候發(fā)生“過勞死”。同時,在第1項到第9項中占兩項以上或者在第10項到18項中占3項以上者也要特別注意,這27項癥狀和因素分別是:

      1.經(jīng)常感到疲倦,忘性大;

      2.酒量突然下降,即使飲酒也不感到有滋味;

      3.突然覺得有衰老感;

      4.肩部和頸部發(fā)木發(fā)僵;

      5.因為疲勞和苦悶失眠;

      6.有一點小事也煩躁和生氣;

      7.經(jīng)常頭痛和胸悶;

      8.發(fā)生高血壓、糖尿病,心電圖測試結(jié)果不正常;

      9.體重突然變化大,出現(xiàn)“將軍肚”;

      10.幾乎每天晚上聚餐飲酒;

      11.一天喝5杯以上咖啡;

      12.經(jīng)常不吃早飯或吃飯時間不固定;

      13.喜歡吃油炸食品;

      14.一天吸煙30支以上;

      15.晚上10時也不回家或者12時以后回家占一半以上;

      16.上下班單程占2小時以上;

      17.最近幾年運動也不流汗;

      18.自我感覺身體良好而不看病;

      19.一天工作10小時以上;

      20.星期天也上班;

      21.經(jīng)常出差,每周只在家住兩三天;

      22.夜班多,工作時間不規(guī)則;

      23.最近有工作調(diào)動或工作變化;

      24.升職或者工作量增多;

      25.最近以來加班時間突然增加;

      26.人際關(guān)系突然變壞;

      27.最近工作失誤或者發(fā)生不和。

      針對如何擺脫過度疲勞,何永成博士開出如下處方:

      消除腦力疲勞法:適當參加體育鍛煉和文娛活動,積極休息。如果是心理疲勞,千萬不要濫用鎮(zhèn)靜劑、安眠藥等,應找出引起感情憂郁的原因,并求得解脫。病理性疲勞,應及時找醫(yī)生檢查和治療。

      飲食補充法:注意飲食營養(yǎng)的搭配。多吃含蛋白質(zhì)、脂肪和豐富的B族維生素食物,如豆腐、牛奶、魚肉類,多吃水果、蔬菜,適量飲水。

      休息恢復法:每天都要留出一定的休息時間。聽音樂、繪畫、散步等有助解除生理疲勞。

      科學健身方法:一是有氧運動,如跑步、打球、打拳、騎車、爬山等;二是腹式呼吸,全身放松后深呼吸,鼓足腹部,憋一會兒再慢慢呼出;三是做保健操;四是點穴按摩。

    ??? 哥們, 上面27條在你身上出現(xiàn)幾條癥狀了?? 怕怕吧??

      建議哥們們每天早上和傍晚各抽出一小時鍛煉身體,畢竟身體是革命的本錢!

    轉(zhuǎn)自: 電子商務論壇 http://bbs.eczn.com/

    posted @ 2006-02-21 08:59 阿成 閱讀(204) | 評論 (0)編輯 收藏

    Hibenate作為一種Java對象持久化技術(shù),在很多大型的多層體系構(gòu)架中得到應用,比如在開發(fā)一套電子商務系統(tǒng)可以以J2EE作為體系構(gòu)架,Structs作為java Web應用框架,以Hibenate實現(xiàn)對象持久化任務,以EJB或者普通的javabean實現(xiàn)業(yè)務邏輯,其實現(xiàn)過程的復雜度可想而知,下面收集一些在Hibenate中多對多關(guān)系中應用技巧給大家分享

    1.cascade="..."?

    cascade屬性并不是多對多關(guān)系一定要用的,有了它只是讓我們在插入或刪除對像時更方便一些,只要在cascade的源頭上插入或是刪除,所有cascade的關(guān)系就會被自己動的插入或是刪除。便是為了能正確的cascade,unsaved-value是個很重要的屬性。

    Hibernate通過這個屬性來判斷一個對象應該save還是update,如果這齠韻蟮膇d是unsaved-value的話,那說明這個對象不是persistence object要save(insert);如果id是非unsaved-value的話,那說明這個對象是persistence object(數(shù)據(jù)庫中已存在),只要update就行了。saveOrUpdate方法用的也是這個機制。

    2.inverse="ture"?

    inverse屬性默認是false的,就是說關(guān)系的兩端都來維護關(guān)系。這個意思就是說,如有一個Student, Teacher和TeacherStudent表,Student和Teacher是多對多對多關(guān)系,這個關(guān)系由TeacherStudent這個表來表現(xiàn)。那么什么時候插入或刪除TeacherStudent表中的記錄來維護關(guān)系呢?在用hibernate時,我們不會顯示的對TeacherStudent表做操作。

    對TeacherStudent的操作是hibernate幫我們做的。hibernate就是看hbm文件中指定的是"誰"維護關(guān)系,那個在插入或刪除"誰"時,就會處發(fā)對關(guān)系表的操作。前提是"誰"這個對象已經(jīng)知道這個關(guān)系了,就是說關(guān)系另一頭的對象已經(jīng)set或是add到"誰"這個對象里來了。前面說過inverse默認是false,就是關(guān)系的兩端都維護關(guān)系,對其中任一個操作都會處發(fā)對表系表的操作。當在關(guān)系的一頭,如Student中的bag或set中用了inverse="true"時,那就代表關(guān)系是由另一關(guān)維護的(Teacher)。就是說當這插入Student時,不會操作TeacherStudent表,即使Student已經(jīng)知道了關(guān)系。只有當Teacher插入或刪除時才會處發(fā)對關(guān)系表的操作。

    所以,當關(guān)系的兩頭都用inverse="true"是不對的,就會導致任何操作都不處發(fā)對關(guān)系表的操作。當兩端都是inverse="false"或是default值是,在代碼對關(guān)系顯示的維護也是不對的,會導致在關(guān)系表中插入兩次關(guān)系。在一對多關(guān)系中inverse就更有意義了。在多對多中,在哪端inverse="true"效果差不多(在效率上)。但是在一對多中,如果要一方維護關(guān)系,就會使在插入或是刪除"一"方時去update"多"方的每一個與這個"一"的對象有關(guān)系的對象。

    而如果讓"多"方面維護關(guān)系時就不會有update操作,因為關(guān)系就是在多方的對象中的,直指插入或是刪除多方對象就行了。當然這時也要遍歷"多"方的每一個對象顯示的操作修關(guān)系的變化體現(xiàn)到DB中。不管怎樣說,還是讓"多"方維護關(guān)系更直觀一些。

    3.cascade和inverse有什么區(qū)別?

    可以這樣理解,cascade定義的是關(guān)系兩端對象到對象的級聯(lián)關(guān)系;而inverse定義的是關(guān)系和對象的級聯(lián)關(guān)系。

    4.net.sf.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): 2, of class: Xxxxx

    這個問題出現(xiàn)在要刪除關(guān)系的一頭時。如,要刪除一個已經(jīng)和Student有關(guān)系的Teacher。當tx.commit();時才會拋出這個異常。這時一個在關(guān)系另一頭的Student對象中的Set或是List中把這個Teacher對象顯示的remove掉,再session.delete(這個teacher);。這是為了防止在Student端有cascade時把這個Teacher對象再存回DB。

    所以,這個異常的只有在Student的關(guān)系定義中有cascade="...",而且沒有像上面說的顯示的解除關(guān)系時才會出現(xiàn)。所以防止出現(xiàn)這個異常的方法就是:1,在Student端不用cascade;2,或是用cascade的話,就顯示的刪除對像中的關(guān)系。 3,在Teacher端要用cascade。

    5.net.sf.hibernate.HibernateException: identifier of an instance of my.MyObject altered from N to N

    這個異常其實不是多對多中常遇到的,但是這個異常的提示不make sense,所以提一下,是因為id的java對象中的type和hbm文件中定義的不一樣,如:java中用long,而hbm中用type="integer",并且generator用的是identity時就會出現(xiàn)。

    posted @ 2006-02-15 10:09 阿成 閱讀(279) | 評論 (0)編輯 收藏

    延遲初始化錯誤是運用Hibernate開發(fā)項目時最常見的錯誤。如果對一個類或者集合配置了延遲檢索策略,那么必須當代理類實例或代理集合處于持久化狀態(tài)(即處于Session范圍內(nèi))時,才能初始化它。如果在游離狀態(tài)時才初始化它,就會產(chǎn)生延遲初始化錯誤。

    下面把Customer.hbm.xml文件的<class>元素的lazy屬性設為true,表示使用延遲檢索策略:

    <class name="mypack.Customer" table="CUSTOMERS" lazy="true">

    當執(zhí)行Session的load()方法時,Hibernate不會立即執(zhí)行查詢CUSTOMERS表的select語句,僅僅返回Customer類的代理類的實例,這個代理類具由以下特征:

    (1) 由Hibernate在運行時動態(tài)生成,它擴展了Customer類,因此它繼承了Customer類的所有屬性和方法,但它的實現(xiàn)對于應用程序是透明的。
    (2) 當Hibernate創(chuàng)建Customer代理類實例時,僅僅初始化了它的OID屬性,其他屬性都為null,因此這個代理類實例占用的內(nèi)存很少。
    (3) 當應用程序第一次訪問Customer代理類實例時(例如調(diào)用customer.getXXX()或customer.setXXX()方法),Hibernate會初始化代理類實例,在初始化過程中執(zhí)行select語句,真正從數(shù)據(jù)庫中加載Customer對象的所有數(shù)據(jù)。但有個例外,那就是當應用程序訪問Customer代理類實例的getId()方法時,Hibernate不會初始化代理類實例,因為在創(chuàng)建代理類實例時OID就存在了,不必到數(shù)據(jù)庫中去查詢。

    提示:Hibernate采用CGLIB工具來生成持久化類的代理類。CGLIB是一個功能強大的Java字節(jié)碼生成工具,它能夠在程序運行時動態(tài)生成擴展Java類或者實現(xiàn)Java接口的代理類。關(guān)于CGLIB的更多知識,請參考:http://cglib.sourceforge.net/。

    以下代碼先通過Session的load()方法加載Customer對象,然后訪問它的name屬性:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    customer.getName();
    tx.commit();

    在運行session.load()方法時Hibernate不執(zhí)行任何select語句,僅僅返回Customer類的代理類的實例,它的OID為1,這是由load()方法的第二個參數(shù)指定的。當應用程序調(diào)用customer.getName()方法時,Hibernate會初始化Customer代理類實例,從數(shù)據(jù)庫中加載Customer對象的數(shù)據(jù),執(zhí)行以下select語句:

    select * from CUSTOMERS where ID=1;
    select * from ORDERS where CUSTOMER_ID=1;

    當<class>元素的lazy屬性為true,會影響Session的load()方法的各種運行時行為,下面舉例說明。

    1.如果加載的Customer對象在數(shù)據(jù)庫中不存在,Session的load()方法不會拋出異常,只有當運行customer.getName()方法時才會拋出以下異常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
    mypack.Customer

    2.如果在整個Session范圍內(nèi),應用程序沒有訪問過Customer對象,那么Customer代理類的實例一直不會被初始化,Hibernate不會執(zhí)行任何select語句。以下代碼試圖在關(guān)閉Session后訪問Customer游離對象:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    tx.commit();
    session.close();
    customer.getName();

    由于引用變量customer引用的Customer代理類的實例在Session范圍內(nèi)始終沒有被初始化,因此在執(zhí)行customer.getName()方法時,Hibernate會拋出以下異常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

    由此可見,Customer代理類的實例只有在當前Session范圍內(nèi)才能被初始化。

    3.net.sf.hibernate.Hibernate類的initialize()靜態(tài)方法用于在Session范圍內(nèi)顯式初始化代理類實例,isInitialized()方法用于判斷代理類實例是否已經(jīng)被初始化。例如:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    if(!Hibernate.isInitialized(customer))
    Hibernate.initialize(customer);
    tx.commit();
    session.close();
    customer.getName();

    以上代碼在Session范圍內(nèi)通過Hibernate類的initialize()方法顯式初始化了Customer代理類實例,因此當Session關(guān)閉后,可以正常訪問Customer游離對象。

    4.當應用程序訪問代理類實例的getId()方法時,不會觸發(fā)Hibernate初始化代理類實例的行為,例如:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    customer.getId();
    tx.commit();
    session.close();
    customer.getName();

    當應用程序訪問customer.getId()方法時,該方法直接返回Customer代理類實例的OID值,無需查詢數(shù)據(jù)庫。由于引用變量customer始終引用的是沒有被初始化的Customer代理類實例,因此當Session關(guān)閉后再執(zhí)行customer.getName()方法,Hibernate會拋出以下異常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

    posted @ 2006-02-13 17:24 阿成 閱讀(328) | 評論 (0)編輯 收藏

    使用FileUpload組件實現(xiàn)文件上傳
    文件上傳在web應用中非常普遍,要在servlet/jsp環(huán)境中實現(xiàn)文件上傳功能非常容易,因為網(wǎng)上已經(jīng)有許多用java開發(fā)的組件用于文件上傳,本文以commons-fileupload組件為例,為servlet/jsp應用添加文件上傳功能。

    common-fileupload組件是apache的一個開源項目之一,可以從http://jakarta.apache.org/commons/fileupload/下載。該組件簡單易用,可實現(xiàn)一次上傳一個或多個文件,并可限制文件大小。

    下載后解壓zip包,將commons-fileupload-1.0.jar復制到tomcat的webapps\你的webapp\WEB-INF\lib\下,如果目錄不存在請自建目錄。

    新建一個servlet: Upload.java用于文件上傳:

    import java.io.*;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import org.apache.commons.fileupload.*;

    public class Upload extends HttpServlet {

    ????private String uploadPath = "C:\\upload\\"; // 用于存放上傳文件的目錄
    ????private String tempPath = "C:\\upload\\tmp\\"; // 用于存放臨時文件的目錄

    ????public void doPost(HttpServletRequest request, HttpServletResponse response)
    ????????throws IOException, ServletException
    ????{
    ????}
    }

    當servlet收到瀏覽器發(fā)出的Post請求后,在doPost()方法中實現(xiàn)文件上傳。以下是示例代碼:

    public void doPost(HttpServletRequest request, HttpServletResponse response)
    ????throws IOException, ServletException
    {
    ????try {
    ????????DiskFileUpload fu = new DiskFileUpload();
    ????????// 設置最大文件尺寸,這里是4MB
    ????????fu.setSizeMax(4194304);
    ????????// 設置緩沖區(qū)大小,這里是4kb
    ????????fu.setSizeThreshold(4096);
    ????????// 設置臨時目錄:
    ????????fu.setRepositoryPath(tempPath);

    ????????// 得到所有的文件:
    ????????List fileItems = fu.parseRequest(request);
    ????????Iterator i = fileItems.iterator();
    ????????// 依次處理每一個文件:
    ????????while(i.hasNext()) {
    ????????????FileItem fi = (FileItem)i.next();
    ????????????// 獲得文件名,這個文件名包括路徑:
    ????????????String fileName = fi.getName();
    ????????????if(fileName!=null) {
    ????????????????// 在這里可以記錄用戶和文件信息
    ????????????????// ...
    ????????????????// 寫入文件a.txt,你也可以從fileName中提取文件名:
    ????????????????fi.write(new File(uploadPath + "a.txt"));
    ????????????}
    ????????}
    ????????// 跳轉(zhuǎn)到上傳成功提示頁面
    ????}
    ????catch(Exception e) {
    ????????// 可以跳轉(zhuǎn)出錯頁面
    ????}
    }

    如果要在配置文件中讀取指定的上傳文件夾,可以在init()方法中執(zhí)行:

    public void init() throws ServletException {
    ????uploadPath = ....
    ????tempPath = ....
    ????// 文件夾不存在就自動創(chuàng)建:
    ????if(!new File(uploadPath).isDirectory())
    ????????new File(uploadPath).mkdirs();
    ????if(!new File(tempPath).isDirectory())
    ????????new File(tempPath).mkdirs();
    }

    編譯該servlet,注意要指定classpath,確保包含commons-upload-1.0.jar和tomcat\common\lib\servlet-api.jar。

    配置servlet,用記事本打開tomcat\webapps\你的webapp\WEB-INF\web.xml,沒有的話新建一個。典型配置如下:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app
    ????PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    ????"http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>
    ????<servlet>
    ????????<servlet-name>Upload</servlet-name>
    ????????<servlet-class>Upload</servlet-class>
    ????</servlet>

    ????<servlet-mapping>
    ????????<servlet-name>Upload</servlet-name>
    ????????<url-pattern>/fileupload</url-pattern>
    ????</servlet-mapping>
    </web-app>


    配置好servlet后,啟動tomcat,寫一個簡單的html測試:

    <form action="fileupload" method="post"
    enctype="multipart/form-data" name="form1">
    ??<input type="file" name="file">
    ??<input type="submit" name="Submit" value="upload">
    </form>

    注意action="fileupload"其中fileupload是配置servlet時指定的url-pattern。

    posted @ 2006-02-10 15:52 阿成 閱讀(357) | 評論 (0)編輯 收藏

    spring下載包中doc目錄下的MVC-step-by-step和sample目錄下的例子都是比較好的spring開發(fā)的例子.

     1、如何學習Spring?

      你可以通過下列途徑學習spring:

      (1) spring下載包中doc目錄下的MVC-step-by-step和sample目錄下的例子都是比較好的spring開發(fā)的例子。

      (2) AppFuse集成了目前最流行的幾個開源輕量級框架或者工具 Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts 。

      你可以通過AppFuse源代碼來學習spring。

    AppFuse網(wǎng)站:http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse

      (3)Spring 開發(fā)指南(夏昕)(http://www.xiaxin.net/Spring_Dev_Guide.rar)

      一本spring的入門書籍,里面介紹了反轉(zhuǎn)控制和依賴注射的概念,以及spring的bean管理,spring的MVC,spring和hibernte,iBatis的結(jié)合。

      (4) spring學習的中文論壇

      SpringFramework中文論壇(http://spring.jactiongroup.net)

      Java視線論壇(http://forum.javaeye.com)的spring欄目

      2、利用Spring框架編程,console打印出log4j:WARN Please initialize the log4j system properly?

      說明你的log4j.properties沒有配置。請把log4j.properties放到工程的classpath中,eclipse的classpath為bin目錄,由于編譯后src目錄下的文件會拷貝到bin目錄下,所以你可以把log4j.properties放到src目錄下。

      這里給出一個log4j.properties的例子:

    log4j.rootLogger=DEBUG,stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n

      3、出現(xiàn) java.lang.NoClassDefFoundError?

      一般情況下是由于你沒有把必要的jar包放到lib中。

      比如你要采用spring和hibernate(帶事務支持的話),你除了spring.jar外還需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的幾個jar包。

    http://www.springframework.org/download.html下載spring開發(fā)包,提供兩種zip包
    spring-framework-1.1.3-with-dependencies.zip和spring-framework-1.1.3.zip,我建議你下載spring-framework-1.1.3-with-dependencies.zip。這個zip解壓縮后比后者多一個lib目錄,其中有hibernate、j2ee、dom4j、aopalliance、jakarta-commons等常用包。

      4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文件?

      原因一般有兩個:

      (1)該xml文件沒有在classpath中。

      (2)applicationContext-hibernate.xml中的xml名字沒有帶包名。比如:


    <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    <property name="dataSource"><ref bean="dataSource"/></property>
    <property name="mappingResources">
     <list>
      <value>User.hbm.xml</value>
      錯,改為:
      <value>com/yz/spring/domain/User.hbm.xml</value>
     </list>
    </property>
    <property name="hibernateProperties">
    <props>
     <prop key="hibernate.dialect"> net.sf.hibernate.dialect.MySQLDialect </prop>
     <prop key="hibernate.show_sql">true</prop>
    </props>
    </property>
    </bean>

      5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean class?

      出現(xiàn)異常的原因是在application-xxx.xml中property name的錯誤。

      <property name="...."> 中name的名字是與bean的set方法相關(guān)的,而且要注意大小寫。

      比如


    public class PostManageImpl extends BaseManage implements PostManage {
     private PostDAO dao = null;
     public void setPostDAO(PostDAO postDAO){
      this.dao = postDAO;
     }
    }

      那么xml的定義應該是:


    <bean id="postManage" parent="txProxyTemplate">
    <property name="target">
     <bean class="com.yz.spring.service.implement.PostManageImpl">
      <property name="postDAO"><ref bean="postDAO"/></property> 對
      <property name="dao"><ref bean="postDAO"/></property> 錯
     </bean>
    </property>
    </bean>

      6、Spring中如何實現(xiàn)事務管理?

      首先,如果使用mysql,確定mysql為InnoDB類型。

      事務管理的控制應該放到商業(yè)邏輯層。你可以寫個處理商業(yè)邏輯的JavaBean,在該JavaBean中調(diào)用DAO,然后把該Bean的方法納入spring的事務管理。

      比如:xml文件定義如下:


    <bean id="txProxyTemplate" abstract="true"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="transactionAttributes">
    <props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="remove*">PROPAGATION_REQUIRED</prop>
    <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>

    <bean id="userManage" parent="txProxyTemplate">
     <property name="target">
      <bean class="com.yz.spring.service.implement.UserManageImpl">
       <property name="userDAO"><ref bean="userDAO"/></property>
      </bean>
     </property>
    </bean>

      com.yz.spring.service.implement.UserManageImpl就是我們的實現(xiàn)商業(yè)邏輯的JavaBean。我們通過parent元素聲明其事務支持。

      7、如何管理Spring框架下更多的JavaBean?

      JavaBean越多,spring配置文件就越大,這樣不易維護。為了使配置清晰,我們可以將JavaBean分類管理,放在不同的配置文件中。 應用啟動時將所有的xml同時加載。

      比如:

      DAO層的JavaBean放到applicationContext-hibernate.xml中,商業(yè)邏輯層的JavaBean放到applicationContext-service.xml中。然后啟動類中調(diào)用以下代碼載入所有的ApplicationContext。


    String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml",
    "com/yz/spring/service/applicationContext-service.xml"};
    ctx = new ClassPathXmlApplicationContext(paths);

      8、web應用中如何加載ApplicationContext?

      可以通過定義web.xml,由web容器自動加載。


    <servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext-hibernate.xml</param-value>
    <param-value>/WEB-INF/applicationContext-service.xml</param-value>
    </context-param>

      9、在spring中如何配置的log4j?

      在web.xml中加入以下代碼即可。


    <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>

      10、Spring框架入門的編程問題解決了,我該如何更深地領(lǐng)會Spring框架呢?

      這兩本書你該去看看。這兩本書是由Spring的作者Rod Johnson編寫的。


    Expert One on one J2EE Design and Development
    Expert One on one J2EE Development Without EJB

      你也該看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern。


    http://www.martinfowler.com/articles/injection.html
     
      再好好研讀一下spring的文檔。


    http://www.jactiongroup.net/reference/html/index.html(中文版,未全部翻譯)

      還有就是多實踐吧。
    posted @ 2006-02-10 10:46 阿成 閱讀(257) | 評論 (0)編輯 收藏
    、JDK,SDK,JRE,JVM

    我們可以通過helloworld來理解這幾個縮寫詞的具體含義:

    public class HelloWorld {
    public static void main(String[] args) {
    System.out.println("helloworld");
    }
    }



    編譯之后, 我們得到了HelloWorld.class(圖中的"Your program's class files")
    在HelloWorld里面, 我們調(diào)用了 JAVA API中的 java.lang.System這個類的靜態(tài)成員對象 out, out 的靜態(tài)方法: public static void println(String string);

    然后我們讓虛擬機器來執(zhí)行這個HelloWorld。
    1. 虛擬機會在classpath中找到HelloWorld.class。
    2. 虛擬機中的解釋器(interpret)會把HelloWorld.class解釋成字節(jié)碼。
    3. 把解釋后的字節(jié)碼交由execution engin執(zhí)行。
    4. execution engin會調(diào)用native method(即平臺相關(guān)的字節(jié)碼)來在host system的stdout(顯示器)的指定部分打印出指定的字符串。
    5. 這樣, 我們就看到"helloworld"字樣了。

    有了這個流程后, 我們就好理解上面幾個術(shù)語了:
    a. JDK: java develop kit (JAVA API包)
    b. SDK: software develop kit, 以前JDK 叫做java software develop kit, 后來出了1.2版本后, 就改名叫jdk了, 省時省力, 節(jié)約成本。
    c. JRE. java runtime environment 我們的helloworld必須在JRE(JAVA運行環(huán)境,JAVA運行環(huán)境又叫JAVA平臺)里面, 才能跑起來。 所以, 顯然地, JRE其實就是JDK + JVM

    d. JVM java virtual machine. 簡單地講, 就是把class文件變成字節(jié)碼, 然后送到excution engin中執(zhí)行。 而為什么叫虛擬機, 而不叫真實機呢? 因為JVM本身是又不能運算, 又不能讓顯示器顯示"helloworld"的, 它只能再調(diào)用host system的API, 比如在w32里面就會調(diào)c++的API, 來讓CPU幫他做做算術(shù)運算, 來調(diào)用c++里面的API來控制顯示器顯示顯示字符串。 而這些API不是JDK里面有的,我們平時又看不見的,所以我們就叫它native api了(亦曰私房XX)。

    e. 解釋平臺無關(guān)。 有人會說, 在linux的里面調(diào)用native api與w32里面調(diào)用的api肯定不一樣吧? 那為什么說JAVA是平臺無關(guān)的呢?
    其 實是這樣的, 君不見java.sun.com里面又有jdk-for-w32又有jdk-for-linux下載嗎? 剛才不是說了嗎? native api, native api, 就是我們平時看不見的api嗎! 調(diào)用native這些煩瑣的活兒都讓jdk去做了。 所以我們調(diào)用的時候只用知道jdk(java api) 里面的java.io.*能提供磁盤訪問功能, java.awt.* 能畫個框框畫個圓圓就行了嗎。 至于JDK又是怎么調(diào)用的, 在LINXU上更圓呢? 還是在W32上更圓,(x) 這個就是JDK個人的事情了。(理論上講是一樣圓的, 當然這又和顯示器是否純平相關(guān)了:D)

    同時, 這里就引申出了另一個話題。 既如何編寫平臺無關(guān)的JAVA程序。 其中關(guān)鍵的一條, 就是調(diào)用且只調(diào)用jdk中的API, 而不要私自調(diào)用native api。 原因很簡單啊, JDK-for-linux和JDK-for-w32表面都是一樣的, 所以我在w32里面調(diào)用JDK寫的java程序,在linux里面也會一樣的寫法啊, 所以就可以移植來移植去都沒問題。(b) 但是如果我在w32里面調(diào)用了 一個圖形顯示的native api, 當我移植到linux去的時候, 誰又能保證里面也有相同名稱, 相同參數(shù),相同返回值, 相同功能的native api供我調(diào)用呢!(?)

    -以上是個人理解, 如有錯漏之處, 萬望指出, 共同進步!


    2.Re:[入門]什么叫JDK,SDK,JRE,JVM [Re: sojan] Copy to clipboard
    Posted by: reddream
    Posted on: 2003-11-27 13:02

    sojan wrote:
    ... 所以, 顯然地, JRE其實就是JDK + JVM...

    這句話不對。JRE顧名思義只是java class運行時需要的環(huán)境,JDK不僅包含了JRE,還提供了開發(fā)調(diào)試java程序需要的工具

    3.Re:[入門]什么叫JDK,SDK,JRE,JVM [Re: sojan] Copy to clipboard
    Posted by: sojan
    Posted on: 2003-11-27 13:30

    我將JRE(Java運行環(huán)境)理解為JAVA PLATFORM, 既JAVA平臺。

    reddream 的話也是對的, JRE同時也包括讓JAVA運行起來的工具,比如: javac(編譯), java(運行), javap(反編譯)這些。

    另一角度

    如果安裝了JDK,會發(fā)同你的電腦有兩套JRE,一套位于 jre 另外一套位于 C:\Program Files\Java\j2re1.4.1_01 目錄下,后面這套比前面那套少了Server端的Java虛擬機,不過直接將前面那套的Server端Java虛擬機復制過來就行了。而且在安裝JDK可 以選擇是否安裝這個位于 C:\Program Files\Jav a 目錄下的JRE。如果你只安裝JRE,而不是JDK,那么只會在 C:\Program Files\Java 目錄下安裝唯一的一套JRE。?

    ??? JRE的地位就象一臺PC機一樣,我們寫好的Win32應用程序需要操作系統(tǒng)幫我們運行,同樣的,我們編寫的Java程序也必須要JRE才能運行。所以當 你裝完JDK后,如果分別在硬盤上的兩個不同地方安裝了兩套JRE,那么你可以想象你的電腦有兩臺虛擬的Java PC機,都具有運行Java程序的功能。所以我們可以說,只要你的電腦安裝了JRE,就可以正確運行Jav a應用程序。

    ???? ?1、為什么Sun要讓JDK安裝兩套相同的JRE?這是因為JDK里面有很多用Java所編寫的開發(fā)工具(如javac.exe、jar.exe等),而且都放置在 lib\tools.jar 里。從下面例子可以看出,先將tools.jar改名為tools1.jar,然后運行javac.exe,顯示如下結(jié)果: Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac /Main 這個意思是說,你輸入javac.exe與輸入 java -cp c:\jdk\lib\tools.jar com.sun.tools.javac.Main 是一樣的,會得到相同的結(jié)果。從這里我們可以證明javac.exe只是一個包裝器(Wrapper),而制作的目的是為了讓開發(fā)者免于輸入太長的指命。 而且可以發(fā)現(xiàn)lib目錄下的程序都很小,不大于2 9K,從這里我們可以得出一個結(jié)論。就是JDK里的工具幾乎是用Java所編寫,所以也是Java應用程序,因此要使用JDK所附的工具來開發(fā)Java程 序,也必須要自行附一套JRE才行,所以位于C:\Program Files\Java目錄下的那套JRE就是用來運行一般Java程序用的。

    ???? 2、如果一臺電腦安裝兩套以上的JRE,誰來決定呢?這個重大任務就落在java.exe身上。Java.exe的工作就是找到合適的JRE來運行 Java程序。 Java.exe依照底下的順序來查找JRE:自己的目錄下有沒有JRE;父目錄有沒有JRE;查詢注冊表: [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment] 所以java.exe的運行結(jié)果與你的電腦里面哪個JRE被執(zhí)行有很大的關(guān)系。

    ??? 3、介紹JVM JRE目錄下的Bin目錄有兩個目錄:server與client。這就是真正的jvm.dll所在。 jvm.dll無法單獨工作,當jvm.dll啟動后,會使用explicit的方法(就是使用Win32 API之中的LoadLibrary()與GetProcAddress()來載入輔助用的動態(tài)鏈接庫),而這些輔助用的動態(tài)鏈接庫(.dll)都必須位 于jvm.dll所在目錄的父目錄之中。因此想使用哪個JVM,只需要設置PATH,指向JRE所在目錄底下的jvm.dll。



    對于這個系列里的問題,每個學Java的人都應該搞懂。當然,如果只是學Java玩玩就無所謂了。如果你認為自己已經(jīng)超越初學者了,卻不很懂這些問題,請將你自己重歸初學者行列。內(nèi)容均來自于CSDN的經(jīng)典老貼。

    二、
    java環(huán)境變量有三個

    JAVA_HOME,CLASSPATH,PATH.

    只有這三個java環(huán)境變量

    JAVA_HOME指向的是JDK的安裝路徑,如C:\j2sdk1.4.2_09,在這路徑下你應該能夠找到bin、lib等目錄。當然,你愿意放哪里,就放哪里。我的是放在c盤根目錄

    JAVA_HOME=C:\j2sdk1.4.2_09;

    PATH環(huán)境變量,目的是為了指向JDK的bin目錄,這里面放的是各種編譯執(zhí)行命令。

    我的設置是:

    PATH=C:\j2sdk1.4.2_09\bin;C:\j2sdk1.4.2_09\jre\bin;

    需要說明,系統(tǒng)中本身就有PATH環(huán)境變量,只要把C:\j2sdk1.4.2_09\bin;C:\j2sdk1.4.2_09\jre\bin;直接放到后面即可,中間有分號間隔。

    如果你的JAVA_HOME是別的目錄,就對照著該吧。

    CLASSPATH最重要。

    CLASSPATH=.;C:\j2sdk1.4.2_09\lib;C:\j2sdk1.4.2_09\lib\tools.jar;這時我的設置。這是類的路徑。前面加上點和分號,意為首先在當前目錄查找,以后你自己編寫類的時候自然明白這點。

    那么為什么要設置環(huán)境變量,以前編寫c語言的時候怎么不設置呢?

    由于WINDOWS默認的搜索順序,先搜索當前目錄的,再搜索系統(tǒng)目錄的,再搜索PATH環(huán)境變量設定的。你在編寫java程序時,在一個指定目錄,這里沒有編譯執(zhí)行命令,而系統(tǒng)目錄里面,也沒有編譯執(zhí)行命令。所以放在環(huán)境變量里面, 從這里你應該可以看出,環(huán)境變量是干什么用的了。簡單說就是告訴操作系統(tǒng)到那里去找指定的文件。你要是把系統(tǒng)目錄給改了,看你用dos命令還好不好使。

    配置完后,在命令提示符下,鍵入java -version,如果出現(xiàn)java的一些信息,說明配置成功

    //問題一
    在命令行中輸入 javac HelloWorld.java 后出現(xiàn)如下錯誤:
    ′javac′ 不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件。
    (javac: Command not found)

    這個錯誤產(chǎn)生的原因是沒有設置好環(huán)境變量path。下面以windows xp為例子來講解如何設置環(huán)境變量path。右鍵單擊我的電腦->屬性->高級->環(huán)境變量,然后在系統(tǒng)變量中選擇添加,變量名為path,變量值為d:\j2se\bin(這里假設你的jdk的安裝d:\j2se,當然如果你的jdk的安裝目錄是別的目錄的話,比如c:\jdk1.2,那么你的path應該設置為c:\jdk1.2\bin。)。最后不要忘記了重新啟動,當然你也可以再接著設置完另一個環(huán)境變量classpath后再重新啟動。

    //問題二
    在命令行中輸入 java HelloWorld 后出現(xiàn)如下錯(注意不是 java HelloWorld.class 。)

    Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld

    這個錯誤產(chǎn)生的原因是沒有設置好環(huán)境變量classpath,這時只需要將classpath的值設置為
    .;d:\j2se\lib\dt.jar;d:\j2se\lib\tools.jar
    當然,如果你的jdk的安裝目錄是在別的地方的話,比如c:\jdk1.2,那么你的classpath變量應該設置為
    .;c:\jdk1.2\lib\dt.jar;c:\jdk1.2\lib\tools.jar
    最后重新啟動,然后再小心:)的去編譯你的HelloWorld.java程序


    三、基礎(chǔ)知識


    問題一:我聲明了什么!

    String s = "Hello world!";

    許多人都做過這樣的事情,但是,我們到底聲明了什么?回答通常是:一個String,內(nèi)容是“Hello world!”。這樣模糊的回答通常是概念不清的根源。如果要準確的回答,一半的人大概會回答錯誤。
    這個語句聲明的是一個指向?qū)ο蟮囊茫麨椤皊”,可以指向類型為String的任何對象,目前指向"Hello world!"這個String類型的對象。這就是真正發(fā)生的事情。我們并沒有聲明一個String對象,我們只是聲明了一個只能指向String對象的引用變量。所以,如果在剛才那句語句后面,如果再運行一句:

    String string = s;

    我們是聲明了另外一個只能指向String對象的引用,名為string,并沒有第二個對象產(chǎn)生,string還是指向原來那個對象,也就是,和s指向同一個對象。

    問題二:"=="和equals方法究竟有什么區(qū)別?

    ==操作符專門用來比較變量的值是否相等。比較好理解的一點是:
    int a=10;
    int b=10;
    則a==b將是true。
    但不好理解的地方是:
    String a=new String("foo");
    String b=new String("foo");
    則a==b將返回false。

    根據(jù)前一帖說過,對象變量其實是一個引用,它們的值是指向?qū)ο笏诘膬?nèi)存地址,而不是對象本身。a和b都使用了new操作符,意味著將在內(nèi)存中產(chǎn)生兩個內(nèi)容為"foo"的字符串,既然是“兩個”,它們自然位于不同的內(nèi)存地址。a和b的值其實是兩個不同的內(nèi)存地址的值,所以使用"=="操作符,結(jié)果會是false。誠然,a和b所指的對象,它們的內(nèi)容都是"foo",應該是“相等”,但是==操作符并不涉及到對象內(nèi)容的比較。
    對象內(nèi)容的比較,正是equals方法做的事。

    看一下Object對象的equals方法是如何實現(xiàn)的:
    boolean equals(Object o){

    return this==o;

    }
    Object對象默認使用了==操作符。所以如果你自創(chuàng)的類沒有覆蓋equals方法,那你的類使用equals和使用==會得到同樣的結(jié)果。同樣也可以看出,Object的equals方法沒有達到equals方法應該達到的目標:比較兩個對象內(nèi)容是否相等。因為答案應該由類的創(chuàng)建者決定,所以Object把這個任務留給了類的創(chuàng)建者。

    看一下一個極端的類:
    Class Monster{
    private String content;
    ...
    boolean equals(Object another){ return true;}

    }
    我覆蓋了equals方法。這個實現(xiàn)會導致無論Monster實例內(nèi)容如何,它們之間的比較永遠返回true。

    所以當你是用equals方法判斷對象的內(nèi)容是否相等,請不要想當然。因為可能你認為相等,而這個類的作者不這樣認為,而類的equals方法的實現(xiàn)是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列碼的集合(HashSet,HashMap,HashTable),請察看一下java doc以確認這個類的equals邏輯是如何實現(xiàn)的。

    問題三:String到底變了沒有?

    沒有。因為String被設計成不可變(immutable)類,所以它的所有對象都是不可變對象。請看下列代碼:

    String s = "Hello";
    s = s + " world!";

    s所指向的對象是否改變了呢?從本系列第一篇的結(jié)論很容易導出這個結(jié)論。我們來看看發(fā)生了什么事情。在這段代碼中,s原先指向一個String對象,內(nèi)容是"Hello",然后我們對s進行了+操作,那么s所指向的那個對象是否發(fā)生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個String對象,內(nèi)容為"Hello world!",原來那個對象還存在于內(nèi)存之中,只是s這個引用變量不再指向它了。
    通過上面的說明,我們很容易導出另一個結(jié)論,如果經(jīng)常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用String來代表字符串的話會引起很大的內(nèi)存開銷。因為String對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉(zhuǎn)換十分容易。
    同時,我們還可以知道,如果要使用內(nèi)容相同的字符串,不必每次都new一個String。例如我們要在構(gòu)造器中對一個名叫s的String引用變量進行初始化,把它設置為初始值,應當這樣做:
    public class Demo {
    private String s;
    ...
    public Demo {
    s = "Initial Value";
    }
    ...
    }
    而非
    s = new String("Initial Value");
    后者每次都會調(diào)用構(gòu)造器,生成新對象,性能低下且內(nèi)存開銷大,并且沒有意義,因為String對象不可改變,所以對于內(nèi)容相同的字符串,只要一個String對象來表示就可以了。也就說,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個對象,他們的String類型屬性s都指向同一個對象。
    上面的結(jié)論還基于這樣一個事實:對于字符串常量,如果內(nèi)容相同,Java認為它們代表同一個String對象。而用關(guān)鍵字new調(diào)用構(gòu)造器,總是會創(chuàng)建一個新的對象,無論內(nèi)容是否相同。
    至于為什么要把String類設計成不可變類,是它的用途決定的。其實不只String,很多Java標準類庫中的類都是不可變的。在開發(fā)一個系統(tǒng)的時候,我們有時候也需要設計不可變類,來傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類有一些優(yōu)點,比如因為它的對象是只讀的,所以多線程并發(fā)訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態(tài)都要一個對象來代表,可能會造成性能上的問題。所以Java標準類庫還提供了一個可變版本,即StringBuffer。

    問題四:final關(guān)鍵字到底修飾了什么?

    final使得被修飾的變量"不變",但是由于對象型變量的本質(zhì)是“引用”,使得“不變”也有了兩種含義:引用本身的不變,和引用指向的對象不變。

    引用本身的不變:
    final StringBuffer a=new StringBuffer("immutable");
    final StringBuffer b=new StringBuffer("not immutable");
    a=b;//編譯期錯誤

    引用指向的對象不變:
    final StringBuffer a=new StringBuffer("immutable");
    a.append(" broken!"); //編譯通過

    可見,final只對引用的“值”(也即它所指向的那個對象的內(nèi)存地址)有效,它迫使引用只能指向初始指向的那個對象,改變它的指向會導致編譯期錯誤。至于它所指向的對象的變化,final是不負責的。這很類似==操作符:==操作符只負責引用的“值”相等,至于這個地址所指向的對象內(nèi)容是否相等,==操作符是不管的。

    理解final問題有很重要的含義。許多程序漏洞都基于此----final只能保證引用永遠指向固定對象,不能保證那個對象的狀態(tài)不變。在多線程的操作中,一個對象會被多個線程共享或修改,一個線程對對象無意識的修改可能會導致另一個使用此對象的線程崩潰。一個錯誤的解決方法就是在此對象新建的時候把它聲明為final,意圖使得它“永遠不變”。其實那是徒勞的。

    問題五:到底要怎么樣初始化!

    本問題討論變量的初始化,所以先來看一下Java中有哪些種類的變量。
    1. 類的屬性,或者叫值域
    2. 方法里的局部變量
    3. 方法的參數(shù)

    對于第一種變量,Java虛擬機會自動進行初始化。如果給出了初始值,則初始化為該初始值。如果沒有給出,則把它初始化為該類型變量的默認初始值。

    int類型變量默認初始值為0
    float類型變量默認初始值為0.0f
    double類型變量默認初始值為0.0
    boolean類型變量默認初始值為false
    char類型變量默認初始值為0(ASCII碼)
    long類型變量默認初始值為0
    所有對象引用類型變量默認初始值為null,即不指向任何對象。注意數(shù)組本身也是對象,所以沒有初始化的數(shù)組引用在自動初始化后其值也是null。

    對于兩種不同的類屬性,static屬性與instance屬性,初始化的時機是不同的。instance屬性在創(chuàng)建實例的時候初始化,static屬性在類加載,也就是第一次用到這個類的時候初始化,對于后來的實例的創(chuàng)建,不再次進行初始化。這個問題會在以后的系列中進行詳細討論。

    對于第二種變量,必須明確地進行初始化。如果再沒有初始化之前就試圖使用它,編譯器會抗議。如果初始化的語句在try塊中或if塊中,也必須要讓它在第一次使用前一定能夠得到賦值。也就是說,把初始化語句放在只有if塊的條件判斷語句中編譯器也會抗議,因為執(zhí)行的時候可能不符合if后面的判斷條件,如此一來初始化語句就不會被執(zhí)行了,這就違反了局部變量使用前必須初始化的規(guī)定。但如果在else塊中也有初始化語句,就可以通過編譯,因為無論如何,總有至少一條初始化語句會被執(zhí)行,不會發(fā)生使用前未被初始化的事情。對于try-catch也是一樣,如果只有在try塊里才有初始化語句,編譯部通過。如果在catch或finally里也有,則可以通過編譯。總之,要保證局部變量在使用之前一定被初始化了。所以,一個好的做法是在聲明他們的時候就初始化他們,如果不知道要出事化成什么值好,就用上面的默認值吧!

    其實第三種變量和第二種本質(zhì)上是一樣的,都是方法中的局部變量。只不過作為參數(shù),肯定是被初始化過的,傳入的值就是初始值,所以不需要初始化。

    問題六:instanceof是什么東東?

    instanceof是Java的一個二元操作符,和==,>,<是同一類東東。由于它是由字母組成的,所以也是Java的保留關(guān)鍵字。它的作用是測試它左邊的對象是否是它右邊的類的實例,返回boolean類型的數(shù)據(jù)。舉個例子:

    String s = "I AM an Object!";
    boolean isObject = s instanceof Object;

    我們聲明了一個String對象引用,指向一個String對象,然后用instancof來測試它所指向的對象是否是Object類的一個實例,顯然,這是真的,所以返回true,也就是isObject的值為True。
    instanceof有一些用處。比如我們寫了一個處理賬單的系統(tǒng),其中有這樣三個類:

    public class Bill {//省略細節(jié)}
    public class PhoneBill extends Bill {//省略細節(jié)}
    public class GasBill extends Bill {//省略細節(jié)}

    在處理程序里有一個方法,接受一個Bill類型的對象,計算金額。假設兩種賬單計算方法不同,而傳入的Bill對象可能是兩種中的任何一種,所以要用instanceof來判斷:

    public double calculate(Bill bill) {
    if (bill instanceof PhoneBill) {
    //計算電話賬單
    }
    if (bill instanceof GasBill) {
    //計算燃氣賬單
    }
    ...
    }
    這樣就可以用一個方法處理兩種子類。

    然而,這種做法通常被認為是沒有好好利用面向?qū)ο笾械亩鄳B(tài)性。其實上面的功能要求用方法重載完全可以實現(xiàn),這是面向?qū)ο笞兂蓱械淖龇ǎ苊饣氐浇Y(jié)構(gòu)化編程模式。只要提供兩個名字和返回值都相同,接受參數(shù)類型不同的方法就可以了:

    public double calculate(PhoneBill bill) {
    //計算電話賬單
    }

    public double calculate(GasBill bill) {
    //計算燃氣賬單
    }

    所以,使用instanceof在絕大多數(shù)情況下并不是推薦的做法,應當好好利用多態(tài)。

    posted @ 2006-02-07 11:29 阿成 閱讀(277) | 評論 (0)編輯 收藏
    ?? ??過年8天假很快就過去了,新的一年即將開始。
    ??? ?希望今年能夠快速的提高編程技術(shù),打好基礎(chǔ)。盡快成長起來。開工嘍!
    posted @ 2006-02-05 19:02 阿成 閱讀(233) | 評論 (0)編輯 收藏
    Java數(shù)據(jù)庫連接(JDBC)由一組用 Java 編程語言編寫的類和接口組成。JDBC 為工具/數(shù)據(jù)庫開發(fā)人員提供了一個標準的 API,使他們能夠用純Java API 來編寫數(shù)據(jù)庫應用程序。然而各個開發(fā)商的接口并不完全相同,所以開發(fā)環(huán)境的變化會帶來一定的配置變化。本文主要集合了不同數(shù)據(jù)庫的連接方式。

      一、連接各種數(shù)據(jù)庫方式速查表

      下面羅列了各種數(shù)據(jù)庫使用JDBC連接的方式,可以作為一個手冊使用。

      1、Oracle8/8i/9i數(shù)據(jù)庫(thin模式)

    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
    String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl為數(shù)據(jù)庫的SID
    String user="test";
    String password="test";
    Connection conn= DriverManager.getConnection(url,user,password);

      2、DB2數(shù)據(jù)庫

    Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
    String url="jdbc:db2://localhost:5000/sample"; //sample為你的數(shù)據(jù)庫名
    String user="admin";
    String password="";
    Connection conn= DriverManager.getConnection(url,user,password);

      3、Sql Server7.0/2000數(shù)據(jù)庫

    Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
    String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
    //mydb為數(shù)據(jù)庫
    String user="sa";
    String password="";
    Connection conn= DriverManager.getConnection(url,user,password);

      4、Sybase數(shù)據(jù)庫

    Class.forName("com.sybase.jdbc.SybDriver").newInstance();
    String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDB為你的數(shù)據(jù)庫名
    Properties sysProps = System.getProperties();
    SysProps.put("user","userid");
    SysProps.put("password","user_password");
    Connection conn= DriverManager.getConnection(url, SysProps);

      5、Informix數(shù)據(jù)庫

    Class.forName("com.informix.jdbc.IfxDriver").newInstance();
    String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
    user=testuser;password=testpassword"; //myDB為數(shù)據(jù)庫名
    Connection conn= DriverManager.getConnection(url);

      6、MySQL數(shù)據(jù)庫

    Class.forName("org.gjt.mm.mysql.Driver").newInstance();
    String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
    //myDB為數(shù)據(jù)庫名
    Connection conn= DriverManager.getConnection(url);

      7、PostgreSQL數(shù)據(jù)庫

    Class.forName("org.postgresql.Driver").newInstance();
    String url ="jdbc:postgresql://localhost/myDB" //myDB為數(shù)據(jù)庫名
    String user="myuser";
    String password="mypassword";
    Connection conn= DriverManager.getConnection(url,user,password);

      8、access數(shù)據(jù)庫直連用ODBC的

    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;
    String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb");
    Connection conn = DriverManager.getConnection(url,"","");
    Statement stmtNew=conn.createStatement() ;

      二、JDBC連接MySql方式

      下面是使用JDBC連接MySql的一個小的教程

      1、查找驅(qū)動程序

      MySQL目前提供的java驅(qū)動程序為Connection/J,可以從MySQL官方網(wǎng)站下載,并找到mysql-connector-java-3.0.15-ga-bin.jar文件,此驅(qū)動程序為純java驅(qū)動程序,不需做其他配置。

      2、動態(tài)指定classpath

      如果需要執(zhí)行時動態(tài)指定classpath,就在執(zhí)行時采用-cp方式。否則將上面的.jar文件加入到classpath環(huán)境變量中。

      3、加載驅(qū)動程序

    try{
     Class.forName(com.mysql.jdbc.Driver);
     System.out.println(Success loading Mysql Driver!);
    }catch(Exception e)
    {
     System.out.println(Error loading Mysql Driver!);
     e.printStackTrace();
    }

      4、設置連接的url

    jdbc:mysql://localhost/databasename[?pa=va][&pa=va]

      三、以下列出了在使用JDBC來連接Oracle數(shù)據(jù)庫時可以使用的一些技巧

      1、在客戶端軟件開發(fā)中使用Thin驅(qū)動程序

      在開發(fā)Java軟件方面,Oracle的數(shù)據(jù)庫提供了四種類型的驅(qū)動程序,二種用于應用軟件、applets、servlets等客戶端軟件,另外二種用于數(shù)據(jù)庫中的Java存儲過程等服務器端軟件。在客戶機端軟件的開發(fā)中,我們可以選擇OCI驅(qū)動程序或Thin驅(qū)動程序。OCI驅(qū)動程序利用Java本地化接口(JNI),通過Oracle客戶端軟件與數(shù)據(jù)庫進行通訊。Thin驅(qū)動程序是純Java驅(qū)動程序,它直接與數(shù)據(jù)庫進行通訊。為了獲得最高的性能,Oracle建議在客戶端軟件的開發(fā)中使用OCI驅(qū)動程序,這似乎是正確的。但我建議使用Thin驅(qū)動程序,因為通過多次測試發(fā)現(xiàn),在通常情況下,Thin驅(qū)動程序的性能都超過了OCI驅(qū)動程序。

      2、關(guān)閉自動提交功能,提高系統(tǒng)性能

      在第一次建立與數(shù)據(jù)庫的連接時,在缺省情況下,連接是在自動提交模式下的。為了獲得更好的性能,可以通過調(diào)用帶布爾值false參數(shù)的Connection類的setAutoCommit()方法關(guān)閉自動提交功能,如下所示:

      conn.setAutoCommit(false);

      值得注意的是,一旦關(guān)閉了自動提交功能,我們就需要通過調(diào)用Connection類的commit()和rollback()方法來人工的方式對事務進行管理。

      3、在動態(tài)SQL或有時間限制的命令中使用Statement對象

      在執(zhí)行SQL命令時,我們有二種選擇:可以使用PreparedStatement對象,也可以使用Statement對象。無論多少次地使用同一個SQL命令,PreparedStatement都只對它解析和編譯一次。當使用Statement對象時,每次執(zhí)行一個SQL命令時,都會對它進行解析和編譯。這可能會使你認為,使用PreparedStatement對象比使用Statement對象的速度更快。然而,我進行的測試表明,在客戶端軟件中,情況并非如此。因此,在有時間限制的SQL操作中,除非成批地處理SQL命令,我們應當考慮使用Statement對象。

      此外,使用Statement對象也使得編寫動態(tài)SQL命令更加簡單,因為我們可以將字符串連接在一起,建立一個有效的SQL命令。因此,我認為,Statement對象可以使動態(tài)SQL命令的創(chuàng)建和執(zhí)行變得更加簡單。

      4、利用helper函數(shù)對動態(tài)SQL命令進行格式化

      在創(chuàng)建使用Statement對象執(zhí)行的動態(tài)SQL命令時,我們需要處理一些格式化方面的問題。例如,如果我們想創(chuàng)建一個將名字O'Reilly插入表中的SQL命令,則必須使用二個相連的“''”號替換O'Reilly中的“'”號。完成這些工作的最好的方法是創(chuàng)建一個完成替換操作的helper方法,然后在連接字符串心服用公式表達一個SQL命令時,使用創(chuàng)建的helper方法。與此類似的是,我們可以讓helper方法接受一個Date型的值,然后讓它輸出基于Oracle的to_date()函數(shù)的字符串表達式。

      5、利用PreparedStatement對象提高數(shù)據(jù)庫的總體效率

      在使用PreparedStatement對象執(zhí)行SQL命令時,命令被數(shù)據(jù)庫進行解析和編譯,然后被放到命令緩沖區(qū)。然后,每當執(zhí)行同一個PreparedStatement對象時,它就會被再解析一次,但不會被再次編譯。在緩沖區(qū)中可以發(fā)現(xiàn)預編譯的命令,并且可以重新使用。在有大量用戶的企業(yè)級應用軟件中,經(jīng)常會重復執(zhí)行相同的SQL命令,使用PreparedStatement對象帶來的編譯次數(shù)的減少能夠提高數(shù)據(jù)庫的總體性能。如果不是在客戶端創(chuàng)建、預備、執(zhí)行PreparedStatement任務需要的時間長于Statement任務,我會建議在除動態(tài)SQL命令之外的所有情況下使用PreparedStatement對象。

      6、在成批處理重復的插入或更新操作中使用PreparedStatement對象

      如果成批地處理插入和更新操作,就能夠顯著地減少它們所需要的時間。Oracle提供的Statement和 CallableStatement并不真正地支持批處理,只有PreparedStatement對象才真正地支持批處理。我們可以使用addBatch()和executeBatch()方法選擇標準的JDBC批處理,或者通過利用PreparedStatement對象的setExecuteBatch()方法和標準的executeUpdate()方法選擇速度更快的Oracle專有的方法。要使用Oracle專有的批處理機制,可以以如下所示的方式調(diào)用setExecuteBatch():

    PreparedStatement pstmt3D null;
    try {
     ((OraclePreparedStatement)pstmt).setExecuteBatch(30);
     ...
     pstmt.executeUpdate();
    }

      調(diào)用setExecuteBatch()時指定的值是一個上限,當達到該值時,就會自動地引發(fā)SQL命令執(zhí)行,標準的executeUpdate()方法就會被作為批處理送到數(shù)據(jù)庫中。我們可以通過調(diào)用PreparedStatement類的sendBatch()方法隨時傳輸批處理任務。

      7、使用Oracle locator方法插入、更新大對象(LOB)

      Oracle的PreparedStatement類不完全支持BLOB和CLOB等大對象的處理,尤其是Thin驅(qū)動程序不支持利用PreparedStatement對象的setObject()和setBinaryStream()方法設置BLOB的值,也不支持利用setCharacterStream()方法設置CLOB的值。只有l(wèi)ocator本身中的方法才能夠從數(shù)據(jù)庫中獲取LOB類型的值。可以使用PreparedStatement對象插入或更新LOB,但需要使用locator才能獲取LOB的值。由于存在這二個問題,因此,我建議使用locator的方法來插入、更新或獲取LOB的值。

      8、使用SQL92語法調(diào)用存儲過程

      在調(diào)用存儲過程時,我們可以使用SQL92或Oracle PL/SQL,由于使用Oracle PL/SQL并沒有什么實際的好處,而且會給以后維護你的應用程序的開發(fā)人員帶來麻煩,因此,我建議在調(diào)用存儲過程時使用SQL92。

      9、使用Object SQL將對象模式轉(zhuǎn)移到數(shù)據(jù)庫中

      既然可以將Oracle的數(shù)據(jù)庫作為一種面向?qū)ο蟮臄?shù)據(jù)庫來使用,就可以考慮將應用程序中的面向?qū)ο竽J睫D(zhuǎn)到數(shù)據(jù)庫中。目前的方法是創(chuàng)建Java bean作為偽裝的數(shù)據(jù)庫對象,將它們的屬性映射到關(guān)系表中,然后在這些bean中添加方法。盡管這樣作在Java中沒有什么問題,但由于操作都是在數(shù)據(jù)庫之外進行的,因此其他訪問數(shù)據(jù)庫的應用軟件無法利用對象模式。如果利用Oracle的面向?qū)ο蟮募夹g(shù),可以通過創(chuàng)建一個新的數(shù)據(jù)庫對象類型在數(shù)據(jù)庫中模仿其數(shù)據(jù)和操作,然后使用JPublisher等工具生成自己的Java bean類。如果使用這種方式,不但Java應用程序可以使用應用軟件的對象模式,其他需要共享你的應用中的數(shù)據(jù)和操作的應用軟件也可以使用應用軟件中的對象模式。

      10、利用SQL完成數(shù)據(jù)庫內(nèi)的操作

      我要向大家介紹的最重要的經(jīng)驗是充分利用SQL的面向集合的方法來解決數(shù)據(jù)庫處理需求,而不是使用Java等過程化的編程語言。

      如果編程人員要在一個表中查找許多行,結(jié)果中的每個行都會查找其他表中的數(shù)據(jù),最后,編程人員創(chuàng)建了獨立的UPDATE命令來成批地更新第一個表中的數(shù)據(jù)。與此類似的任務可以通過在set子句中使用多列子查詢而在一個UPDATE命令中完成。當能夠在單一的SQL命令中完成任務,何必要讓數(shù)據(jù)在網(wǎng)上流來流去的?我建議用戶認真學習如何最大限度地發(fā)揮SQL的功能。
    posted @ 2006-01-26 11:32 阿成 閱讀(261) | 評論 (0)編輯 收藏
    在Servlet2.3規(guī)范中,Web應用事件是新增加的部分。它讓你能最大程度地控制你的Web應用。在本文中,我們將學習兩個很重要的應用事件:

    應用的啟動和停止

    Session的創(chuàng)建和失效如它們的名字那樣,應用啟動事件發(fā)生在你的應用第一次被servlet容器裝載和啟動的時候;停止事件發(fā)生在Web應用停止的時候。

    Session創(chuàng)建事件發(fā)生在每次一個新的session創(chuàng)建的時候,類似地Session失效事件發(fā)生在每次一個Session失效的時候。為了使用這些Web應用事件為你做些有用的事情,我們必須創(chuàng)建和使用一些特殊的“監(jiān)聽”類。下面,我們將研究這些監(jiān)聽類到地是什么以及我們?nèi)绾稳ナ褂盟鼈儭?br />
    監(jiān)聽類:

    它們是實現(xiàn)了下邊兩個接口中任何一個接口的簡單的java類:

    javax.servlet.ServletContextListener 
    javax.servlet.http.HttpSessionListener


    如果你想讓你的類監(jiān)聽應用的啟動和停止事件,你就得實現(xiàn)ServletContextListener接口;如果你想讓你的類去監(jiān)聽Session的創(chuàng)建和失效事件,那你就得實現(xiàn)HttpSessionListener接口。 讓我們看看在這些接口中你必須要實現(xiàn)的方法。

    1.ServletContextListener :

    接口包括如下兩個方法:

    public void contextInitialized
    (ServletContextEvent sce); 
    
    public void contextDestroyed
    (ServletContextEvent sce);


    如果你實現(xiàn)了一個接口,那你就必須實現(xiàn)它所有的方法。因此,如果你想利用應用的啟動和停止事件,你就需要創(chuàng)建一個Java類并實現(xiàn)ServletContextListener接口。下邊是這樣的一個類的例子:

    /*File : ApplicationWatch.java*/
    import javax.servlet.ServletContextListener;
    import javax.servlet.ServletContextEvent;
    public class ApplicationWatch implements 
    ServletContextListener 
    {
    public static long
    applicationInitialized = 0L;
    /* 應用啟動事件 */
    public void contextInitialized
    (ServletContextEvent ce)
    {
    applicationInitialized =
    System.currentTimeMillis();
    }
    /*應用停止事件 */
    public void contextDestroyed
    (ServletContextEvent ce) {}
    }


    在上邊的代碼中,ApplicationWatch類實現(xiàn)了ServletContextListener接口。它實現(xiàn)了接口中的兩個方法,但只用了其中的一個方法,另一個方法中沒有寫任何代碼。這個類把應用啟動的時間記錄在一個可以從其它應用類中存取應用啟動時間的public static變量中。

    我將很快解釋如何告訴服務器我們有這個監(jiān)聽類,但首先讓我們看看HttpSessionListener接口有什么不同的方法。

    2.HttpSessionListener :

    這個接口也只包含兩個方法,分別對應于Session的創(chuàng)建和失效:

    public void sessionCreated
    (HttpSessionEvent se); 
    
    public void sessionDestroyed
    (HttpSessionEvent se);


    如上邊的ApplicationWatch例子那樣,我們也創(chuàng)建了一個實現(xiàn)HttpSessionListener接口的類。如下:

    /*File : SessionCounter.java*/
    import javax.servlet.http.HttpSessionListener;
    import javax.servlet.http.HttpSessionEvent;
    public class SessionCounter
    implements HttpSessionListener 
    {
    private static int activeSessions =0;
    /* Session創(chuàng)建事件 */
    public void sessionCreated
    (HttpSessionEvent se)
    {
           activeSessions++;
    }
    /* Session失效事件 */
    public void sessionDestroyed
    (HttpSessionEvent se)
    {
    if(activeSessions>0)activeSessions--;
    }
    
    public static int getActiveSessions()
    {
    return activeSessions;
    }
    }


    在上邊的代碼中,SessionCounter類實現(xiàn)了HttpSessionListener接口,其目的是計算活動會話的數(shù)量。

    好了,我們已經(jīng)學習了什么是Web應用事件,有什么接口可以用以及看到了一些實現(xiàn)這些接口的例子。讓我們看看如何告訴應用服務器我們有這些監(jiān)聽類。

    Web.xml :

    我們通過把類路徑加入/WEB-INF/web.xml文件的標簽中來告訴服務器我們的監(jiān)聽類。下邊是一個web.xml文件的例子:

    <!-- Web.xml -->
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-appPUBLIC "-//Sun Microsystems,
    Inc.//DTD Web Application 2.3
    //EN""http://java.sun.com
    /j2ee/dtds/web-app_2.3.dtd">
    <web-app>
    <!-- Listeners -->
    <listener>
    <listener-class>
    com.stardeveloper.web.listener.SessionCounter
    </listener-class>
    </listener>
    <listener>
    <listener-class>
    com.stardeveloper.web.listener.
    ApplicationWatch</listener-class>
    </listener>
    </web-app>


    如上所示,在web.xml文件中聲明監(jiān)聽類是非常簡單的。現(xiàn)在,每次的服務器的啟動和停止,會話的創(chuàng)建和失效,配置好的監(jiān)聽類的相應的方法就會被調(diào)用。
    posted @ 2006-01-25 10:11 阿成 閱讀(243) | 評論 (0)編輯 收藏
    ?????? 快過年了,這幾天才越來越感覺到,學生時代的生活一去不復返了。
    ??????以前的日子,無論高三還是大學,這個時候早就在家待著了,或許在家看電視,或許賀同學 聚會,
    或許在親戚家住著。。。。
    ??????可是現(xiàn)在,還在公司上班。晚上沒事,來公司上上網(wǎng),過年前的這幾天,學習好像也沒有多大的興趣了,不由自主的懷念起學生時代的生活。和舍友一起出去吃飯,上網(wǎng)吧聯(lián)網(wǎng)打游戲等等,心里有些失落

    ??? 但上班了,也越來越體會到父母的辛苦。
    ??? 他們在一天一天變老,可我在一天一天“長大”嗎?
    ??? 家里的擔子要接過來了,他們該休息休息了。
    posted @ 2006-01-24 21:27 阿成 閱讀(198) | 評論 (0)編輯 收藏
    僅列出標題
    共10頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 
    主站蜘蛛池模板: 亚洲色成人网站WWW永久四虎| 亚洲精品日韩中文字幕久久久| 亚洲AV无码一区二区三区网址| 免费精品无码AV片在线观看| 亚洲AV无码一区二区二三区软件 | 九九精品免费视频| 色播亚洲视频在线观看| 日韩午夜理论免费TV影院| 亚洲欧洲国产日韩精品| 在线日本高清免费不卡| 亚洲国产美女在线观看| 最近最新中文字幕完整版免费高清| 中中文字幕亚洲无线码| 妞干网免费观看视频| 国产精品亚洲专区无码唯爱网| 又黄又爽一线毛片免费观看| 一二三区免费视频| 国产亚洲精品无码成人| 2021国内精品久久久久精免费| 亚洲黄色网址大全| 四虎影视www四虎免费| 狠狠热精品免费观看| 国产亚洲精品国产| 青草草色A免费观看在线| 亚洲av无码日韩av无码网站冲| 亚洲精品亚洲人成在线观看下载| 伊人免费在线观看| 亚洲国产精品成人综合色在线婷婷| 国产美女在线精品免费观看| 无码 免费 国产在线观看91| 亚洲成AV人片在线观看| 国色精品卡一卡2卡3卡4卡免费| 亚洲av午夜电影在线观看 | 免费人成网站永久| 亚洲AV无码专区在线播放中文| 性做久久久久久免费观看| 日本高清免费中文在线看| 亚洲男人天堂av| 国产一级淫片免费播放电影| 久久免费看少妇高潮V片特黄| 亚洲日本VA午夜在线电影|