posts - 120,  comments - 19,  trackbacks - 0
           

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

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

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

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

            1.經常感到疲倦,忘性大;

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

            3.突然覺得有衰老感;

            4.肩部和頸部發木發僵;

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

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

            7.經常頭痛和胸悶;

            8.發生高血壓、糖尿病,心電圖測試結果不正常;

            9.體重突然變化大,出現“將軍肚”;

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

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

            12.經常不吃早飯或吃飯時間不固定;

            13.喜歡吃油炸食品;

            14.一天吸煙30支以上;

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

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

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

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

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

            20.星期天也上班;

            21.經常出差,每周只在家住兩三天;

            22.夜班多,工作時間不規則;

            23.最近有工作調動或工作變化;

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

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

            26.人際關系突然變壞;

            27.最近工作失誤或者發生不和。

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

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

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

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

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

          ??? 哥們, 上面27條在你身上出現幾條癥狀了?? 怕怕吧??

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

          轉自: 電子商務論壇 http://bbs.eczn.com/

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

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

          1.cascade="..."?

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

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

          2.inverse="ture"?

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

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

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

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

          3.cascade和inverse有什么區別?

          可以這樣理解,cascade定義的是關系兩端對象到對象的級聯關系;而inverse定義的是關系和對象的級聯關系。

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

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

          所以,這個異常的只有在Student的關系定義中有cascade="...",而且沒有像上面說的顯示的解除關系時才會出現。所以防止出現這個異常的方法就是:1,在Student端不用cascade;2,或是用cascade的話,就顯示的刪除對像中的關系。 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時就會出現。

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

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

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

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

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

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

          提示:Hibernate采用CGLIB工具來生成持久化類的代理類。CGLIB是一個功能強大的Java字節碼生成工具,它能夠在程序運行時動態生成擴展Java類或者實現Java接口的代理類。關于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不執行任何select語句,僅僅返回Customer類的代理類的實例,它的OID為1,這是由load()方法的第二個參數指定的。當應用程序調用customer.getName()方法時,Hibernate會初始化Customer代理類實例,從數據庫中加載Customer對象的數據,執行以下select語句:

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

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

          1.如果加載的Customer對象在數據庫中不存在,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范圍內,應用程序沒有訪問過Customer對象,那么Customer代理類的實例一直不會被初始化,Hibernate不會執行任何select語句。以下代碼試圖在關閉Session后訪問Customer游離對象:

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

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

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

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

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

          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范圍內通過Hibernate類的initialize()方法顯式初始化了Customer代理類實例,因此當Session關閉后,可以正常訪問Customer游離對象。

          4.當應用程序訪問代理類實例的getId()方法時,不會觸發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值,無需查詢數據庫。由于引用變量customer始終引用的是沒有被初始化的Customer代理類實例,因此當Session關閉后再執行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 阿成 閱讀(329) | 評論 (0)編輯 收藏

          使用FileUpload組件實現文件上傳
          文件上傳在web應用中非常普遍,要在servlet/jsp環境中實現文件上傳功能非常容易,因為網上已經有許多用java開發的組件用于文件上傳,本文以commons-fileupload組件為例,為servlet/jsp應用添加文件上傳功能。

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

          下載后解壓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收到瀏覽器發出的Post請求后,在doPost()方法中實現文件上傳。以下是示例代碼:

          public void doPost(HttpServletRequest request, HttpServletResponse response)
          ????throws IOException, ServletException
          {
          ????try {
          ????????DiskFileUpload fu = new DiskFileUpload();
          ????????// 設置最大文件尺寸,這里是4MB
          ????????fu.setSizeMax(4194304);
          ????????// 設置緩沖區大小,這里是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"));
          ????????????}
          ????????}
          ????????// 跳轉到上傳成功提示頁面
          ????}
          ????catch(Exception e) {
          ????????// 可以跳轉出錯頁面
          ????}
          }

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

          public void init() throws ServletException {
          ????uploadPath = ....
          ????tempPath = ....
          ????// 文件夾不存在就自動創建:
          ????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開發的例子.

           1、如何學習Spring?

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

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

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

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

          AppFuse網站:http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse

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

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

            (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、出現 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開發包,提供兩種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?

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

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

            比如


          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中如何實現事務管理?

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

            事務管理的控制應該放到商業邏輯層。你可以寫個處理商業邏輯的JavaBean,在該JavaBean中調用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就是我們的實現商業邏輯的JavaBean。我們通過parent元素聲明其事務支持。

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

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

            比如:

            DAO層的JavaBean放到applicationContext-hibernate.xml中,商業邏輯層的JavaBean放到applicationContext-service.xml中。然后啟動類中調用以下代碼載入所有的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框架入門的編程問題解決了,我該如何更深地領會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里面, 我們調用了 JAVA API中的 java.lang.System這個類的靜態成員對象 out, out 的靜態方法: public static void println(String string);

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

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

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

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

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

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


          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運行時需要的環境,JDK不僅包含了JRE,還提供了開發調試java程序需要的工具

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

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

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

          另一角度

          如果安裝了JDK,會發同你的電腦有兩套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應用程序需要操作系統幫我們運行,同樣的,我們編寫的Java程序也必須要JRE才能運行。所以當 你裝完JDK后,如果分別在硬盤上的兩個不同地方安裝了兩套JRE,那么你可以想象你的電腦有兩臺虛擬的Java PC機,都具有運行Java程序的功能。所以我們可以說,只要你的電腦安裝了JRE,就可以正確運行Jav a應用程序。

          ???? ?1、為什么Sun要讓JDK安裝兩套相同的JRE?這是因為JDK里面有很多用Java所編寫的開發工具(如javac.exe、jar.exe等),而且都放置在 lib\tools.jar 里。從下面例子可以看出,先將tools.jar改名為tools1.jar,然后運行javac.exe,顯示如下結果: 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 是一樣的,會得到相同的結果。從這里我們可以證明javac.exe只是一個包裝器(Wrapper),而制作的目的是為了讓開發者免于輸入太長的指命。 而且可以發現lib目錄下的程序都很小,不大于2 9K,從這里我們可以得出一個結論。就是JDK里的工具幾乎是用Java所編寫,所以也是Java應用程序,因此要使用JDK所附的工具來開發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的運行結果與你的電腦里面哪個JRE被執行有很大的關系。

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



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

          二、
          java環境變量有三個

          JAVA_HOME,CLASSPATH,PATH.

          只有這三個java環境變量

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

          JAVA_HOME=C:\j2sdk1.4.2_09;

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

          我的設置是:

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

          需要說明,系統中本身就有PATH環境變量,只要把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;這時我的設置。這是類的路徑。前面加上點和分號,意為首先在當前目錄查找,以后你自己編寫類的時候自然明白這點。

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

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

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

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

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

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

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

          這個錯誤產生的原因是沒有設置好環境變量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程序


          三、基礎知識


          問題一:我聲明了什么!

          String s = "Hello world!";

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

          String string = s;

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

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

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

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

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

          return this==o;

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

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

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

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

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

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

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

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

          問題四:final關鍵字到底修飾了什么?

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

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

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

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

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

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

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

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

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

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

          問題六:instanceof是什么東東?

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

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

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

          public class Bill {//省略細節}
          public class PhoneBill extends Bill {//省略細節}
          public class GasBill extends Bill {//省略細節}

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

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

          然而,這種做法通常被認為是沒有好好利用面向對象中的多態性。其實上面的功能要求用方法重載完全可以實現,這是面向對象變成應有的做法,避免回到結構化編程模式。只要提供兩個名字和返回值都相同,接受參數類型不同的方法就可以了:

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

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

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

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

            一、連接各種數據庫方式速查表

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

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

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

            2、DB2數據庫

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

            3、Sql Server7.0/2000數據庫

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

            4、Sybase數據庫

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

            5、Informix數據庫

          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為數據庫名
          Connection conn= DriverManager.getConnection(url);

            6、MySQL數據庫

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

            7、PostgreSQL數據庫

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

            8、access數據庫直連用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、查找驅動程序

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

            2、動態指定classpath

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

            3、加載驅動程序

          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數據庫時可以使用的一些技巧

            1、在客戶端軟件開發中使用Thin驅動程序

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

            2、關閉自動提交功能,提高系統性能

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

            conn.setAutoCommit(false);

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

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

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

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

            4、利用helper函數對動態SQL命令進行格式化

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

            5、利用PreparedStatement對象提高數據庫的總體效率

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

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

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

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

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

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

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

            8、使用SQL92語法調用存儲過程

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

            9、使用Object SQL將對象模式轉移到數據庫中

            既然可以將Oracle的數據庫作為一種面向對象的數據庫來使用,就可以考慮將應用程序中的面向對象模式轉到數據庫中。目前的方法是創建Java bean作為偽裝的數據庫對象,將它們的屬性映射到關系表中,然后在這些bean中添加方法。盡管這樣作在Java中沒有什么問題,但由于操作都是在數據庫之外進行的,因此其他訪問數據庫的應用軟件無法利用對象模式。如果利用Oracle的面向對象的技術,可以通過創建一個新的數據庫對象類型在數據庫中模仿其數據和操作,然后使用JPublisher等工具生成自己的Java bean類。如果使用這種方式,不但Java應用程序可以使用應用軟件的對象模式,其他需要共享你的應用中的數據和操作的應用軟件也可以使用應用軟件中的對象模式。

            10、利用SQL完成數據庫內的操作

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

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

          應用的啟動和停止

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

          Session創建事件發生在每次一個新的session創建的時候,類似地Session失效事件發生在每次一個Session失效的時候。為了使用這些Web應用事件為你做些有用的事情,我們必須創建和使用一些特殊的“監聽”類。下面,我們將研究這些監聽類到地是什么以及我們如何去使用它們。

          監聽類:

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

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


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

          1.ServletContextListener :

          接口包括如下兩個方法:

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


          如果你實現了一個接口,那你就必須實現它所有的方法。因此,如果你想利用應用的啟動和停止事件,你就需要創建一個Java類并實現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類實現了ServletContextListener接口。它實現了接口中的兩個方法,但只用了其中的一個方法,另一個方法中沒有寫任何代碼。這個類把應用啟動的時間記錄在一個可以從其它應用類中存取應用啟動時間的public static變量中。

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

          2.HttpSessionListener :

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

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


          如上邊的ApplicationWatch例子那樣,我們也創建了一個實現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創建事件 */
          public void sessionCreated
          (HttpSessionEvent se)
          {
                 activeSessions++;
          }
          /* Session失效事件 */
          public void sessionDestroyed
          (HttpSessionEvent se)
          {
          if(activeSessions>0)activeSessions--;
          }
          
          public static int getActiveSessions()
          {
          return activeSessions;
          }
          }


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

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

          Web.xml :

          我們通過把類路徑加入/WEB-INF/web.xml文件的標簽中來告訴服務器我們的監聽類。下邊是一個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文件中聲明監聽類是非常簡單的。現在,每次的服務器的啟動和停止,會話的創建和失效,配置好的監聽類的相應的方法就會被調用。
          posted @ 2006-01-25 10:11 阿成 閱讀(244) | 評論 (0)編輯 收藏
          ?????? 快過年了,這幾天才越來越感覺到,學生時代的生活一去不復返了。
          ??????以前的日子,無論高三還是大學,這個時候早就在家待著了,或許在家看電視,或許賀同學 聚會,
          或許在親戚家住著。。。。
          ??????可是現在,還在公司上班。晚上沒事,來公司上上網,過年前的這幾天,學習好像也沒有多大的興趣了,不由自主的懷念起學生時代的生活。和舍友一起出去吃飯,上網吧聯網打游戲等等,心里有些失落

          ??? 但上班了,也越來越體會到父母的辛苦。
          ??? 他們在一天一天變老,可我在一天一天“長大”嗎?
          ??? 家里的擔子要接過來了,他們該休息休息了。
          posted @ 2006-01-24 21:27 阿成 閱讀(198) | 評論 (0)編輯 收藏
          僅列出標題
          共10頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 
          主站蜘蛛池模板: 体育| 桃园县| 前郭尔| 汶川县| 佛山市| 靖安县| 旺苍县| 涿州市| 平原县| 珠海市| 平江县| 龙里县| 延庆县| 惠水县| 镇康县| 昌都县| 仁布县| 德庆县| 迭部县| 奉节县| 醴陵市| 金寨县| 宣化县| 山东| 正安县| 义马市| 肇东市| 奇台县| 酒泉市| 余江县| 马公市| 谷城县| 温泉县| 鄂伦春自治旗| 宁国市| 永兴县| 定边县| 城步| 贵德县| 巍山| 博客|