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

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

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

    隨筆 - 18, 文章 - 0, 評(píng)論 - 8, 引用 - 0
    數(shù)據(jù)加載中……

    2005年7月20日

    CyclicBarrier 簡(jiǎn)單舉例

    一句話解釋:預(yù)備~~~開始

     1 import java.util.concurrent.BrokenBarrierException;
     2 import java.util.concurrent.CyclicBarrier;
     3 
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 
     7 public class CyclicBarrierLearn {
     8     
     9     private Logger log = LoggerFactory.getLogger(CyclicBarrierLearn.class);
    10     
    11     private class Work extends Thread {
    12         
    13         private String name;
    14         private CyclicBarrier cyclicBarrier;
    15         
    16         public Work(String name, CyclicBarrier cyclicBarrier) {
    17             this.name = name;
    18             this.cyclicBarrier = cyclicBarrier;
    19         }
    20         
    21         @Override
    22         public void run() {
    23             try {
    24                 log.debug("thread name: " + name + " waiting work");
    25                 cyclicBarrier.await();
    26                 log.debug("thread name: " + name + " working");
    27             } catch (InterruptedException e) {
    28                 e.printStackTrace();
    29             } catch (BrokenBarrierException e) {
    30                 e.printStackTrace();
    31             }
    32             
    33         }
    34     }
    35     
    36     public void cyclicBarrier() {
    37         CyclicBarrier cyclicBarrier = new CyclicBarrier(50, new Runnable() {
    38             
    39             @Override
    40             public void run() {
    41                 log.debug("let's begin work");
    42             }
    43         });
    44         
    45         for (int i = 0; i < cyclicBarrier.getParties(); i++) {
    46             Work work = new Work(String.valueOf(i), cyclicBarrier);
    47             work.start();
    48         }
    49         
    50     }
    51 
    52     public static void main(String[] args) {
    53         CyclicBarrierLearn cyclicBarrierLearn = new CyclicBarrierLearn();
    54         cyclicBarrierLearn.cyclicBarrier();
    55 
    56     }
    57 
    58 }
    59 

    posted @ 2017-07-13 11:39 丑男 閱讀(175) | 評(píng)論 (0)編輯 收藏

    CountDownLatch 簡(jiǎn)單舉例

    一句話解釋:主線程阻塞,其他線程完成后,主線程被喚醒后繼續(xù)執(zhí)行

     1 import java.util.Random;
     2 import java.util.concurrent.CountDownLatch;
     3 
     4 import org.slf4j.Logger;
     5 import org.slf4j.LoggerFactory;
     6 
     7 public class CountDownLatchLearn {
     8     
     9     private Logger log = LoggerFactory.getLogger(CountDownLatchLearn.class);
    10     private CountDownLatch countDownLatch;
    11     
    12     public CountDownLatchLearn() {
    13         countDownLatch = new CountDownLatch(50);
    14     }
    15     
    16     public void countDown() {
    17         Long count = countDownLatch.getCount();
    18         log.debug("countDownLatch count is:" + count.toString());
    19         
    20         for (int i = 0; i < count; i++) {
    21             Work work = new Work(String.valueOf(i), countDownLatch);
    22             work.start();
    23         }
    24         try {
    25             countDownLatch.await();
    26         } catch (InterruptedException e) {
    27             e.printStackTrace();
    28         }
    29         log.debug("work finish!!!");
    30     }
    31     
    32     private class Work extends Thread {
    33         
    34         private String name;
    35         private CountDownLatch countDownLatch;
    36         
    37         public Work(String name, CountDownLatch countDownLatch) {
    38             this.name = name;
    39             this.countDownLatch = countDownLatch;
    40         }
    41         
    42         @Override
    43         public void run() {
    44             Random r = new Random();
    45             int sleep = r.nextInt(2000);
    46             try {
    47                 log.debug("thread sleep: "+ sleep);
    48                 Thread.sleep(sleep);
    49             } catch (InterruptedException e) {
    50                 e.printStackTrace();
    51             }
    52             log.debug("thread: " + name + ": do work");
    53             countDownLatch.countDown();
    54         }
    55     }
    56 
    57     public static void main(String[] args) {
    58         System.out.println("main start!!!");
    59         
    60         CountDownLatchLearn countDownLatchLearn = new CountDownLatchLearn();
    61         countDownLatchLearn.countDown();
    62         
    63         System.out.println("main end!!!");
    64     }
    65 
    66 }

    posted @ 2017-07-13 11:18 丑男 閱讀(308) | 評(píng)論 (0)編輯 收藏

    mysql 5.7 for windows安裝過程

    環(huán)境說明:

    OSwindows 7 64bit Databasemysql-5.7.18-winx64 Noinstall版本

     

    1. 解壓Mysql安裝目錄

    2. 編寫my.ini配置文件

    3. mysqld --defaults-file=../my.ini --initialize

    4. ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';

    5. mysql –u root –p

    6. 密碼在logs/*.err日志中

     
    my.ini文件內(nèi)容

     1 # my.ini文件內(nèi)容
     2 # For advice on how to change settings please see
     3 # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
     4 # *** DO NOT EDIT THIS FILE. It's a template which will be copied to the
     5 # *** default location during install, and will be replaced if you
     6 # *** upgrade to a newer version of MySQL.
     7 
     8 [mysqld]
     9 
    10 # Remove leading # and set to the amount of RAM for the most important data
    11 # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
    12 # innodb_buffer_pool_size = 128M
    13 
    14 # Remove leading # to turn on a very important data integrity option: logging
    15 # changes to the binary log between backups.
    16 # log_bin
    17 
    18 # These are commonly set, remove the # and set as required.
    19 basedir=D:\\mysql-5.7.18-winx64
    20 datadir=D:\\mysql-5.7.18-winx64\\data
    21 # port = ..
    22 # server_id = ..
    23 
    24 
    25 # Remove leading # to set options mainly useful for reporting servers.
    26 # The server defaults are faster for transactions and fast SELECTs.
    27 # Adjust sizes as needed, experiment to find the optimal values.
    28 # join_buffer_size = 128M
    29 # sort_buffer_size = 2M
    30 # read_rnd_buffer_size = 2M 
    31 
    32 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
    33 
    34 long_query_time=0.1
    35 slow_query_log=on
    36 slow_query_log_file=D:\\mysql-5.7.18-winx64\\logs\\mysqlslow.log
    37 

    posted @ 2017-07-10 00:53 丑男 閱讀(211) | 評(píng)論 (0)編輯 收藏

    添加用戶【備份】

    useradd -g 501 -s /sbin/nologin builder

    posted @ 2013-05-06 17:25 丑男 閱讀(125) | 評(píng)論 (0)編輯 收藏

    [ZT]Java虛擬機(jī)JVM的調(diào)優(yōu)參數(shù)選擇

    在任何一個(gè)的生產(chǎn)系統(tǒng)上線前,系統(tǒng)性能調(diào)優(yōu)(Tuning)都是很重要的一步。通常,應(yīng)用系統(tǒng)的軟硬件的缺省值都是給開發(fā)平臺(tái)(或小規(guī)模系統(tǒng))設(shè)計(jì)的,用來跑生產(chǎn)系統(tǒng)幾乎都無法發(fā)揮出軟硬件的最佳性能。有時(shí),系統(tǒng)調(diào)優(yōu)前后的性能會(huì)差好幾倍。另一方面,由于應(yīng)用程序的開發(fā)人員通常都是針對(duì)功能作開發(fā)的,因此,開發(fā)硬件都是比生產(chǎn)環(huán)境要小的機(jī)器。例如,生產(chǎn)系統(tǒng)是一臺(tái)8個(gè)CPU,64GB內(nèi)存服務(wù)器,而開發(fā)服務(wù)器可能只有1個(gè)CPU和4GB內(nèi)存。所以,在開發(fā)人員中常常不具備做性能方面測(cè)試的軟硬件環(huán)境。另外,有的程序員甚至在開發(fā)時(shí)都沒有考慮到多用戶并發(fā)的環(huán)境,程序中存在單點(diǎn)瓶頸等問題。在做壓力測(cè)試和調(diào)優(yōu)時(shí),往往就會(huì)發(fā)現(xiàn)這些關(guān)鍵點(diǎn)。

      由于應(yīng)用系統(tǒng)是個(gè)軟硬件的完整統(tǒng)一體,系統(tǒng)調(diào)優(yōu)往往需要涉及硬件、網(wǎng)絡(luò)操作系統(tǒng)、中間件,應(yīng)用程序和數(shù)據(jù)庫等方面。在調(diào)優(yōu)的過程中,往往需要發(fā)現(xiàn)存在瓶頸的地方(也就是導(dǎo)致系統(tǒng)變慢的部分),分析原因,從而改進(jìn)和確定較優(yōu)的參數(shù)。

      我們?cè)谧鱆VM的調(diào)優(yōu)前,通常先要了解運(yùn)行的硬件平臺(tái),操作系統(tǒng)和中間件,然后針對(duì)這些情況配置相應(yīng)的系統(tǒng)參數(shù),在測(cè)試中不斷完善參數(shù)。由于性能調(diào)優(yōu)需要對(duì)系統(tǒng)非常了解,并且需要豐富的經(jīng)驗(yàn),因此不是一件容易的事情。這里介紹一些很好的參考資料,就是SPEC.org的網(wǎng)站。這是硬件廠商公布benchmark測(cè)試結(jié)果的地方,通常硬件廠商會(huì)把系統(tǒng)調(diào)到最優(yōu)化才公布結(jié)果的,因此很有借鑒意義。常見和JVM有關(guān)的benchmark值主要有SPECjAppServer2004和SPECjbb2005。前者是J2EE應(yīng)用服務(wù)器的性能指標(biāo),后者是服務(wù)器端Java虛擬機(jī)的性能指標(biāo)。給大家介紹這個(gè)網(wǎng)站的目的是說大家可以參考硬件廠商給出的JVM配置,在根據(jù)自己應(yīng)用環(huán)境的特點(diǎn),較快的得出較好的參數(shù)。例如,這個(gè)網(wǎng)頁給出了SUN公司T5120服務(wù)器+應(yīng)用服務(wù)器9.1 +JDK1.5的SPECjAppServer2004值是8,439.36:

      http://www.spec.org/jAppServer2004/results/res2007q4/jAppServer2004-20071106-00092.html

      我們現(xiàn)在要關(guān)心的不是Benchmark的值(注:實(shí)際上,Sun公司的這個(gè)值是個(gè)很不錯(cuò)的結(jié)果),而是留意在這種環(huán)境下JVM的參數(shù)配置,可以找到一個(gè)欄目“Notes / Tuning Information”:

      JVM Options: -server -XX:+AggressiveHeap

    -Xmx2560m -Xms2560m -Xmn1024m -Xss128k

    -XX:PermSize=256m

    -XX:+DisableExplicitGC

    -XX:ParallelGCThreads=24

    -XX:LargePageSizeInBytes=256m

    -XX:+UseParallelOldGC

    -XX:+AggressiveOpts

    -DAllowManagedFieldsInDefaultFetchGroup=true

    -DAllowMediatedWriteInDefaultFetchGroup=true

    -XX:-UseBiasedLocking

    -Dcom.sun.ejb.containers.readonly.relative.refresh.mode=true

    -Dcom.sun.jts.dblogging.insertquery=insert into

    txn_log_table_0 values (
    ? , ? , ? )

    -Dcom.sun.jts.dblogging.deletequery=delete from

    txn_log_table_0 where localtid
    = ? and servername = ?

    -Dcom.sun.jdo.spi.persistence.support.sqlstore.

    MULTILEVEL_PREFETCH
    =true

      那么上面那些參數(shù)是什么意思呢?上述段落中“-XX”的參數(shù)是SUN JVM的擴(kuò)展選項(xiàng),其中以下的這些都是和垃圾回收(GC)有關(guān):

      -XX:PermSize=256m

    -XX:+DisableExplicitGC

    -XX:ParallelGCThreads=24

    -XX:+UseParallelOldGC

    -XX:+AggressiveHeap

      下面這個(gè)選項(xiàng)是選擇大的內(nèi)存頁面:

      -XX:LargePageSizeInBytes=256m

      "-XX:+AggressiveOpts"是一些試驗(yàn)性優(yōu)化參數(shù),“-XX:-UseBiasedLocking”是非競(jìng)爭(zhēng)性的同步選項(xiàng)。

      而選項(xiàng)“-Xmx2560m -Xms2560m -Xmn1024m -Xss128k”則是初始堆棧的內(nèi)存值,注意-Xmx和-Xms的值是一樣的,這樣系統(tǒng)性能會(huì)較平穩(wěn)些。

      至于這些參數(shù)詳細(xì)代表什么意義,大家可以google一下就很容易了解。這是Sun網(wǎng)站上的說明,有興趣的可以讀一下: http://java.sun.com/performance/reference/whitepapers/tuning.html

      如果你的應(yīng)用系統(tǒng)是JDK1.5,硬件是T5120,操作系統(tǒng)是Solaris,那么這些參數(shù)就很有借鑒意義。如果你的硬件系統(tǒng)不是T5120,但是使用SUN的JDK1.5 ,這些參數(shù)也是有一定參考作用。當(dāng)然,最理想的是選擇一個(gè)和自己的環(huán)境最近似的結(jié)果來參考。大多數(shù)軟硬件的測(cè)試結(jié)果都可以在SPEC.org上找到,如果你的系統(tǒng)是J2EE的3層架構(gòu),可以用jAppServer2004指標(biāo),如果是純JAVA的應(yīng)用,可用jbb2005的結(jié)果:

      http://www.spec.org/jAppServer2004/

      http://www.spec.org/jbb2005/

      需要注意的是,這些調(diào)優(yōu)參數(shù)只是提供了一個(gè)思路,具體是否合適你的應(yīng)用還要看實(shí)測(cè)結(jié)果。

    posted @ 2009-04-29 19:24 丑男 閱讀(271) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)帖]Hibernate常用保存

    hibernate對(duì)于對(duì)象的保存提供了太多的方法,他們之間有很多不同,這里細(xì)說一下,以便區(qū)別:
    一、預(yù)備知識(shí):
    在所有之前,說明一下,對(duì)于hibernate,它的對(duì)象有三種狀態(tài),transient、persistent、detached
    下邊是常見的翻譯辦法:
    transient:瞬態(tài)或者自由態(tài)
    persistent:持久化狀態(tài)
    detached:脫管狀態(tài)或者游離態(tài)
    脫管狀態(tài)的實(shí)例可以通過調(diào)用save()、persist()或者saveOrUpdate()方法進(jìn)行持久化。
    持久化實(shí)例可以通過調(diào)用 delete()變成脫管狀態(tài)。通過get()或load()方法得到的實(shí)例都是持久化狀態(tài)的。
    脫管狀態(tài)的實(shí)例可以通過調(diào)用 update()、0saveOrUpdate()、lock()或者replicate()進(jìn)行持久化。
    save() 和persist()將會(huì)引發(fā)SQL的INSERT,delete()會(huì)引發(fā)SQLDELETE,而update()或merge()會(huì)引發(fā) SQLUPDATE.對(duì)持久化(persistent)實(shí)例的修改在刷新提交的時(shí)候會(huì)被檢測(cè)到,它也會(huì)引起 SQLUPDATE.saveOrUpdate()或者replicate()會(huì)引發(fā)SQLINSERT或者UPDATE
    二、save 和update區(qū)別
    把這一對(duì)放在第一位的原因是因?yàn)檫@一對(duì)是最常用的。
    save的作用是把一個(gè)新的對(duì)象保存
    update是把一個(gè)脫管狀態(tài)的對(duì)象保存
    三、update 和saveOrUpdate區(qū)別
    這個(gè)是比較好理解的,顧名思義,saveOrUpdate基本上就是合成了save和update引用hibernate reference中的一段話來解釋他們的使用場(chǎng)合和區(qū)別。
    通常下面的場(chǎng)景會(huì)使用update()或saveOrUpdate():
    程序在第一個(gè)session中加載對(duì)象
    該對(duì)象被傳遞到表現(xiàn)層
    對(duì)象發(fā)生了一些改動(dòng)
    該對(duì)象被返回到業(yè)務(wù)邏輯層
    程序調(diào)用第二個(gè)session的update()方法持久這些改動(dòng)
    saveOrUpdate()做下面的事:
    如果對(duì)象已經(jīng)在本session中持久化了,不做任何事
    如果另一個(gè)與本session關(guān)聯(lián)的對(duì)象擁有相同的持久化標(biāo)識(shí)(identifier),拋出一個(gè)異常
    如果對(duì)象沒有持久化標(biāo)識(shí)(identifier)屬性,對(duì)其調(diào)用save()
    如果對(duì)象的持久標(biāo)識(shí)(identifier)表明其是一個(gè)新實(shí)例化的對(duì)象,對(duì)其調(diào)用save()
    如果對(duì)象是附帶版本信息的(通過或) 并且版本屬性的值表明其是一個(gè)新實(shí)例化的對(duì)象,save()它。
    四、persist和save區(qū)別
    這個(gè)是最迷離的一對(duì),表面上看起來使用哪個(gè)都行,在hibernate reference文檔中也沒有明確的區(qū)分他們。
    這里給出一個(gè)明確的區(qū)分。(可以跟進(jìn)src看一下,雖然實(shí)現(xiàn)步驟類似,但是還是有細(xì)微的差別)
    1.persist把一個(gè)瞬態(tài)的實(shí)例持久化,但是并"不保證"標(biāo)識(shí)符被立刻填入到持久化實(shí)例中,標(biāo)識(shí)符的填入可能被推遲到flush的時(shí)間。
    2.persist" 保證",當(dāng)它在一個(gè)transaction外部被調(diào)用的時(shí)候并不觸發(fā)一個(gè)Sql Insert,這個(gè)功能是很有用的,當(dāng)我們通過繼承Session/persistence context來封裝一個(gè)長會(huì)話流程的時(shí)候,一個(gè)persist這樣的函數(shù)是需要的。
    3.save"不保證"第2條,它要返回標(biāo)識(shí)符,所以它會(huì)立即執(zhí)行Sql insert,不管是不是在transaction內(nèi)部。
    五、saveOrUpdateCopy,merge和update區(qū)別
    首先說明merge是用來代替saveOrUpdateCopy的,然后比較update和merge,update的作用上邊說了,這里說一下merge的作用。
    如果session中存在相同持久化標(biāo)識(shí)(identifier)的實(shí)例,用用戶給出的對(duì)象的狀態(tài)覆蓋舊有的持久實(shí)例
    如果session沒有相應(yīng)的持久實(shí)例,則嘗試從數(shù)據(jù)庫中加載,或創(chuàng)建新的持久化實(shí)例,最后返回該持久實(shí)例
    用戶給出的這個(gè)對(duì)象沒有被關(guān)聯(lián)到session上,它依舊是脫管的
    重點(diǎn)是最后一句:
    當(dāng)我們使用update的時(shí)候,執(zhí)行完成后,我們提供的對(duì)象A的狀態(tài)變成持久化狀態(tài)
    但當(dāng)我們使用merge的時(shí)候,執(zhí)行完成,我們提供的對(duì)象A還是脫管狀態(tài),hibernate或者new了一個(gè)B,或者檢索到一個(gè)持久對(duì)象,并把我們提供的對(duì)象A的所有的值拷貝到這個(gè)B,執(zhí)行完成后B是持久狀態(tài),而我們提供的A還是托管狀態(tài)。
    六、flush和update區(qū)別
    這兩個(gè)的區(qū)別好理解
    update操作的是在脫管狀態(tài)的對(duì)象,而flush是操作的在持久狀態(tài)的對(duì)象。
    默認(rèn)情況下,一個(gè)持久狀態(tài)的對(duì)象是不需要update的,只要你更改了對(duì)象的值,等待hibernate flush就自動(dòng)保存到數(shù)據(jù)庫了。hibernate flush發(fā)生再幾種情況下:
    1.調(diào)用某些查詢的時(shí)候
    2.transaction commit的時(shí)候
    3.手動(dòng)調(diào)用flush的時(shí)候
    七、lock和update區(qū)別
    update是把一個(gè)已經(jīng)更改過的脫管狀態(tài)的對(duì)象變成持久狀態(tài)
    lock是把一個(gè)沒有更改過的脫管狀態(tài)的對(duì)象變成持久狀態(tài)
    對(duì)應(yīng)更改一個(gè)記錄的內(nèi)容,兩個(gè)的操作不同:
    update的操作步驟是:
    更改脫管的對(duì)象->調(diào)用update
    lock的操作步驟是:
    調(diào)用lock把對(duì)象從脫管狀態(tài)變成持久狀態(tài)——>更改持久狀態(tài)的對(duì)象的內(nèi)容——>等待flush或者手動(dòng)flush

    posted @ 2008-08-23 21:22 丑男 閱讀(243) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)帖]Oracle執(zhí)行計(jì)劃解釋

    一.相關(guān)的概念

        Rowid的概念:rowid是一個(gè)偽列,既然是偽列,那么這個(gè)列就不是用戶定義,而是系統(tǒng)自己給加上的。 對(duì)每個(gè)表都有一個(gè)rowid的偽列,但是表中并不物理存儲(chǔ)ROWID列的值。不過你可以像使用其它列那樣使用它,但是不能刪除改列,也不能對(duì)該列的值進(jìn)行 修改、插入。一旦一行數(shù)據(jù)插入數(shù)據(jù)庫,則rowid在該行的生命周期內(nèi)是唯一的,即即使該行產(chǎn)生行遷移,行的rowid也不會(huì)改變。

        Recursive SQL概念:有時(shí)為了執(zhí)行用戶發(fā)出的一個(gè)sql語句,oracle必須執(zhí)行一些額外的語句,我們將這些額外的語句稱之為''recursive calls''或''recursive sql statements''.如當(dāng)一個(gè)DDL語句發(fā)出后,ORACLE總是隱含的發(fā)出一些recursive SQL語句,來修改數(shù)據(jù)字典信息,以便用戶可以成功的執(zhí)行該DDL語句。當(dāng)需要的數(shù)據(jù)字典信息沒有在共享內(nèi)存中時(shí),經(jīng)常會(huì)發(fā)生Recursive calls,這些Recursive calls會(huì)將數(shù)據(jù)字典信息從硬盤讀入內(nèi)存中。用戶不比關(guān)心這些recursive SQL語句的執(zhí)行情況,在需要的時(shí)候,ORACLE會(huì)自動(dòng)的在內(nèi)部執(zhí)行這些語句。當(dāng)然DML語句與SELECT都可能引起recursive sql.簡(jiǎn)單的說,我們可以將觸發(fā)器視為recursive sql.

        Row Source(行源):用在查詢中,由上一操作返回的符合條件的行的集合,即可以是表的全部行數(shù)據(jù)的集合;也可以是表的部分行數(shù)據(jù)的集合;也可以為對(duì)上2個(gè)row source進(jìn)行連接操作(如join連接)后得到的行數(shù)據(jù)集合。

        Predicate(謂詞):一個(gè)查詢中的WHERE限制條件

        Driving table(驅(qū)動(dòng)表):該表又稱為外層表(OUTER table)。 這個(gè)概念用于嵌套與HASH連接中。如果該row source返回較多的行數(shù)據(jù),則對(duì)所有的后續(xù)操作有負(fù)面影響。注意此處雖然翻譯為驅(qū)動(dòng)表,但實(shí)際上翻譯為驅(qū)動(dòng)行源(driving row source)更為確切。一般說來,是應(yīng)用查詢的限制條件后,返回較少行源的表作為驅(qū)動(dòng)表,所以如果一個(gè)大表在WHERE條件有有限制條件(如等值限 制),則該大表作為驅(qū)動(dòng)表也是合適的,所以并不是只有較小的表可以作為驅(qū)動(dòng)表,正確說法應(yīng)該為應(yīng)用查詢的限制條件后,返回較少行源的表作為驅(qū)動(dòng)表。在執(zhí)行 計(jì)劃中,應(yīng)該為靠上的那個(gè)row source,后面會(huì)給出具體說明。在我們后面的描述中,一般將該表稱為連接操作的row source 1.

        Probed table(被探查表):該表又稱為內(nèi)層表(INNER table)。在我們從驅(qū)動(dòng)表中得到具體一行的數(shù)據(jù)后,在該表中尋找符合連接條件的行。所以該表應(yīng)當(dāng)為大表(實(shí)際上應(yīng)該為返回較大row source的表)且相應(yīng)的列上應(yīng)該有索引。在我們后面的描述中,一般將該表稱為連接操作的row source 2.

        組合索引(concatenated index):由多個(gè)列構(gòu)成的索引,如create index idx_emp on emp(col1, col2, col3, ……),則我們稱idx_emp索引為組合索引。在組合索引中有一個(gè)重要的概念:引導(dǎo)列(leading column),在上面的例子中,col1列為引導(dǎo)列。當(dāng)我們進(jìn)行查詢時(shí)可以使用“where col1 = ? ”,也可以使用“where col1 = ? and col2 = ?”,這樣的限制條件都會(huì)使用索引,但是“where col2 = ? ”查詢就不會(huì)使用該索引。所以限制條件中包含先導(dǎo)列時(shí),該限制條件才會(huì)使用該組合索引。

        可選擇性(selectivity):比較一下列中唯一鍵的數(shù)量和表中的行數(shù),就可以判斷該列的可選擇性。 如果該列的“唯一鍵的數(shù)量/表中的行數(shù)”的比值越接近1,則該列的可選擇性越高,該列就越適合創(chuàng)建索引,同樣索引的可選擇性也越高。在可選擇性高的列上進(jìn) 行查詢時(shí),返回的數(shù)據(jù)就較少,比較適合使用索引查詢。

    歡迎進(jìn)入Oracle社區(qū)論壇,與200萬技術(shù)人員互動(dòng)交流 >>進(jìn)入
    二.oracle訪問數(shù)據(jù)的存取方法

        1) 全表掃描(Full table Scans, FTS)

        為實(shí)現(xiàn)全表掃描,oracle讀 取表中所有的行,并檢查每一行是否滿足語句的WHERE限制條件一個(gè)多塊讀 操作可以使一次I/O能讀取多塊數(shù)據(jù)塊(db_block_multiblock_read_count參數(shù)設(shè)定),而不是只讀取一個(gè)數(shù)據(jù)塊,這極大的減 少了I/O總次數(shù),提高了系統(tǒng)的吞吐量,所以利用多塊讀的方法可以十分高效地實(shí)現(xiàn)全表掃描,而且只有在全表掃描的情況下才能使用多塊讀操作。在這種訪問模 式下,每個(gè)數(shù)據(jù)塊只被讀一次。

        使用FTS的前提條件:在較大的表上不建議使用全表掃描,除非取出數(shù)據(jù)的比較多,超過總量的5% —— 10%,或你想使用并行查詢功能時(shí)。

        使用全表掃描的例子:

        ~~~~~~~~~~~~~~~~~~~~~~~~ sql> explain plan for select * from dual;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=

        table ACCESS FULL DUAL

        2) 通過ROWID的表存取(Table Access by ROWID或rowid lookup)

        行的ROWID指出了該行所在的數(shù)據(jù)文件、數(shù)據(jù)塊以及行在該塊中的位置,所以通過ROWID來存取數(shù)據(jù)可以快速定位到目標(biāo)數(shù)據(jù)上,是Oracle存取單行數(shù)據(jù)的最快方法。

        這種存取方法不會(huì)用到多塊讀操作,一次I/O只能讀取一個(gè)數(shù)據(jù)塊。我們會(huì)經(jīng)常在執(zhí)行計(jì)劃中看到該存取方法,如通過索引查詢數(shù)據(jù)。

        使用ROWID存取的方法: sql> explain plan for select * from dept where rowid = ''AAAAyGAADAAAAATAAF'';

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=1

        table ACCESS BY ROWID DEPT [ANALYZED]


        3)索引掃描(Index Scan或index lookup)

        我們先通過index查找到數(shù)據(jù)對(duì)應(yīng)的rowid值(對(duì)于非唯一索引可能返回多個(gè)rowid值),然后根據(jù)rowid直接從表中得到具體的數(shù)據(jù),這 種查找方式稱為索引掃描或索引查找(index lookup)。一個(gè)rowid唯一的表示一行數(shù)據(jù),該行對(duì)應(yīng)的數(shù)據(jù)塊是通過一次i/o得到的,在此情況下該次i/o只會(huì)讀取一個(gè)數(shù)據(jù)庫塊。

        在索引中,除了存儲(chǔ)每個(gè)索引的值外,索引還存儲(chǔ)具有此值 的行對(duì)應(yīng)的ROWID值。索引掃描可以由2步組成:(1) 掃描索引得到對(duì)應(yīng)的rowid值。 (2) 通過找到的rowid從表中讀出具體的數(shù)據(jù)。每步都是單獨(dú)的一次I/O,但是對(duì)于索引,由于經(jīng)常使用,絕大多數(shù)都已經(jīng)CACHE到內(nèi)存中,所以第1步的 I/O經(jīng)常是邏輯I/O,即數(shù)據(jù)可以從內(nèi)存中得到。但是對(duì)于第2步來說,如果表比較大,則其數(shù)據(jù)不可能全在內(nèi)存中,所以其I/O很有可能是物理I/O,這 是一個(gè)機(jī)械操作,相對(duì)邏輯I/O來說,是極其費(fèi)時(shí)間的。所以如果多大表進(jìn)行索引掃描,取出的數(shù)據(jù)如果大于總量的5% —— 10%,使用索引掃描會(huì)效率下降很多。如下列所示:SQL> explain plan for select empno, ename from emp where empno=10;

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=1

        table ACCESS BY ROWID EMP [ANALYZED]

        INDEX UNIQUE SCAN EMP_I1


        但是如果查詢的數(shù)據(jù)能全在索引中找到,就可以避免進(jìn)行第2步操作,避免了不必要的I/O,此時(shí)即使通過索引掃描取出的數(shù)據(jù)比較多,效率還是很高的

        sql> explain plan for select empno from emp where empno=10;-- 只查詢empno列值

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=1

        INDEX UNIQUE SCAN EMP_I1

        進(jìn)一步講,如果sql語句中對(duì)索引列進(jìn)行排序,因?yàn)樗饕呀?jīng)預(yù)先排序好了,所以在執(zhí)行計(jì)劃中不需要再對(duì)索引列進(jìn)行排序
        sql> explain plan for select empno, ename from emp

        where empno > 7876 order by empno;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=1

        table ACCESS BY ROWID EMP [ANALYZED]

        INDEX RANGE SCAN EMP_I1 [ANALYZED]


        從這個(gè)例子中可以看到:因?yàn)樗饕且呀?jīng)排序了的,所以將按照索引的順序查詢出符合條件的行,因此避免了進(jìn)一步排序操作。

    根據(jù)索引的類型與where限制條件的不同,有4種類型的索引掃描:

        索引唯一掃描(index unique scan)

        索引范圍掃描(index range scan)

        索引全掃描(index full scan)

        索引快速掃描(index fast full scan)

        (1) 索引唯一掃描(index unique scan)

        通過唯一索引查找一個(gè)數(shù)值經(jīng)常返回單個(gè)ROWID.如果存在UNIQUE 或PRIMARY KEY 約束(它保證了語句只存取單行)的話,Oracle經(jīng)常實(shí)現(xiàn)唯一性掃描。

        使用唯一性約束的例子:

        sql> explain plan for

        select empno,ename from emp where empno=10;

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=1

        table ACCESS BY ROWID EMP [ANALYZED]

        INDEX UNIQUE SCAN EMP_I1

        (2) 索引范圍掃描(index range scan)

        使用一個(gè)索引存取多行數(shù)據(jù),在唯一索引上使用索引范圍掃描的典型情況下是在謂詞(where限制條件)中使用了范圍操作符(如>、<、<>、>=、<=、between)

        使用索引范圍掃描的例子:

        sql> explain plan for select empno,ename from emp

        where empno > 7876 order by empno;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=1

        table ACCESS BY ROWID EMP [ANALYZED]

        INDEX RANGE SCAN EMP_I1 [ANALYZED]

        在非唯一索引上,謂詞col = 5可能返回多行數(shù)據(jù),所以在非唯一索引上都使用索引范圍掃描。

        使用index rang scan的3種情況:

        (a) 在唯一索引列上使用了range操作符(> < <> >= <= between)

        (b) 在組合索引上,只使用部分列進(jìn)行查詢,導(dǎo)致查詢出多行

        (c) 對(duì)非唯一索引列上進(jìn)行的任何查詢。

        (3) 索引全掃描(index full scan)

        與全表掃描對(duì)應(yīng),也有相應(yīng)的全索引掃描。而且此時(shí)查詢出的數(shù)據(jù)都必須從索引中可以直接得到。

        全索引掃描的例子:

        An Index full scan will not perform single block i/o''s and so it may prove to be inefficient.

        e.g.

        Index BE_IX is a concatenated index on big_emp (empno, ename)

        sql> explain plan for select empno, ename from big_emp order by empno,ename;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=26

        INDEX FULL SCAN BE_IX [ANALYZED]

        (4) 索引快速掃描(index fast full scan)

        掃描索引中的所有的數(shù)據(jù)塊,與 index full scan很類似,但是一個(gè)顯著的區(qū)別就是它不對(duì)查詢出的數(shù)據(jù)進(jìn)行排序,即數(shù)據(jù)不是以排序順序被返回。在這種存取方法中,可以使用多塊讀功能,也可以使用并行讀入,以便獲得最大吞吐量與縮短執(zhí)行時(shí)間。

        索引快速掃描的例子:

        BE_IX索引是一個(gè)多列索引: big_emp (empno,ename)

        sql> explain plan for select empno,ename from big_emp;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=1

        INDEX FAST FULL SCAN BE_IX [ANALYZED]

        只選擇多列索引的第2列:

        sql> explain plan for select ename from big_emp;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=1

        INDEX FAST FULL SCAN BE_IX [ANALYZED]

       三、表之間的連接

        Join是一種試圖將兩個(gè)表結(jié)合在一起的謂詞,一次只能連接2個(gè)表,表連接也可以被稱為表關(guān)聯(lián)。在后面的敘 述中,我們將會(huì)使用“row source”來代替“表”,因?yàn)槭褂胷ow source更嚴(yán)謹(jǐn)一些,并且將參與連接的2個(gè)row source分別稱為row source1和row source 2.Join過程的各個(gè)步驟經(jīng)常是串行操作,即使相關(guān)的row source可以被并行訪問,即可以并行的讀取做join連接的兩個(gè)row source的數(shù)據(jù),但是在將表中符合限制條件的數(shù)據(jù)讀入到內(nèi)存形成row source后,join的其它步驟一般是串行的。有多種方法可以將2個(gè)表連接起來,當(dāng)然每種方法都有自己的優(yōu)缺點(diǎn),每種連接類型只有在特定的條件下才會(huì) 發(fā)揮出其最大優(yōu)勢(shì)。

        row source(表)之間的連接順序?qū)τ诓樵兊男视蟹浅4蟮挠绊憽Mㄟ^首先存取特定的表,即將該表作為驅(qū)動(dòng)表,這樣可以先應(yīng)用某些限制條件,從而得到一個(gè) 較小的row source,使連接的效率較高,這也就是我們常說的要先執(zhí)行限制條件的原因。一般是在將表讀入內(nèi)存時(shí),應(yīng)用where子句中對(duì)該表的限制條件。

        根據(jù)2個(gè)row source的連接條件的中操作符的不同,可以將連接分為等值連接(如WHERE A.COL3 = B.COL4)、非等值連接(WHERE A.COL3 > B.COL4)、外連接(WHERE A.COL3 = B.COL4(+))。上面的各個(gè)連接的連接原理都基本一樣,所以為了簡(jiǎn)單期間,下面以等值連接為例進(jìn)行介紹。

        在后面的介紹中,都已:

        SELECT A.COL1, B.COL2

        FROM A, B

        WHERE A.COL3 = B.COL4;

        為例進(jìn)行說明,假設(shè)A表為Row Soruce1,則其對(duì)應(yīng)的連接操作關(guān)聯(lián)列為COL 3;B表為Row Soruce2,則其對(duì)應(yīng)的連接操作關(guān)聯(lián)列為COL 4;

        連接類型:

        目前為止,無論連接操作符如何,典型的連接類型共有3種:

        排序 - - 合并連接(Sort Merge Join (SMJ) )

        嵌套循環(huán)(Nested Loops (NL) )

        哈希連接(Hash Join)

        排序 - - 合并連接(Sort Merge Join, SMJ)

        內(nèi)部連接過程:

        1) 首先生成row source1需要的數(shù)據(jù),然后對(duì)這些數(shù)據(jù)按照連接操作關(guān)聯(lián)列(如A.col3)進(jìn)行排序。

        2) 隨后生成row source2需要的數(shù)據(jù),然后對(duì)這些數(shù)據(jù)按照與sort source1對(duì)應(yīng)的連接操作關(guān)聯(lián)列(如B.col4)進(jìn)行排序。

        3) 最后兩邊已排序的行被放在一起執(zhí)行合并操作,即將2個(gè)row source按照連接條件連接起來

        下面是連接步驟的圖形表示:

        MERGE

        /"

        SORTSORT

        ||

        Row Source 1Row Source 2

        如果row source已經(jīng)在連接關(guān)聯(lián)列上被排序,則該連接操作就不需要再進(jìn)行sort操作,這樣可以大大提高這種連接操作的連接速度,因?yàn)榕判蚴莻€(gè)極其費(fèi)資源的操 作,特別是對(duì)于較大的表。預(yù)先排序的row source包括已經(jīng)被索引的列(如a.col3或b.col4上有索引)或row source已經(jīng)在前面的步驟中被排序了。盡管合并兩個(gè)row source的過程是串行的,但是可以并行訪問這兩個(gè)row source(如并行讀入數(shù)據(jù),并行排序)。

        SMJ連接的例子:SQL> explain plan for

        select /*+ ordered */ e.deptno, d.deptno

        from emp e, dept d

        where e.deptno = d.deptno

        order by e.deptno, d.deptno;

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=17

        MERGE JOIN

        SORT JOIN

        table ACCESS FULL EMP [ANALYZED]

        SORT JOIN

        table ACCESS FULL DEPT [ANALYZED]


        排序是一個(gè)費(fèi)時(shí)、費(fèi)資源的操作,特別對(duì)于大表。基于這個(gè)原因,SMJ經(jīng)常不是一個(gè)特別有效的連接方法,但是如果2個(gè)row source都已經(jīng)預(yù)先排序,則這種連接方法的效率也是蠻高的。

        嵌套循環(huán)(Nested Loops, NL)

        這個(gè)連接方法有驅(qū)動(dòng)表(外部表)的概念。其實(shí),該連接過程就是一個(gè)2層嵌套循環(huán),所以外層循環(huán)的次數(shù)越少越好,這也就是我們?yōu)槭裁磳⑿”砘蚍祷剌^小 row source的表作為驅(qū)動(dòng)表(用于外層循環(huán))的理論依據(jù)。但是這個(gè)理論只是一般指導(dǎo)原則,因?yàn)樽裱@個(gè)理論并不能總保證使語句產(chǎn)生的I/O次數(shù)最少。有時(shí) 不遵守這個(gè)理論依據(jù),反而會(huì)獲得更好的效率。如果使用這種方法,決定使用哪個(gè)表作為驅(qū)動(dòng)表很重要。有時(shí)如果驅(qū)動(dòng)表選擇不正確,將會(huì)導(dǎo)致語句的性能很差、很 差。

        內(nèi)部連接過程:

        Row source1的Row 1 —— Probe ->Row source 2

        Row source1的Row 2 —— Probe ->Row source 2

        Row source1的Row 3 —— Probe ->Row source 2

        ……。

        Row source1的Row n —— Probe ->Row source 2

        從內(nèi)部連接過程來看,需要用row source1中的每一行,去匹配row source2中的所有行,所以此時(shí)保持row source1盡可能的小與高效的訪問row source2(一般通過索引實(shí)現(xiàn))是影響這個(gè)連接效率的關(guān)鍵問題。這只是理論指導(dǎo)原則,目的是使整個(gè)連接操作產(chǎn)生最少的物理I/O次數(shù),而且如果遵守這 個(gè)原則,一般也會(huì)使總的物理I/O數(shù)最少。但是如果不遵從這個(gè)指導(dǎo)原則,反而能用更少的物理I/O實(shí)現(xiàn)連接操作,那盡管違反指導(dǎo)原則吧!因?yàn)樽钌俚奈锢? I/O次數(shù)才是我們應(yīng)該遵從的真正的指導(dǎo)原則,在后面的具體案例分析中就給出這樣的例子。

        在上面的連接過程中,我們稱Row source1為驅(qū)動(dòng)表或外部表。Row Source2被稱為被探查表或內(nèi)部表。

        在NESTED LOOPS連接中,Oracle讀取row source1中的每一行,然后在row sourc2中檢查是否有匹配的行,所有被匹配的行都被放到結(jié)果集中,然后處理row source1中的下一行。這個(gè)過程一直繼續(xù),直到row source1中的所有行都被處理。這是從連接操作中可以得到第一個(gè)匹配行的最快的方法之一,這種類型的連接可以用在需要快速響應(yīng)的語句中,以響應(yīng)速度為 主要目標(biāo)。

        如果driving row source(外部表)比較小,并且在inner row source(內(nèi)部表)上有唯一索引,或有高選擇性非唯一索引時(shí),使用這種方法可以得到較好的效率。NESTED LOOPS有其它連接方法沒有的的一個(gè)優(yōu)點(diǎn)是:可以先返回已經(jīng)連接的行,而不必等待所有的連接操作處理完才返回?cái)?shù)據(jù),這可以實(shí)現(xiàn)快速的響應(yīng)時(shí)間。

        如果不使用并行操作,最好的驅(qū)動(dòng)表是那些應(yīng)用了where 限制條件后,可以返回較少行數(shù)據(jù)的的表,所以大表也可能稱為驅(qū)動(dòng)表,關(guān)鍵看限制條件。對(duì)于并行查詢,我們經(jīng)常選擇大表作為驅(qū)動(dòng)表,因?yàn)榇蟊砜梢猿浞掷貌? 行功能。當(dāng)然,有時(shí)對(duì)查詢使用并行操作并不一定會(huì)比查詢不使用并行操作效率高,因?yàn)樽詈罂赡苊總€(gè)表只有很少的行符合限制條件,而且還要看你的硬件配置是否 可以支持并行(如是否有多個(gè)CPU,多個(gè)硬盤控制器),所以要具體問題具體對(duì)待。

        NL連接的例子:

        sql> explain plan for

        select a.dname,b.sql

        from dept a,emp b

        where a.deptno = b.deptno;

        Query Plan

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

        SELECT STATEMENT [CHOOSE] Cost=5

        NESTED LOOPS

        table ACCESS FULL DEPT [ANALYZED]

        table ACCESS FULL EMP [ANALYZED]


        哈希連接(Hash Join, HJ)

        這種連接是在oracle 7.3以后引入的,從理論上來說比NL與SMJ更高效,而且只用在CBO優(yōu)化器中。

        較小的row source被用來構(gòu)建hash table與bitmap,第2個(gè)row source被用來被hansed,并與第一個(gè)row source生成的hash table進(jìn)行匹配,以便進(jìn)行進(jìn)一步的連接。Bitmap被用來作為一種比較快的查找方法,來檢查在hash table中是否有匹配的行。特別的,當(dāng)hash table比較大而不能全部容納在內(nèi)存中時(shí),這種查找方法更為有用。這種連接方法也有NL連接中所謂的驅(qū)動(dòng)表的概念,被構(gòu)建為hash table與bitmap的表為驅(qū)動(dòng)表,當(dāng)被構(gòu)建的hash table與bitmap能被容納在內(nèi)存中時(shí),這種連接方式的效率極高。

        HASH連接的例子:

        sql> explain plan for

        select /*+ use_hash(emp) */ empno

        from emp, dept

        where emp.deptno = dept.deptno;

        Query Plan

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

        SELECT STATEMENT[CHOOSE] Cost=3

        HASH JOIN

        table ACCESS FULL DEPT

        table ACCESS FULL EMP


        要使哈希連接有效,需要設(shè)置HASH_JOIN_ENABLED=TRUE,缺省情況下該參數(shù)為TRUE,另外,不要忘了還要設(shè)置 hash_area_size參數(shù),以使哈希連接高效運(yùn)行,因?yàn)楣_B接會(huì)在該參數(shù)指定大小的內(nèi)存中運(yùn)行,過小的參數(shù)會(huì)使哈希連接的性能比其他連接方式還 要低。

        總結(jié)一下,在哪種情況下用哪種連接方法比較好:

        排序 - - 合并連接(Sort Merge Join, SMJ):

        a) 對(duì)于非等值連接,這種連接方式的效率是比較高的。

        b) 如果在關(guān)聯(lián)的列上都有索引,效果更好。

        c) 對(duì)于將2個(gè)較大的row source做連接,該連接方法比NL連接要好一些。

        d) 但是如果sort merge返回的row source過大,則又會(huì)導(dǎo)致使用過多的rowid在表中查詢數(shù)據(jù)時(shí),數(shù)據(jù)庫性能下降,因?yàn)檫^多的I/O.

        嵌套循環(huán)(Nested Loops, NL):

        a) 如果driving row source(外部表)比較小,并且在inner row source(內(nèi)部表)上有唯一索引,或有高選擇性非唯一索引時(shí),使用這種方法可以得到較好的效率。

        b) NESTED LOOPS有其它連接方法沒有的的一個(gè)優(yōu)點(diǎn)是:可以先返回已經(jīng)連接的行,而不必等待所有的連接操作處理完才返回?cái)?shù)據(jù),這可以實(shí)現(xiàn)快速的響應(yīng)時(shí)間。

        哈希連接(Hash Join, HJ):

        a) 這種方法是在oracle7后來引入的,使用了比較先進(jìn)的連接理論,一般來說,其效率應(yīng)該好于其它2種連接,但是這種連接只能用在CBO優(yōu)化器中,而且需要設(shè)置合適的hash_area_size參數(shù),才能取得較好的性能。

        b) 在2個(gè)較大的row source之間連接時(shí)會(huì)取得相對(duì)較好的效率,在一個(gè)row source較小時(shí)則能取得更好的效率。

        c) 只能用于等值連接中

        笛卡兒乘積(Cartesian Product)

        當(dāng)兩個(gè)row source做連接,但是它們之間沒有關(guān)聯(lián)條件時(shí),就會(huì)在兩個(gè)row source中做笛卡兒乘積,這通常由編寫代碼疏漏造成(即程序員忘了寫關(guān)聯(lián)條件)。笛卡爾乘積是一個(gè)表的每一行依次與另一個(gè)表中的所有行匹配。在特殊情 況下我們可以使用笛卡兒乘積,如在星形連接中,除此之外,我們要盡量使用笛卡兒乘積,否則,自己想結(jié)果是什么吧!

        注意在下面的語句中,在2個(gè)表之間沒有連接。

        sql> explain plan for

        select emp.deptno,dept,deptno

        from emp,dept

        Query Plan

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

        SLECT STATEMENT [CHOOSE] Cost=5

        MERGE JOIN CARTESIAN

        table ACCESS FULL DEPT

        SORT JOIN

        table ACCESS FULL EMP

        CARTESIAN關(guān)鍵字指出了在2個(gè)表之間做笛卡爾乘積。假如表emp有n行,dept表有m行,笛卡爾乘積的結(jié)果就是得到n * m行結(jié)果。

    posted @ 2008-08-22 22:33 丑男 閱讀(2504) | 評(píng)論 (0)編輯 收藏

    Fedora 7 安裝 nvidia顯卡驅(qū)動(dòng)

    第一步,到nvidia官方下載驅(qū)動(dòng),根據(jù)自己顯卡的型號(hào)選擇,一定要看readme
    第二步,驅(qū)動(dòng)只能在命令行方式下安裝,所以要修改/etc/inittab文件
        id:3:initdefault
                    3代表文本方式,5代表圖形方式
        修改后重啟系統(tǒng)
    第三步,執(zhí)行驅(qū)動(dòng),不出意外會(huì)非常的順利,之后shutdown -r now就完成了

    本人也是第一次安裝,有不對(duì)的地方請(qǐng)大家指正,祝好運(yùn)

    posted @ 2007-07-29 13:48 丑男 閱讀(780) | 評(píng)論 (0)編輯 收藏

    apache rewrite 簡(jiǎn)單應(yīng)用

    主要需求,DNSwww.mydomain.com指向www.mydomain.com/app/login.do

    目前是DNS指向某一個(gè)IP,不能將IP對(duì)應(yīng)到10.11.xxx.xxx/app/login.do

    生產(chǎn)環(huán)境WEB服務(wù)器是apache server


    解決辦法
    利用apache rewriter功能,在httpd.conf中找到

    #LoadModule rewrite_module modules/mod_rewrite.so

    將#號(hào)去掉,也就是把mod_rewrite.so模塊加載進(jìn)來

    之后在文件結(jié)尾處添加

    rewriteengine on
    rewriterule ^/$ http://10.11.xxx.xxx/app/login.do [R]

    posted @ 2007-07-16 21:47 丑男 閱讀(312) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)貼]jasperreport可以用Collection做為數(shù)據(jù)源



    jasperreport可以用Collection做為數(shù)據(jù)源,這種方式比用Connection方式更為靈活方便
     

    posted @ 2005-12-11 18:12 丑男 閱讀(417) | 評(píng)論 (0)編輯 收藏

    我的eclipse插件

    1.MyEclipse
       新出的GA4.0,功能非常強(qiáng)大,是我的首先。
       http://www.myeclipseide.com
    2.Log4E
       配合和Log4j日志功能
       http://log4e.jayefem.de/update
    3.i18n
       編輯國際化資源文件,省得寫native2ascii了
       http://propedit.sourceforge.jp/eclipse_plugins/
    4.FreeMen
        隨時(shí)知道內(nèi)存使用情況
        http://www.junginger.biz/eclipse/

    posted @ 2005-09-04 16:13 丑男 閱讀(397) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)帖]學(xué)習(xí)Reflection

    Reflection 是 Java 程序開發(fā)語言的特征之一,它允許運(yùn)行中的 Java 程序?qū)ψ陨磉M(jìn)行檢查,或者說“自審”,并能直接操作程序的內(nèi)部屬性。例如,使用它能獲得 Java 類中各成員的名稱并顯示出來。
    Java 的這一能力在實(shí)際應(yīng)用中也許用得不是很多,但是在其它的程序設(shè)計(jì)語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數(shù)定義相關(guān)的信息。
    JavaBean 是 reflection 的實(shí)際應(yīng)用之一,它能讓一些工具可視化的操作軟件組件。這些工具通過 reflection 動(dòng)態(tài)的載入并取得 Java 組件(類) 的屬性。
     
    1. 一個(gè)簡(jiǎn)單的例子
    考慮下面這個(gè)簡(jiǎn)單的例子,讓我們看看 reflection 是如何工作的。
    import java.lang.reflect.*;
    public class DumpMethods {
       public static void main(String args[]) {
           try {
               Class c = Class.forName(args[0]);
               Method m[] = c.getDeclaredMethods();
               for (int i = 0; i < m.length; i++)
                   System.out.println(m[i].toString());
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    按如下語句執(zhí)行:
    java DumpMethods java.util.Stack
    它的結(jié)果輸出為:
    public java.lang.Object java.util.Stack.push(java.lang.Object)
    public synchronized java.lang.Object java.util.Stack.pop()
    public synchronized java.lang.Object java.util.Stack.peek()
    public boolean java.util.Stack.empty()
    public synchronized int java.util.Stack.search(java.lang.Object)
    這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。
    這個(gè)程序使用 Class.forName 載入指定的類,然后調(diào)用 getDeclaredMethods 來獲取這個(gè)類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個(gè)類中單個(gè)方法的一個(gè)類。
    2.開始使用 Reflection
    用于 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時(shí)候必須要遵循三個(gè)步驟:第一步是獲得你想操作的類的 java.lang.Class 對(duì)象。在運(yùn)行中的 Java 程序中,用 java.lang.Class 類來描述類和接口等。
    下面就是獲得一個(gè) Class 對(duì)象的方法之一:
    Class c = Class.forName("java.lang.String");
    這條語句得到一個(gè) String 類的類對(duì)象。還有另一種方法,如下面的語句:
    Class c = int.class;
    或者
    Class c = Integer.TYPE;
    它們可獲得基本類型的類信息。其中后一種方法中訪問的是基本類型的封裝類 (如 Integer) 中預(yù)先定義好的 TYPE 字段。
    第二步是調(diào)用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。
    一旦取得這個(gè)信息,就可以進(jìn)行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:
    Class c = Class.forName("java.lang.String");
    Method m[] = c.getDeclaredMethods();
    System.out.println(m[0].toString());
    它將以文本方式打印出 String 中定義的第一個(gè)方法的原型。
    在下面的例子中,這三個(gè)步驟將為使用 reflection 處理特殊應(yīng)用程序提供例證。
    模擬 instanceof 操作符
    得到類信息之后,通常下一個(gè)步驟就是解決關(guān)于 Class 對(duì)象的一些基本的問題。例如,Class.isInstance 方法可以用于模擬 instanceof 操作符:
    class A {
    }
    public class instance1 {
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("A");
               boolean b1 = cls.isInstance(new Integer(37));
               System.out.println(b1);
               boolean b2 = cls.isInstance(new A());
               System.out.println(b2);
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    在這個(gè)例子中創(chuàng)建了一個(gè) A 類的 Class 對(duì)象,然后檢查一些對(duì)象是否是 A 的實(shí)例。Integer(37) 不是,但 new A() 是。
    3.找出類的方法
    找出一個(gè)類中定義了些什么方法,這是一個(gè)非常有價(jià)值也非常基礎(chǔ)的 reflection 用法。下面的代碼就實(shí)現(xiàn)了這一用法:
    import java.lang.reflect.*;
    public class method1 {
       private int f1(Object p, int x) throws NullPointerException {
           if (p == null)
               throw new NullPointerException();
           return x;
       }
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("method1");
               Method methlist[] = cls.getDeclaredMethods();
               for (int i = 0; i < methlist.length; i++) {
                   Method m = methlist[i];
                   System.out.println("name = " + m.getName());
                   System.out.println("decl class = " + m.getDeclaringClass());
                   Class pvec[] = m.getParameterTypes();
                   for (int j = 0; j < pvec.length; j++)
                       System.out.println("param #" + j + " " + pvec[j]);
                   Class evec[] = m.getExceptionTypes();
                   for (int j = 0; j < evec.length; j++)
                       System.out.println("exc #" + j + " " + evec[j]);
                   System.out.println("return type = " + m.getReturnType());
                   System.out.println("-----");
               }
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    這個(gè)程序首先取得 method1 類的描述,然后調(diào)用 getDeclaredMethods 來獲取一系列的 Method 對(duì)象,它們分別描述了定義在類中的每一個(gè)方法,包括 public 方法、protected 方法、package 方法和 private 方法等。如果你在程序中使用 getMethods 來代替 getDeclaredMethods,你還能獲得繼承來的各個(gè)方法的信息。
    取得了 Method 對(duì)象列表之后,要顯示這些方法的參數(shù)類型、異常類型和返回值類型等就不難了。這些類型是基本類型還是類類型,都可以由描述類的對(duì)象按順序給出。
    輸出的結(jié)果如下:
    name = f1
    decl class = class method1
    param #0 class java.lang.Object
    param #1 int
    exc #0 class java.lang.NullPointerException
    return type = int
    -----
    name = main
    decl class = class method1
    param #0 class [Ljava.lang.String;
    return type = void
    -----

    4.獲取構(gòu)造器信息
    獲取類構(gòu)造器的用法與上述獲取方法的用法類似,如:
    import java.lang.reflect.*;
    public class constructor1 {
       public constructor1() {
       }
       protected constructor1(int i, double d) {
       }
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("constructor1");
               Constructor ctorlist[] = cls.getDeclaredConstructors();
               for (int i = 0; i < ctorlist.length; i++) {
                   Constructor ct = ctorlist[i];
                   System.out.println("name = " + ct.getName());
                   System.out.println("decl class = " + ct.getDeclaringClass());
                   Class pvec[] = ct.getParameterTypes();
                   for (int j = 0; j < pvec.length; j++)
                       System.out.println("param #" + j + " " + pvec[j]);
                   Class evec[] = ct.getExceptionTypes();
                   for (int j = 0; j < evec.length; j++)
                       System.out.println("exc #" + j + " " + evec[j]);
                   System.out.println("-----");
               }
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    這個(gè)例子中沒能獲得返回類型的相關(guān)信息,那是因?yàn)闃?gòu)造器沒有返回類型。
    這個(gè)程序運(yùn)行的結(jié)果是:
    name = constructor1
    decl class = class constructor1
    -----
    name = constructor1
    decl class = class constructor1
    param #0 int
    param #1 double
    -----
    5.獲取類的字段(域)
    找出一個(gè)類中定義了哪些數(shù)據(jù)字段也是可能的,下面的代碼就在干這個(gè)事情:

    import java.lang.reflect.*;
    public class field1 {
       private double d;
       public static final int i = 37;
       String s = "testing";
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("field1");
               Field fieldlist[] = cls.getDeclaredFields();
               for (int i = 0; i < fieldlist.length; i++) {
                   Field fld = fieldlist[i];
                   System.out.println("name = " + fld.getName());
                   System.out.println("decl class = " + fld.getDeclaringClass());
                   System.out.println("type = " + fld.getType());
                   int mod = fld.getModifiers();
                   System.out.println("modifiers = " + Modifier.toString(mod));
                   System.out.println("-----");
               }
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    這個(gè)例子和前面那個(gè)例子非常相似。例中使用了一個(gè)新東西 Modifier,它也是一個(gè) reflection 類,用來描述字段成員的修飾語,如“private int”。這些修飾語自身由整數(shù)描述,而且使用 Modifier.toString 來返回以“官方”順序排列的字符串描述 (如“static”在“final”之前)。這個(gè)程序的輸出是:
    name = d
    decl class = class field1
    type = double
    modifiers = private
    -----
    name = i
    decl class = class field1
    type = int
    modifiers = public static final
    -----
    name = s
    decl class = class field1
    type = class java.lang.String
    modifiers =
    -----
    和獲取方法的情況一下,獲取字段的時(shí)候也可以只取得在當(dāng)前類中申明了的字段信息 (getDeclaredFields),或者也可以取得父類中定義的字段 (getFields) 。

    6.根據(jù)方法的名稱來執(zhí)行方法
    文本到這里,所舉的例子無一例外都與如何獲取類的信息有關(guān)。我們也可以用 reflection 來做一些其它的事情,比如執(zhí)行一個(gè)指定了名稱的方法。下面的示例演示了這一操作:
    import java.lang.reflect.*;
    public class method2 {
       public int add(int a, int b) {
           return a + b;
       }
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("method2");
               Class partypes[] = new Class[2];
               partypes[0] = Integer.TYPE;
               partypes[1] = Integer.TYPE;
               Method meth = cls.getMethod("add", partypes);
               method2 methobj = new method2();
               Object arglist[] = new Object[2];
               arglist[0] = new Integer(37);
               arglist[1] = new Integer(47);
               Object retobj = meth.invoke(methobj, arglist);
               Integer retval = (Integer) retobj;
               System.out.println(retval.intvalue());
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    假如一個(gè)程序在執(zhí)行的某處的時(shí)候才知道需要執(zhí)行某個(gè)方法,這個(gè)方法的名稱是在程序的運(yùn)行過程中指定的 (例如,JavaBean 開發(fā)環(huán)境中就會(huì)做這樣的事),那么上面的程序演示了如何做到。
    上例中,getMethod 用于查找一個(gè)具有兩個(gè)整型參數(shù)且名為 add 的方法。找到該方法并創(chuàng)建了相應(yīng)的 Method 對(duì)象之后,在正確的對(duì)象實(shí)例中執(zhí)行它。執(zhí)行該方法的時(shí)候,需要提供一個(gè)參數(shù)列表,這在上例中是分別包裝了整數(shù) 37 和 47 的兩個(gè) Integer 對(duì)象。執(zhí)行方法的返回的同樣是一個(gè) Integer 對(duì)象,它封裝了返回值 84。
    7.創(chuàng)建新的對(duì)象
    對(duì)于構(gòu)造器,則不能像執(zhí)行方法那樣進(jìn)行,因?yàn)閳?zhí)行一個(gè)構(gòu)造器就意味著創(chuàng)建了一個(gè)新的對(duì)象 (準(zhǔn)確的說,創(chuàng)建一個(gè)對(duì)象的過程包括分配內(nèi)存和構(gòu)造對(duì)象)。所以,與上例最相似的例子如下:
    import java.lang.reflect.*;
    public class constructor2 {
       public constructor2() {
       }
       public constructor2(int a, int b) {
           System.out.println("a = " + a + " b = " + b);
       }
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("constructor2");
               Class partypes[] = new Class[2];
               partypes[0] = Integer.TYPE;
               partypes[1] = Integer.TYPE;
               Constructor ct = cls.getConstructor(partypes);
               Object arglist[] = new Object[2];
               arglist[0] = new Integer(37);
               arglist[1] = new Integer(47);
               Object retobj = ct.newInstance(arglist);
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    根據(jù)指定的參數(shù)類型找到相應(yīng)的構(gòu)造函數(shù)并執(zhí)行它,以創(chuàng)建一個(gè)新的對(duì)象實(shí)例。使用這種方法可以在程序運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建對(duì)象,而不是在編譯的時(shí)候創(chuàng)建對(duì)象,這一點(diǎn)非常有價(jià)值。
    8.改變字段(域)的值
    reflection 的還有一個(gè)用處就是改變對(duì)象數(shù)據(jù)字段的值。reflection 可以從正在運(yùn)行的程序中根據(jù)名稱找到對(duì)象的字段并改變它,下面的例子可以說明這一點(diǎn):
    import java.lang.reflect.*;
    public class field2 {
       public double d;
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("field2");
               Field fld = cls.getField("d");
               field2 f2obj = new field2();
               System.out.println("d = " + f2obj.d);
               fld.setDouble(f2obj, 12.34);
               System.out.println("d = " + f2obj.d);
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    這個(gè)例子中,字段 d 的值被變?yōu)榱?12.34。
    9.使用數(shù)組
    本文介紹的 reflection 的最后一種用法是創(chuàng)建的操作數(shù)組。數(shù)組在 Java 語言中是一種特殊的類類型,一個(gè)數(shù)組的引用可以賦給 Object 引用。觀察下面的例子看看數(shù)組是怎么工作的:
    import java.lang.reflect.*;
    public class array1 {
       public static void main(String args[]) {
           try {
               Class cls = Class.forName("java.lang.String");
               Object arr = Array.newInstance(cls, 10);
               Array.set(arr, 5, "this is a test");
               String s = (String) Array.get(arr, 5);
               System.out.println(s);
           } catch (Throwable e) {
               System.err.println(e);
           }
       }
    }
    例中創(chuàng)建了 10 個(gè)單位長度的 String 數(shù)組,為第 5 個(gè)位置的字符串賦了值,最后將這個(gè)字符串從數(shù)組中取得并打印了出來。
    下面這段代碼提供了一個(gè)更復(fù)雜的例子:
    import java.lang.reflect.*;
    public class array2 {
       public static void main(String args[]) {
           int dims[] = new int[]{5, 10, 15};
           Object arr = Array.newInstance(Integer.TYPE, dims);
           Object arrobj = Array.get(arr, 3);
           Class cls = arrobj.getClass().getComponentType();
           System.out.println(cls);
           arrobj = Array.get(arrobj, 5);
           Array.setInt(arrobj, 10, 37);
           int arrcast[][][] = (int[][][]) arr;
           System.out.println(arrcast[3][5][10]);
       }
    }
    例中創(chuàng)建了一個(gè) 5 x 10 x 15 的整型數(shù)組,并為處于 [3][5][10] 的元素賦了值為 37。注意,多維數(shù)組實(shí)際上就是數(shù)組的數(shù)組,例如,第一個(gè) Array.get 之后,arrobj 是一個(gè) 10 x 15 的數(shù)組。進(jìn)而取得其中的一個(gè)元素,即長度為 15 的數(shù)組,并使用 Array.setInt 為它的第 10 個(gè)元素賦值。
    注意創(chuàng)建數(shù)組時(shí)的類型是動(dòng)態(tài)的,在編譯時(shí)并不知道其類型。

    posted @ 2005-08-07 01:02 丑男 閱讀(419) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)帖]Eclipse快捷鍵

    作用域
    功能
    快捷鍵
    全局
    查找并替換
    Ctrl+F
    文本編輯器
    查找上一個(gè)
    Ctrl+Shift+K
    文本編輯器
    查找下一個(gè)
    Ctrl+K
    全局
    撤銷
    Ctrl+Z
    全局
    復(fù)制
    Ctrl+C
    全局
    恢復(fù)上一個(gè)選擇
    Alt+Shift+↓
    全局
    剪切
    Ctrl+X
    全局
    快速修正
    Ctrl1+1
    全局
    內(nèi)容輔助
    Alt+/
    全局
    全部選中
    Ctrl+A
    全局
    刪除
    Delete
    全局
    上下文信息
    Alt+?
    Alt+Shift+?
    Ctrl+Shift+Space
    Java編輯器
    顯示工具提示描述
    F2
    Java編輯器
    選擇封裝元素
    Alt+Shift+↑
    Java編輯器
    選擇上一個(gè)元素
    Alt+Shift+←
    Java編輯器
    選擇下一個(gè)元素
    Alt+Shift+→
    文本編輯器
    增量查找
    Ctrl+J
    文本編輯器
    增量逆向查找
    Ctrl+Shift+J
    全局
    粘貼
    Ctrl+V
    全局
    重做
    Ctrl+Y
     
    查看
    作用域
    功能
    快捷鍵
    全局
    放大
    Ctrl+=
    全局
    縮小
    Ctrl+-
     
    窗口
    作用域
    功能
    快捷鍵
    全局
    激活編輯器
    F12
    全局
    切換編輯器
    Ctrl+Shift+W
    全局
    上一個(gè)編輯器
    Ctrl+Shift+F6
    全局
    上一個(gè)視圖
    Ctrl+Shift+F7
    全局
    上一個(gè)透視圖
    Ctrl+Shift+F8
    全局
    下一個(gè)編輯器
    Ctrl+F6
    全局
    下一個(gè)視圖
    Ctrl+F7
    全局
    下一個(gè)透視圖
    Ctrl+F8
    文本編輯器
    顯示標(biāo)尺上下文菜單
    Ctrl+W
    全局
    顯示視圖菜單
    Ctrl+F10
    全局
    顯示系統(tǒng)菜單
    Alt+-
     
    導(dǎo)航
    作用域
    功能
    快捷鍵
    Java編輯器
    打開結(jié)構(gòu)
    Ctrl+F3
    全局
    打開類型
    Ctrl+Shift+T
    全局
    打開類型層次結(jié)構(gòu)
    F4
    全局
    打開聲明
    F3
    全局
    打開外部javadoc
    Shift+F2
    全局
    打開資源
    Ctrl+Shift+R
    全局
    后退歷史記錄
    Alt+←
    全局
    前進(jìn)歷史記錄
    Alt+→
    全局
    上一個(gè)
    Ctrl+,
    全局
    下一個(gè)
    Ctrl+.
    Java編輯器
    顯示大綱
    Ctrl+O
    全局
    在層次結(jié)構(gòu)中打開類型
    Ctrl+Shift+H
    全局
    轉(zhuǎn)至匹配的括號(hào)
    Ctrl+Shift+P
    全局
    轉(zhuǎn)至上一個(gè)編輯位置
    Ctrl+Q
    Java編輯器
    轉(zhuǎn)至上一個(gè)成員
    Ctrl+Shift+↑
    Java編輯器
    轉(zhuǎn)至下一個(gè)成員
    Ctrl+Shift+↓
    文本編輯器
    轉(zhuǎn)至行
    Ctrl+L
     
    搜索
    作用域
    功能
    快捷鍵
    全局
    出現(xiàn)在文件中
    Ctrl+Shift+U
    全局
    打開搜索對(duì)話框
    Ctrl+H
    全局
    工作區(qū)中的聲明
    Ctrl+G
    全局
    工作區(qū)中的引用
    Ctrl+Shift+G
     
    文本編輯
    作用域
    功能
    快捷鍵
    文本編輯器
    改寫切換
    Insert
    文本編輯器
    上滾行
    Ctrl+↑
    文本編輯器
    下滾行
    Ctrl+↓
     
    文件
    作用域
    功能
    快捷鍵
    全局
    保存
    Ctrl+X
    Ctrl+S
    全局
    打印
    Ctrl+P
    全局
    關(guān)閉
    Ctrl+F4
    全局
    全部保存
    Ctrl+Shift+S
    全局
    全部關(guān)閉
    Ctrl+Shift+F4
    全局
    屬性
    Alt+Enter
    全局
    新建
    Ctrl+N
     
    項(xiàng)目
    作用域
    功能
    快捷鍵
    全局
    全部構(gòu)建
    Ctrl+B
     
    源代碼
    作用域
    功能
    快捷鍵
    Java編輯器
    格式化
    Ctrl+Shift+F
    Java編輯器
    取消注釋
    Ctrl+
    Java編輯器
    注釋
    Ctrl+/
    Java編輯器
    添加導(dǎo)入
    Ctrl+Shift+M
    Java編輯器
    組織導(dǎo)入
    Ctrl+Shift+O
    Java編輯器
    使用try/catch塊來包圍
    未設(shè)置,太常用了,所以在這里列出,建議自己設(shè)置。
    也可以使用Ctrl+1自動(dòng)修正。
     
    運(yùn)行
    作用域
    功能
    快捷鍵
    全局
    單步返回
    F7
    全局
    單步跳過
    F6
    全局
    單步跳入
    F5
    全局
    單步跳入選擇
    Ctrl+F5
    全局
    調(diào)試上次啟動(dòng)
    F11
    全局
    繼續(xù)
    F8
    全局
    使用過濾器單步執(zhí)行
    Shift+F5
    全局
    添加/去除斷點(diǎn)
    Ctrl+Shift+B
    全局
    顯示
    Ctrl+D
    全局
    運(yùn)行上次啟動(dòng)
    Ctrl+F11
    全局
    運(yùn)行至行
    Ctrl+R
    全局
    執(zhí)行
    Ctrl+U
     
    重構(gòu)
    作用域
    功能
    快捷鍵
    全局
    撤銷重構(gòu)
    Alt+Shift+Z
    全局
    抽取方法
    Alt+Shift+M
    全局
    抽取局部變量
    Alt+Shift+L
    全局
    內(nèi)聯(lián)
    Alt+Shift+I
    全局
    移動(dòng)
    Alt+Shift+V
    全局
    重命名
    Alt+Shift+R
    全局
    重做
    Alt+Shift+Y

    posted @ 2005-08-06 00:02 丑男 閱讀(441) | 評(píng)論 (0)編輯 收藏

    簡(jiǎn)單應(yīng)用日期類

    1.自定義格式
    ?? 用到j(luò)ava.text.SimpleDateFormat,其中參數(shù)如下:
    ???ss:秒
    ???mm:分
    ???hh:小時(shí)
    ???EEEE:星期
    ???MMMM:月份
    ?? dd:日期
    ?? yyyy:年份
    ????????Date?d?=?new?Date();
    ????????SimpleDateFormat?sdf?
    =?new?SimpleDateFormat("ss-mm-hh-EEEE-MMMM-dd-yyyy");
    ????????System.
    out.println(sdf.format(d));

    運(yùn)行結(jié)果
    58-21-11-星期五-七月-22-2005

    2.DateFormat自帶格式
    ??????? Date?date?=?new?Date();?

    ????????DateFormat?shortDateFormat?
    =?DateFormat.getDateTimeInstance(?DateFormat.SHORT,?
    ???????????????????????????????????????????????????????????????????????????????????????????????????????????????? DateFormat.SHORT);?
    ???????????System.out.println(shortDateFormat.format(date));
    ?????????? //輸出結(jié)果????? 05-7-22 下午11:47


    ?????????? DateFormat mediumDateFormat = DateFormat.getDateTimeInstance(?DateFormat.MEDIUM,
    ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? DateFormat.MEDIUM);?
    ?????????? System.out.println?(mediumDateFormat.format(date));
    ?????????? //輸出結(jié)果?????? 2005-7-22 23:48:11


    ?????????? DateFormat longDateFormat =?DateFormat.getDateTimeInstance(?DateFormat.LONG,?
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????? DateFormat.LONG);
    ?????????? System.out.println(longDateFormat.format(date));
    ?????????? //輸出結(jié)果????? 2005年7月22日 下午11時(shí)48分45秒


    ?????????? DateFormat fullDateFormat = DateFormat.getDateTimeInstance( DateFormat.FULL,
    ?????????????????????????????????????????????????????????????????????????????????????????????????????????????? DateFormat.FULL);
    ?????????? System.out.println?(fullDateFormat.format(date));
    ?????????? //輸出結(jié)果????? Saturday, September 29, 2001 8:44:45 PM EDT

    posted @ 2005-08-05 23:31 丑男 閱讀(430) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)帖]Log4j比較全面的配置

    LOG4J的配置之簡(jiǎn)單使它遍及于越來越多的應(yīng)用中了:Log4J配置文件實(shí)現(xiàn)了輸出到控制臺(tái)、文件、回滾文件、發(fā)送日志郵件、輸出到數(shù)據(jù)庫日志表、自定義標(biāo)簽等全套功能。擇其一二使用就夠用了,

     

    log4j.rootLogger=DEBUG,CONSOLE,A1,im
    log4j.addivity.org.apache=true

     

    # 應(yīng)用于控制臺(tái)

    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.Threshold=DEBUG
    log4j.appender.CONSOLE.Target=System.out
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
    #log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n


    #應(yīng)用于文件

    log4j.appender.FILE=org.apache.log4j.FileAppender
    log4j.appender.FILE.File=file.log
    log4j.appender.FILE.Append=false
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
    # Use this layout for LogFactor 5 analysis

     

    # 應(yīng)用于文件回滾

    log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.ROLLING_FILE.Threshold=ERROR
    log4j.appender.ROLLING_FILE.File=rolling.log
    log4j.appender.ROLLING_FILE.Append=true
    log4j.appender.ROLLING_FILE.MaxFileSize=10KB
    log4j.appender.ROLLING_FILE.MaxBackupIndex=1
    log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


    #應(yīng)用于socket
    log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
    log4j.appender.SOCKET.RemoteHost=localhost
    log4j.appender.SOCKET.Port=5001
    log4j.appender.SOCKET.LocationInfo=true
    # Set up for Log Facter 5
    log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
    log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n


    # Log Factor 5 Appender
    log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
    log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

     

    # 發(fā)送日志給郵件

    log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
    log4j.appender.MAIL.Threshold=FATAL
    log4j.appender.MAIL.BufferSize=10
    log4j.appender.MAIL.From=xxx@www.xxx.com
    log4j.appender.MAIL.SMTPHost=www.wusetu.com
    log4j.appender.MAIL.Subject=Log4J Message
    log4j.appender.MAIL.To=xxx@www.xxx.com
    log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
    log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

     

    # 用于數(shù)據(jù)庫
    log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
    log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
    log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
    log4j.appender.DATABASE.user=root
    log4j.appender.DATABASE.password=
    log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
    log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
    log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


    log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.A1.File=SampleMessages.log4j
    log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
    log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout


    輸出到2000NT日志
     把Log4j壓縮包里的NTEventLogAppender.dll拷到WINNT\SYSTEM32目錄下

     log4j.logger.NTlog=FATAL, A8
     # APPENDER A8
     log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender
     log4j.appender.A8.Source=JavaTest
     log4j.appender.A8.layout=org.apache.log4j.PatternLayout
     log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n

    #自定義Appender

    log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

    log4j.appender.im.host = mail.cybercorlin.net
    log4j.appender.im.username = username
    log4j.appender.im.password = password
    log4j.appender.im.recipient = xxx@xxx.net

    log4j.appender.im.layout=org.apache.log4j.PatternLayout
    log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

    posted @ 2005-07-24 22:25 丑男 閱讀(657) | 評(píng)論 (0)編輯 收藏

    學(xué)習(xí)Log4j筆記

    今天花了一天的時(shí)間來配置Log4j,沒想到要那么多時(shí)間,還問了不少人,帖子也發(fā)了不少,不過最終還是搞定了,不過還有些問題,請(qǐng)高手幫我看看,多謝了。

    1.首先是配置簡(jiǎn)單java project
    現(xiàn)在來看log4j.propertise
    #級(jí)別為DEBUG,二個(gè)輸出端,分別為stdout,R
    log4j.logger.helloappLogger=DEBUG, stdout, R

    #控制臺(tái)輸出
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n

    #保存到helloappLoggerlog.txt日志中,大小為100KB
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=F:/code/eclipse/workspace/TestLo4j/log/helloappLoggerlog.txt
    log4j.appender.R.MaxFileSize=100KB
    log4j.appender.R.MaxBackupIndex=1
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%d{yyyy MMM dd HH:mm:ss} %-5p %c - %m%n

    java文件中用到日志
    package com;
    import org.apache.log4j.*;
    public class TestLog4j {
        static Logger logger = Logger.getLogger("helloappLogger");
        public static void main(String[] args) {
    //      PropertyConfigurator.configure("log4j.properties");
    //      如果.properties在當(dāng)前目錄下可以省略,我放在項(xiàng)目根目錄下,和com包同目錄
            logger.debug("Debug ...");
            logger.info("Info ...");
            logger.warn("Warn ...");
            logger.error("Error ...");
        }
    }

    2.web project中配置log4j

    還是先來看log4j.perproties

    #級(jí)別為DEBUG,三個(gè)輸出端,分別為stdout,FILE,R
    log4j.logger.hello=DEBUG, stdout, FILE, R

    #stdout是在控制臺(tái)輸出
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n

    #保存在rolling_log_file.log日志中,appender是RollingFileAppender
    #需要注意的是File=F:/code/...,不要寫成\,這就一點(diǎn)害死我了
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=F:/code/eclipse/workspace/TestCvs/WebRoot/WEB-INF/rolling_log_file.log
    log4j.appender.R.MaxFileSize=100KB
    log4j.appender.R.MaxBackupIndex=1
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%d{yyyy MMM dd HH:mm:ss} %-5p %c - %m%n

    #保存在log_file.log日志中,appender是FileAppender
    log4j.appender.FILE=org.apache.log4j.FileAppender
    log4j.appender.FILE.File=F:/code/eclipse/workspace/TestCvs/WebRoot/WEB-INF/log_file.log
    log4j.appender.FILE.Append=false
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=%d{yyyy MMM dd HH:mm:ss} %-5p %c - %m%n

    之后要把它加入serlet中,和服務(wù)器一起啟動(dòng),方便其他程序使用

    public class Log4jServlet extends HttpServlet {
        public void init() throws ServletException {
            ServletContext sct = getServletContext();
            System.out.println("[Log4j]: The Root Path: " + sct.getRealPath("/"));
            System.out.println("[Log4j]: InitServlet init start...");
            PropertyConfigurator.configure(sct.getRealPath("/")
                  +getServletConfig().getInitParameter("propfile"));
            System.out.println("[Log4j]: InitServlet init over.");
        }
    }

    <servlet>
        <description>init log4j of servlet</description>
        <display-name>log4j servlet</display-name>
        <servlet-name>Log4jServlet</servlet-name>
        <servlet-class>com.testCvs.Log4jServlet</servlet-class>
        <init-param>
         <param-name>propfile</param-name>
         <param-value>/WEB-INF/log4j.properties</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    注:log4j.properties放在/WEB-INF下,servlet自動(dòng)加載這個(gè)文件

    至此所有配置應(yīng)該成功了,不過還是有些問題沒有解決好,問了幾個(gè)朋友也沒有得到好的答復(fù),但是現(xiàn)在可以在控制臺(tái)和文件中輸出日志,基本功能達(dá)到了。還請(qǐng)各位有空給我看看這個(gè)錯(cuò)誤,歡迎指正。

    錯(cuò)誤如下:
    log4j:WARN No appenders could be found for logger (org.apache.jasper.compiler.JspRuntimeContext).
    log4j:WARN Please initialize the log4j system properly.

    posted @ 2005-07-24 22:10 丑男 閱讀(9660) | 評(píng)論 (8)編輯 收藏

    CVS配置學(xué)習(xí)筆記

    本文很簡(jiǎn)單,CVS的配置,做個(gè)學(xué)習(xí)筆記吧,省得忘了
    1.首先要下載cvsnt,是windows平臺(tái)下cvs服務(wù)器端軟件。http://www.cvsnt.com/cvspro/

    2.安裝軟件并查看服務(wù)是否啟動(dòng)

    3.建立Repositories,設(shè)置Server Settings,在Compatibility選中Respond as cvs 1.11.2 to version request,方便eclipse與其通信

    4.在eclipse中建立工程,之后右鍵project-->team-->share project-->,全部選擇默認(rèn)設(shè)置

    至此,cvs配置成功,還是花了些時(shí)間。請(qǐng)各位高手指正

    posted @ 2005-07-23 23:37 丑男 閱讀(642) | 評(píng)論 (0)編輯 收藏

    開篇

    剛剛申請(qǐng)到blogjava,第一篇先報(bào)道吧!
    剛才大概看了幾個(gè)Blog,真是高手如林,其中就有大名鼎鼎的大胃,以前就教過我不少,看來又找到了學(xué)習(xí)的好地方。說實(shí)話,這段時(shí)間事情太多了,已經(jīng)有些日子沒寫程序了,慚愧。不過從維護(hù)這個(gè)blog開始,我要繼續(xù)學(xué)習(xí)了,爭(zhēng)取年底能找個(gè)好工作。

    posted @ 2005-07-20 16:16 丑男 閱讀(423) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲一区中文字幕久久| 成年网站免费入口在线观看| 亚洲春色另类小说| 亚洲va久久久久| 国产精品久久久久久亚洲小说| 深夜特黄a级毛片免费播放| 中国好声音第二季免费播放| 男女作爱在线播放免费网站| 黄网站免费在线观看| 成全视频免费高清| 国产一区二区三区在线免费观看| 免费a级毛片无码a∨性按摩| 亚洲人精品午夜射精日韩| 久久综合亚洲鲁鲁五月天| 精品韩国亚洲av无码不卡区| 98精品全国免费观看视频| 国产片免费福利片永久| 亚洲Av永久无码精品三区在线| 亚洲国产日产无码精品| 亚洲日韩在线观看免费视频| 99久久久国产精品免费无卡顿| 亚洲第一页综合图片自拍| 亚洲AV日韩AV天堂久久| 美女免费视频一区二区| 日本zzzzwww大片免费| 狠狠色伊人亚洲综合成人| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲免费视频一区二区三区| 亚洲色偷偷av男人的天堂| 麻豆高清免费国产一区| 亚洲色精品aⅴ一区区三区| 免费观看久久精彩视频| 亚洲精品中文字幕乱码| 国产日韩精品无码区免费专区国产 | 噜噜噜亚洲色成人网站| 亚洲精品视频免费| 精品国产麻豆免费人成网站| 亚洲精品中文字幕无乱码| 国产高清在线免费视频| GOGOGO高清免费看韩国| 亚洲熟妇色自偷自拍另类|