java筆記整理

Java 筆記整理javascript

包含內容css

    Unixhtml

Java 基礎,前端

數據庫(Oracle jdbc Hibernate pl/sql),java

webnode

JSPmysql

Strutslinux

Ajaxc++

Spring程序員

Ejb

java和模式

Linux/Unix筆記

 

inode :存儲編號(地址)

ls -k:查看磁盤分區

ls -li:顯示當前文件的inode號。

目錄的大小跟文件的大小有關,跟目錄裏的文件(目錄)數量無關。

一行多個命令的話,中間用分號分開。如:pwd;cal;date

last | grep pts/13 表示查看pts/13登錄服務器的記錄。

find . -mtime -10 -print

-10:表示10天之內的,

+10:表示10天之前的,

.:表示當前路徑

-mtime:最後一次修改時間。

-print:表示輸出到顯示器(可有可沒有)。

-user 0:表示UID是0。

size+400:表示大於400*0.5K  ,-400表示小於400*0.5K

-atime:表示最後一次訪問時間。

grep:在文件裏查找符合要求的那一行。一般用在管道(|)後面,表示對 |  前面的輸出作查找。

如:cat /etc/passwd | gred liu | sort

sort:表示排序。

進程是做業,做業是進程。

前臺就是終端,後臺就是服務器。

當殺掉父進程,前臺子進程會消失,,後臺做業不依賴於任何終端,會繼續運行

LINUX經常使用命令(基礎)

1. man 對你熟悉或不熟悉的命令提供幫助解釋

eg:man ls 就能夠查看ls相關的用法

注:按q鍵或者ctrl+c退出,在linux下能夠使用ctrl+c終止當前程序運行。

2. ls 查看目錄或者文件的屬*,列舉出任一目錄下面的文件

eg: ls /usr/man        ls -l

a.d表示目錄(directory),若是是一個"-"表示是文件,若是是l則表示是一個鏈接文件(link)

b.表示文件或者目錄許可權限.分別用可讀(r),可寫(w),可運行(x)。

3. cp 拷貝文件

eg: cp filename1 filename2 //把filename1拷貝成filename2

cp 1.c netseek/2.c //將1.c拷到netseek目錄下命名爲2.c

4. rm 刪除文件和目錄

eg: rm 1.c //將1.c這個文件刪除

5. mv 移走目錄或者改文件名

eg: mv filename1 filename2 //將filename1 更名爲filename2

mv qib.tgz ../qib.tgz //移到上一級目錄

6. cd 改變當前目錄 pwd 查看當前所在目錄完整路徑

eg: pwd //查看當前所在目錄路徑

cd netseek //進入netseek這個目錄

cd //退出當前目錄

7. cat,more命令

將某個文件的內容顯示出來。兩個命令所不一樣的是:cat把文件內容一直打印出來,而 more則分屏顯示

eg; cat>1.c //就能夠把代碼粘帖到1.c文件裏,按ctrl+d 保存代碼。

cat 1.c 或more 1.c //均可以查看裏面的內容。

gcc -o 1 1.c //將1.c編譯成.exe文件,咱們能夠用此命編譯出代碼。

8.chmod 命令 權限修改 用法:chmod 一位8進制數 filename。

eg: chmod u+x filenmame //只想給本身運行,別人只能讀

//u表示文件主人, g 表示文件文件所在組。 o 表示其餘人 ;r 表可讀,w 表可寫,x 表能夠運行

chmod g+x filename //同組的人來執行

9. clear,date命令

clear:清屏,至關與DOS下的cls;date:顯示當前時間。

10. mount 加載一個硬件設備

用法:mount [參數] 要加載的設備 載入點

eg: mount /dev/cdrom

cd /mnt/cdrom //進入光盤目錄

11. su 在不退出登錄的狀況下,切換到另一我的的身份

用法: su -l 用戶名(若是用戶名缺省,則切換到root狀態)

eg:su -l netseek (切換到netseek這個用戶,將提示輸入密碼)

12.whoami,whereis,which,id

//whoami:確認本身身份

//whereis:查詢命令所在目錄以及幫助文檔所在目錄

//which:查詢該命令所在目錄(相似whereis)

//id:打印出本身的UID以及GID。(UID:用戶身份惟一標識。GID:用戶組身份惟一標識。每個用戶只能有一個惟一的UID和 GID)

eg: whoami //顯示你自已登錄的用戶名

whereis bin 顯示bin所在的目錄,將顯示爲:/usr/local/bin

which bin

13. grep,find

grep:文本內容搜索;find:文件或者目錄名以及權限屬主等匹配搜索

eg: grep success *    /*查找當前目錄下面全部文件裏面含有success字符的文件

14. kill 能夠殺死某個正在進行或者已是dest狀態的進程

eg; ps ax

15. passwd 能夠設置口令

16. history 用戶用過的命令

eg: history //能夠顯示用戶過去使用的命令

17. !! 執行最近一次的命令

18. mkdir命令

eg: mkdir netseek //建立netseek這個目錄

19. tar 解壓命令

eg: tar -zxvf nmap-3.45.tgz //將這個解壓到nmap-3.45這個目錄裏

20. finger 可讓使用者查詢一些其餘使用者的資料

eg: finger //查看所用用戶的使用資料

finger root //查看root的資料

ftp上傳下載ftp 192.168.1.100

用戶:xiangf  Pwd xiangf

Put   mput上傳多個Get   mget下載多個

linuxJdk的安裝

1. 先從網上下載jdk(jdk-1_5_0_02-linux-i586.rpm) 

進入安裝目錄
#cd /home
#cp jdk-1_5_0_02-linux-i586.rpm /usr/local
#cd /usr/local
給全部用戶添加可執行的權限
#chmod +x jdk-1_5_0_02-linux-i586.rpm.bin
#./jdk-1_5_0_02-linux-i586.rpm.bin
此時會生成文件jdk-1_5_0_02-linux-i586.rpm,一樣給全部用戶添加可執行的權限
#chmod +x jdk-1_5_0_02-linux-i586.rpm
安裝程序
#rpm -ivh jdk-1_5_0_02-linux-i586.rpm
出現安裝協議等,按接受便可

2.設置環境變量。[U1] 
#vi /etc/profile
在最後面加入 
#set java environment
JAVA_HOME=/usr/java/jdk-1_5_0_02
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
保存退出。

3.檢查JDK是否安裝成功。
#java -version
若是看到JVM版本及相關信息,即安裝成功!

bash-profile是配置文件,配置java-homepathclasspath

。空格。bash-profile  重新啓動 

Vim bash-profile編輯

Javac .java編譯成。Class     java運行。Class文件

java –d.按包的名字自動生成相對應的


Core Java筆記

人--->源文件--->編譯器--->程序--->CPU

編譯器:

1,編譯執行:源文件--->可執行代碼。如:C/C++語言。

         執行效率高。可移植性差。---->開發成本的增長。

2,解釋執行:源文件--->體系結構中立的中間代碼( .class)--- >解釋器 --->機器指令。 如 :java語言

     執行效率低。 可移植性好。---->  對硬件要求高。

JAVA語言:

(源文件)--->(編譯器javac.exe)--->中間碼--->(虛擬機java.exe)--->機器指令--->CPU

(編譯) (解釋)

.java ----> .class ---> 可執行文件

PATH:指定可執行程序(命令)在哪一個目錄。不一樣目錄用(:)分開。--->SHELL

JAVA_HOME:指定JDK的安裝目錄。給其它應用程序看的。

CLASSPATH:指定(jar文件)中間字節碼文件在什麼地方。由多個目錄組成的集合。--->

           讓虛擬機能夠找到中間字節碼文件。就是能夠找到.class文件

服務器上csh:.cshrc

bsh:.profile

客戶端上。bash:.bash_profile

  1 # .bash_profile

  3 # Get the aliases and functions

  4 if [ -f ~/.bashrc ]; then

  5  . ~/.bashrc

  6 fi  //if的結尾。

  8 # User specific environment and startup programs  //#表明註釋。

  9 JAVA_HOME=/opt/jdk1.5.0_15       JDK 安裝路徑--- JDK = JRE {JVM(硬件)+編譯器( 軟件)} +編譯器工具+類庫            

 10 PATH=$JAVA_HOME/bin:$PATH:$HOME/bin         //系統定義的$PATH   啓動命令

 11 CLASSPATH=.:java/jar/servlet-api.jar:/java/jar/jsp-api.jar        //類路徑

 12

 13 export PATH CLASSPATH JAVA_HOME   //使三個變量變成全局變量。。

Source .bash_profile:只能通過這條命令以後,纔會讓修改的變量生效。(csh)

. .bash_profile。 只能通過這條命令以後,纔會讓修改的變量生效。   (bash)

java -version:查看虛擬機的版本號。

 

2.,編寫第一個JAVA程序[U2] 

1),以.java結尾的文件。

2),全部內容,都要寫在一個類中(類名要和文件名想同,包括大小寫在內)

       pbulic class HelloWorld{......}

3),main函數是程序執行的入口,程序從main函數的第一條語句開始執行,執行到main函數結束爲止。

           public static void main(String argvs[]){

                   }

4),輸出語句:System.out.println(    );

5),每條語句以(;)結尾

   先指定到源程序存放的目錄,而後進行如下步驟運行。

   編譯:javac命令。如:javac -d . HelloWorld.java -->生成HelloWorld.class類文件

   啓動虛擬機(java),運行類文件。如:java com.work.core.HelloWorld   

      後面的.class省略,無需寫成java com.work.core.HelloWorld.class

 

包(package):

1,package com.kettas.corejava; //包聲明。

2,必須保證類文件必定放在相應的目錄結構中,HelloWorld.class放在com/kettas/corejava目錄中。

3,運行時,必定在頂層包的同級目錄下運行java命令,

      例如:com(shell界面裏運行)java com.kettas.corejava.HelloWorld

 (若是頂級包所在的目錄已經被配置到CLASSPATH中的話能夠在任意目錄中啓動 java命令)

1,類文件太多,很差管理。

2,解決重名。

javac -d . HelloWorld.java     (不只可以編譯類文件,同時還能建立包結構)

運行命令java xxxx 類的名字--- 啓動虛擬機

(一)語言:適合於internet

1,跨平臺的   (屬於解釋執行的語言)

2,更容易開發出安全的程序:

       1)垃圾回收器,(幫助程序員管理內存)

       2)取消了指針,對數組越界進行檢查

       3)安全檢查機制,(對生成的字節碼檢測,如:包結構檢測)

      Hash算法,,只要加密的源是同樣的。通過Hash運算以後,Hash值都同樣。

       加密的源若是不同了,通過Hash運算以後,值都不同。

 

(二)變量:

如:  學生,姓名,性別,age

            賬戶,ID,password,balance,username

內存:沒記憶,容量小,成本高,存儲變量數據,最小邏輯單位:byte(字節)=8bit(位)

外存(硬盤):有記憶,容量大,成本低,存儲文件數據

1,變量聲明:給變量起名,是給變量選擇一種數據類型。如:int age;

 不一樣的變量,

             1)參與的運算是不一樣的,

             2)存儲的值是不一樣的,

             3)須要的存儲空間的大小也不一樣,

 

 java數據類型:

簡單數據類型(原始數據類型)

   數字:    整數:byte(1字節)-short(2字節) -int[U3] (在內存中佔4個字節)-long(8個字節)

  小數:float(4個字節,單精度浮點型) - double(8個字節,雙精度浮點型)

  字符:char(一個字符=2個字節):只能表示一個字。  如:char c='中'; c存的是‘中‘這個字的編碼。

 布爾:boolean(true,false),不能用0和非0表示。

String[U4] (字符串)複雜數據類型(類)

String 類提供了數值不可改變的字符串 String s=new String(「abc」);建立了兩個對象1,在字符串池中建立一個對象(此對象是不能重複的)2,new出一個對象。Java運行環境有一個字符串池,由String類維護。執行語句String s="abc"時,首先查看字符串池中是否存在字符串"abc",若是存在則直接將"abc"賦給s,若是不存在則先在字符串池中新建一個字符串"abc",而後再將其賦給s。執行語句String s=new String("abc")時,無論字符串池中是否存在字符串"abc",直接新建一個字符串"abc"(注意:新建的字符串"abc"不是在字符串池中),而後將其付給s。

2,初始化 (局部變量而言,必須初始化才能使用)   如:age=10; 

3,經過變量的名字對變量進行操做,如:age=other;

            賦值時,左=右

                  1)數據性質是否同樣。

                  2)所佔用的內存空間上考慮   (左>右)不用類型轉換。(左<右)要類型強制轉換,

                    如:int age=1;

                       long l=10;

                       age=(int)l;

 符號位:0表明正數,1表明負數。

BigDecimal比double更精確,通常用於處理高精度運算。

&和&&的區別。

&是位運算符,表示按位與運算,&&是邏輯運算符,表示邏輯與(and)

Java中的標識符的要求:

1,只能是字母,數字,_,$。 2,數字不能做爲標識符的開頭。

3,大小寫敏感。               4,沒有長度限制。如:ArrayOutOfBoudleException  

5,標識符不能是關鍵字。 

 

通常來講,類的名字以大寫字母開頭。

方法和變量的名字以小寫字母開頭。

標識符的名字應當具備含義,如    age  , name

 

表達式:1,由運算符和變量組成。2,都會有返回值。           

簡單表達式:a/b;       複合表達式:"a/b="+(a/b);

 

做業,打印潤年,

1,能被4整除,但不能被100整除

2,能被400整除。

 

自增(++),自減(--)運算符。

前++:++a;先對a+1,再返回a+1以後的值。

後++:a++;先返回a的值,而後對a進行+1。

前++,後++共同的特色:a自己的值都會+1;

區別在於表達式的返回值是不同;用返回值來參與計算。

 

? :    -->(boolean express)? A : B;如:char ch=(5>2)?'Y':'N';

?前面的布爾表達式若是爲真就執行A,不然執行B。

      (‘:‘左右兩側的返回類型要一致,且與ch的返回類型也同樣)

 

 

 

 

 

 

 

 

java打包(壓縮包    .zip   .rar    .tar   .gz    .jar)。

 

root/

  yesq/

  |-com/

    |-work/

      |-core/

        |-VarTest.class

        |-RunNian.class

          .  .  .  .  .  .

   壓縮命令: jar -cvf abc.jar  dir

   解壓命令:jar -xvf abc.jar

 abc.jar爲生成壓縮包的名字

 dir爲被打包的文件目錄下的東西

 c:是作壓縮。v:爲壓縮過程的信息。f:指定壓縮文件的名字。x:是作解壓

  打包通常從頂層包開始打。如:[java@localhost yesq]$ jar -cvf first.jar com    

                                             //當前目錄(yesq)下的com文件夾開始打

 

1,得到別人提供的jar文件

2,將jar文件的名字以及他的絕對路徑配置到CLASSPATH中

3,使用import語句,將其餘包的內容導入到本文件中,如:引入包com.kettas.common包中的SystemIn類

                                              import com.kettas.common.SystemIn;

 

 

------   java中的流程控制   -----

1,順序

2,條件(代碼是否執行,依賴於一個特定的條件)

  if(boolean express){

     XXXXXX;   //若是布爾表達式爲真就執行XXXXXX。

     XXXXXX;

 }else{

     XXXXXX;   //若是布爾表達式爲假就執行XXXXXX。

     XXXXXX;

 }

3,循環(相同的代碼,被重複的執行屢次)

      a,初始化循環條件。b,肯定循環條件。c,肯定循環變量在循環體中的變化。

 

(1)       a;    

while(boolean express){

           XXXXXXXXX;   //若是布爾表達式爲真就執行XXXXXX

           XXXXXXXXX;

                 c;

      }

(2)  for(a;b;c){

                

}

(3) do{

           XXXXXXXXXX;      //循環體至少執行一次;

           XXXXXXXXXX;

           }while(boolean express);

          

while(XXX){

      XXXXXX;

      XXXXXX;

      bread;           //或者continue;

      XXXXXX;

}

break :用在循環或分支裏,用於退出整個循環或分支

 

 

continue :用在循環裏,用於結束本次循環。接着開始下一次循環

4,分支

      switch(var[U5] ){

           case 1 : XXXXXX;

                 break;

           case 2 : xxxxxx;

                 break;

           ........

           default : xxxxxxx;    //    default後面能夠不用break;

      }

函數(方法):是由一些相關代碼組成的集合,目的是爲了解決一個特定的問題,或者實現某個特定的功能。

函數(方法)必定有一個本身的名字,經過函數的名字執行函數中的代碼。

          2,在java中如何定義函數:

a,聲明:public static void printMenu(int a,double b){.....}

b,編寫函數體:

 

如: public static void printMenu(int a,double b){

           XXXXXXXXXXX;

           XXXXXXXXXX;

      }

      函數(方法)裏面不容許再有其它的函數(方法),函數(方法)的位置必須是並列的。

      3,調用函數:

      經過函數名,如pirntMenu(a,b);

public static void main(String argv[]){

      XXXXXXXXXXXX;

      printMenu(a,b);

      XXXXXXXX;

}

調用者-原數據->函數

return 做用:1,結束本方法。2,返回結果。

一個函數返回的值只能有一個。

 

 

4,值傳遞。傳遞的是實參的值

           被調函數使用的數都是實參的拷貝

           是否改變實參,要看被調函數的設計。

 

數組:一維數組-->:三種聲明方式

一,(1)首先要聲明。如:int[] array;或int array[];

      (2)申請內存空間如:array=new int[2];

   array表明數組array[]的首地址(引用:引用就是C++裏的指針。);當參數傳遞時,只要用數組的首地址就能夠。

1,數組中的元素類型要一致。

2,數組長度不能缺省,不能改變,但能夠刪了重建。

3,內存空間連續,有索引下標值(從0開始,最大length-1)

優缺點:查詢快,增刪慢(鏈表,查詢慢,增刪快)

 

只要有new在,就要爲變量分配內存。 array.length   //表示數組array的長度。

array存的是array數組首變量的地址。

二,數組的顯示初始化:int[] array={1,2,3,4,5,6};

三,int[] array=new int[]{1,2,3,4,5,6,7};

 

數組的拷貝:

public static int[] expand(int[] a){

      int[] b=new int[a.length*2];

/* for(int i=0;i<a.length;i++){

           b[i]=a[i];

      }

這段代碼等於下面那條代碼

*/

      // 從a數組下標爲0的位置開始拷貝,到b數組下標爲0 的位置開始粘貼。

      // a.length爲粘貼的個數。(通常爲a數組的長度)。

      System.arraycopy(a,0,b,0,a.length);   

      return b;  //返回擴展後的數組b。b是表明數組b的首地址。

}

 

二維數組(數組的數組)-->:三種聲明方式

 

二維數組的第二個[]在聲明時能夠留空,如:int[][] array=new int[4][];

  //留空說明該二維數組的列是以行的數組下標爲數組名,再成爲新的數組。

 

一,聲明:int[][] array=new int[3][4]; //聲明一個三行四列的整型二維數組。

二,int[][] array={{1,2,3},{2,3,4},{2,5,7},{2,3,6}};

三,int[][] array=new int[][]{{1,2,3},{2,3,4},{2,5,7},{2,3,6}};

1,找對象(客觀存在的事物);

2,利用對象的功能。就是讓對象乾點什麼;

3,對象的屬性能夠是其餘對象。

4,對象還能夠經過調用其餘對象的函數產生聯繫。

5,簡單的對象構成複雜的系統。

 

有什麼:屬性-------》 實例變量

作什麼:方法-------》函數

  對象的屬性能夠是其餘對象

  對象還能夠經過調用其餘對象的函數產生聯繫     

  簡單的對象構成複雜的系統

 

思想:解決問題的過程,

 

總綱(優點)

1,符合人的思惟過程。

2,編寫出來的代碼比較合理。如:可擴展性,可維護性,可讀性等等。(存在就是合理),(貼近生活)

3,弱耦合性,

4,可擴展性

5,可複用性。              不要重複製造輪子。

6,更盡所能,更施其職。

 

==========類:==============

面向過程:是代碼的容器。

面向對象:對象所共有的功能和屬性進行抽像,成爲了類。客觀事物在人腦中的主觀反映。在程序裏類是建立對象的模板。  

 

java中的對象[U6] :對現實對象的抽象(得到有用的,捨棄沒用的)。

      存儲空間中的一塊數據區域,用於存數據。如:人(nama sex age)

       屬性:實例變量(定義在類之內,方法以外) 

            1.默認的初值

            2.實例變量的使用範圍至少是類之內

            3.實例變量調用必須有對象,實例變量和局部變量重名,局部優先。

              

例:

public class Test{

      public static void main(String[] args){

     

      //新建對象stu;stu存的是新建對象stu的地址。stu的專業術語:引用/對象變量/引用變量/實例變量

           Student stu=new Student();       

           stu.name="tom";       //給對象stu的name屬性賦值。

      }}

class Student{              //用類聲明的數據(str)爲引用類型,如:Student str;

 

      //實例變量:定義在方法以外,類之內的,沒有static修飾的變量

      //實例變量會有一個默認的初始值。初始值與變量定義時的類型有關。

      //實例變量(成員變量)--->屬性。可經過新建對象的引用來訪問類的實例變量。如,stu.name;

      String name;    

      int age;

      String sex;

}

實例變量和局部變量的區別

1,位置:局部變量定義在方法裏面。實例變量定義在類之內方法以外

2,使用的範圍:局部變量只能在定義他的方法裏面使用,直接調用變量名就能夠了。

      實例變量至少能夠在定義他的整個類內使用,使用時必須用對象去調用。只有跟對象一塊兒實例變量纔有意義。

3,局部變量使用以前必須初始化。實例變量不須要賦初值,系統會給默認的初值。

 

4,局部變量在同一方法裏不能重名。局部變量和實例變量能夠重名,在方法裏採用就近原則。

 

==方法:======================

包括:

      方法:

       作什麼:方法的定義 

           修飾符   返回類型   方法名(參數列表) 異常

       怎麼作:方法的實現 {******}          

修飾符(如:public)  返回類型(如:int) 方法名/函數名 (參數表--形參)         

如:

      public void eat(String fish){                //eat(),吃的功能。

           //怎麼作.

      }

使用實例方法時也須要用對象去調用。如:stu.eat("fish");

方法重載(overloading):編譯時多態。[U7] 

在一個類的內部,方法名相同形參數不一樣的方法,對返回類型不要求,這種現象稱之爲重載;

編譯器會自動選擇使用的方法。體現了一個編譯時多態。

好處:對使用者屏蔽由於參數不一樣形成方法間的差別。

找方法時若是沒有合適的,採起自動向上擴展原則。

調用時形參之間的區別必定要明確。

    1. 形參的個數不一樣

    2. 形參的類型不一樣

    3. 形參的順序不一樣

    4. 形參的名字相同

 

方法覆蓋(override):運行時多態。

1,發生在父類和子類之間

2,方法名相同,參數相同,返回類型相同

3,子類方法的訪問權限不能更嚴格,只能等於或更加寬鬆。

 

構造方法:

1,沒有返回類型,方法名必須和類同名。

2,構造方法不能手動調用,它只用在建立對象在時候,只出如今new以後。

      只要構造方法被調用運行,就必定有對象產生。

3,在一個對象的生命週期裏,構造方法只能被調用一次。

4,類寫好後必定有構造方法,

      若是程序沒有顯示的提供構造方法,JVM會提供一個默認的構造方法,public classname(){}

      若是程序顯示提供,系統再也不提供默認的

5,同一個類的多個構造方法必定重載。

6,建立對象的同時構造方法的代碼塊裏還能夠寫須要運行的代碼,還能夠給屬性(實例變量)賦值,

      引用類型的屬性賦值就是用new建立對象,而後調用構造方法。如:Student stu=new Student();

用new建立對象時JVM作的三件事:

如:Student stu=new Student();

1,申請空間;(把值放到空間裏,再把空間的地址給引用變量。)----建立父類對象

2,初始化實例變量;沒顯示聲明值的話就用默認值。

3,執行構造方法,

由於實例變量在建立對象的過程當中被初始化,因此使用實例變量前必須建立對象(要用對象去調用),不然實例變量根本不存在

 

=====關鍵字:this=======

1,在普通方法裏,指代當前對象引用(哪一個對象調用該方法,this就指向該對象)

2,this不能出如今靜態方法裏。

3,在構造方法裏,this用來指代本類的其餘構造方法。在本類構造方法之間互相調用。如:this(形參);

      使用時放在構造方法裏的第一行。

4,不能寫成死循環(不能遞歸調用)

=====關鍵字:super=======

(和this的用法相似)

1,調用父類的構造方法,在子類調用父類的構造方法必須出如今第一句,構造方法第一句可能出現的三種狀況(調用父類的構造方法看子類構造方法的第一句)①super();②super(參數)注意傳遞的參數必定是實體,有值的。③this(),先在本類的構造方法間調用,再看調用那個構造方法的第一句是什麼

2,super訪問父類的變量和方法,及super表明父類的對象,super.name;super.setName();

======參數傳遞========

1,參數至關於局部變量

2,參數傳遞至關於賦值語句

3,基本類型數據傳遞的是自己的值,引用類型數據傳遞的是引用xx(Animal animal)(地址,對象變量自己的值)

 

面向對象的三大特性:

 

一,封裝(Encapsulation):一個系統以合理的粒度出現。

定義:封裝就是將客戶端不該看到的信息包裹起來。使內部執行對外部來看不一種不透明的、是一個黑箱,客戶端不須要內部資源就能達到他的目的。(封裝是把過程和數據包圍起來,對數據的訪問只能經過已定義的界面。面向對象計算始於這個基本概

念,即現實世界能夠被描繪成一系列徹底自治、封裝的對象,這些對象經過一個受保護的接口訪問其餘對象。)
1.事物的內部實現細節隱藏起來
2.對外提供一致的公共的接口――間接訪問隱藏數據         3.可維護性  

訪問控制修飾符:public(公開的),protected(受保護的,1,本包內可見;2,其餘包的子類可見)

                       default(默認,本包內可見),private(私有的,類內部可見)

訪問控制修飾符   (能夠範圍)          (可修飾)下面的類(指外部類)

      private         本類            方法,屬性

      default         本包            類,方法,屬性

      protected     本包+子類                方法,屬性

      public         處處可見          類,方法,屬性

 

1,屬性:隱藏全部屬性,用private。隱藏後屬性只能在類之內訪問 。程序能夠根據須要提供get和set

2,方法(函數):該公開的公開,該私有的就私有。(視狀況而定)

3,公開方法的功能,隱藏方法的實現細節。

 

二,繼承(inheritance):抽象出不變性。

從通常到特殊的關係,能夠設計成繼承

   特色:共性寫在父類裏面,特性寫在子類

全部類的總父類是 Object (Object是類的祖先)

父類裏寫的是共性,子類裏寫的是特性。

父類中用private修飾的屬性和方法不能被子類繼承;

可是父類裏的屬性子類都有,若是子類有特殊屬性的話,就要在子類裏定義

且在建立該子類對象的時候初始化屬性(包括父類全部屬性和該子類全部屬性);

 

什麼樣的功能和屬性能夠繼承到子類?

對於父類裏的屬性和方法,子類有權訪問的,咱們稱爲能夠繼承;

 

用new建立子類對象,JVM執行的過程:Dog d=new Dog(); 爲d申請空間。 class Dog extends Animal{}   

(1)申請空間;(把值放到空間裏,再把空間的地址給引用變量。)

(2)看本類構造方法的第一句

(3)默認的建立父類對象:

      執行順序:子類(2)--->  父類(2-->3-->4-->5)--->   子類(4-->5),

      新建一個對象空間只申請一次(該空間存放全部父類和子類)。)

(4)初始化本類的實例變量(該類的全部屬性);

(5)執行本類的構造方法,(構造方法只會在建立一個對象的時候被執行一次)

 

(建立是先執行父類的構造方法,在執行子類的構造方法,訪問時先訪問子類本身的特殊屬性和方法再訪問父類的屬性和方法)

用super調用父類被子類覆蓋的普通方法和遮蓋的屬性,

指代的是在建立子類對象過程當中,由JVM自動建立的那個父類,如:super.方法名()/屬性

用super調用父類的構造方法;必須出如今子類構造方法的第一句。如:super(形參);

1,在子類的構造方法裏若是沒有指明調用哪個父類的構造方法(就是子類中沒有super(形參)語句;),

      JVM會默認調用父類的無參構造方法,跟本類構造方法的形參沒有關係。

2,顯示的寫super,JVM會根據參數調用相應的父類構造方法。

3,有this(形參),在本類的構造方法之間調用,看被調用的那個構造方法的第一行。

 

 

 

 

三,多態[U8] (polymorphism):多態只有方法多態,沒有屬性多態。

用父類類型屏蔽子類之間的差別

 

全部的子類對象均可以當父類對象來用,一個父類型的引用可能指向的是一個子類對象,

如:把狗(對象)看做動物(類型)。Animal a=new Dog();               編譯看前面,運行看後面。

                            (編譯時類型)   (運行時類型)

1,運行時對象不會改變(對象是客觀存在的),如:狗這個對象的屬性和方法是不會改變的。

2,對一個引用,只能調用編譯時類型裏的已知方法。

      如:編譯器知道動物裏已有的屬性和方法,但不知道狗的屬性和方法。

3,運行時會根據運行時類型自動尋找覆蓋過的方法運行。

 

引用  instanceof 類名       //結果爲boolean值,

引用所指向的對象和類名類型是否一致(對象是否屬於類名類型)

類型的轉換:轉換編譯時類型

   Sub  su= (Sub) s;

   子類型的引用向父類型轉換時,不須要強轉

   父類型的引用向子類型轉換時,須要強轉                                                    

     Animal a=new Cat();

     Dog d=(Dog)a;      // 類型轉換異常

     引用  instanceof  類名 -----> boolean

     引用所指向的對象和類名所表明的類型是否一致  

     a instanceof Animal ----->  true      a instanceof Cat---------->  true    a instanceof Dog----------->false

     Employee e=new Manager();

     e instanceof Employee ------>true

     e instanceof Manager------> true     

    

 屬性沒有多態,屬性只看編譯時類型

   

編寫程序的順序:

class 類名{

      private屬性(有什麼)

      無參的構造方法(public類名(){})

      有參的構造方法(做用:給屬性賦值)

      set和get(設置和得到屬性)

      業務方法(作什麼)

 

一,修飾符:static [U9] 

      static變量:如:static int index=2;

           類的全部對象共同擁有的一個屬性;能夠用類名直接訪問,又稱爲類變量,

           類的全部對象共同擁有的一個變量;類第一次被加載時會初始化靜態變量

(也就是會先執行static修飾的變量);

           跟類建立了多少對象無關;任何對象對靜態變量作的修改,其餘對象看到的是修改後的值。

            能夠用做計數器,記錄類建立對象的個數 , static變量在類加載的時候只會被初始化一次

      static方法:如:public static void teach(){}

           能夠用類名直接去調用,不須要對象因此不能直接訪問(在沒有對象的狀況下)實例變量,

在靜態方法裏不能出現this和super,類的全部對象共同擁有的一個方法;跟類建立了多少對象無關。

           在繼承裏,父類的靜態方法只能被子類的靜態方法覆蓋,且覆蓋之後沒有多態

(訪問的是父類的靜態方法);

      static初始化塊:如:class Teacher(){

                                  static int index=4;

                                  static{          //static初始化塊

                                       .........

                                       }

                                  }

      靜態初始華塊:用static修飾類裏面的一個獨立的代碼塊,類第一次被JVM加載的時候執行,只被執行一次

      類加載:JVM在第一次使用一個類時,會到classpath所指定的路徑去找這個類所對應的字節碼文件,

           並讀進JVM保存起來,這個過程稱之爲類加載,一個線程一個jvm

     

二,final  (最後的,最終的)final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承

      final類:如:final class Animal{}

           表示該類不能被繼承,意味着不能改變裏面的代碼;

           對虛擬機的正常運行有重要做用的類一般用final修飾,如:String,System,Math ...等類

      final方法:如:public final void sleep(){}       該方法不能被覆蓋(修改),但能被子類訪問。

                     

     

      final變量:如:final (static) int index=4;

                      該變量是常量能被繼承(訪問);

                      final修飾的變量就是常量,一般和static一塊兒連用,來聲明常量;

                      final修飾引用類型數據,指的是引用(地址)不能變,但引用裏的數據不受限制。

                      final修飾的變量,只要在初始化的過程當中就能夠賦值。

 

                      實例變量:聲明的同時或構造方法裏賦值;

                      靜態變量:聲明的同時或在靜態代碼塊裏賦值;

 

三,abstract

      abstract類:如:abstract class Animal{}

                      抽象類,不能建立對象(如一些父類),可是能夠聲明一個抽象類型的引用

                      (能夠聲明父類類型子類對象,編譯時利用多態調用抽象方法)。

                      含有抽象方法的類必定是抽象類,但抽象類並不必定要有抽象方法;

                      抽象類通常是用來被繼承的;子類繼承自抽象類,就要實現裏面的抽象方法,

                      若是不想讓子類也是抽象類的話,必須實現父類裏面全部的抽象方法。

                      抽象類有構造方法,有父類,也遵循單繼承的規律。

     

      abstract方法:如:public abstract void sleep();

           抽象方法,只有方法名的定義,沒有實現體(只定義了能作什麼,沒定義怎麼作),不能被調用,

                      用於被子類的方法覆蓋或從新實現。只能放在抽象類中。

                      好處:容許方法的定義和實現分開。

                      public  protected  default  private  static final  abstract

                   能夠: public static

                           private static

                          public final

                          public static final

                 不能夠:abstract final void eat(); 

                 private abstract void eat();

                 static abstract void eat();

            abstract不能和final,private,static連用。

 

四,interface:是抽象類的變體,。在接口中,全部方法都是抽象的。如:interface M{

                                       int num=3;

                                       void eat();

                                  }

      理解爲接口是一個特殊的抽象類,因此接口不能建立對象,且接口沒有構造方法,

      但能夠聲明一個接口類型的引用(m是接口類型實現類對象,如:M m=new N();)

      接口存在的意義是被子類實現,若是不想讓子類也抽象,

      就要實現接口裏面全部的抽象方法,實現過程當中注意訪問權限;

 

      用  implements 關鍵字實現接口,如:class N implements M{

                                                  public void eat(){...}

                                                }

      接口裏面的常量默認都是public static final的;

      接口裏面的方法默認都是public abstract的。

     

      接口自己支持多繼承,繼承了父接口裏功能的定義,如,interface A extends B,C,D{}        //A,B,C,D都是接口;

      類能夠同時繼承一個父類和實現接口(或多個接口)。

      如:class AA extends BB implements CC,DD,EE{}//AA,BB      是類,CC,DD,EE是接口;

      做用:1,用接口去實現多繼承,接口是對類的共性進行再次抽象,抽象出類的次要類型。

                 如:蜘蛛俠,擁有人和蜘蛛的屬性,但主要類型是人,次要類型(接口)是蜘蛛,

                 由於接口是次要類型,因此在類關係裏不佔一個節點,不會破壞類層次關係的樹狀結構,

             2,標準(保證弱耦合):一個接口就是一個標準(裏面的屬性不能改變,只定義了功能,

但沒有被實現),  接口將標準的制定者,標準的實現者以及標準的使用者分離開,

                 下降實現者和使用者的耦合。接口是java裏一種重要的下降耦合的工具;

接口能夠屏蔽不一樣實現類的差別,

                 當底層的實現類更換後,不會對上層的使用者產生影響,體如今參數和返回值。  

                

                 寫程序時,應該先寫實現者再寫使用者,如:Bank.java是實現者,View.java是使用者,

                 可是有了接口以後,就能夠用接口回調的功能;

                 接口回調:先定義接口,而後寫使用者和實現者的順序隨便(通常是先寫使用者,

後寫實現者);利用參數把實現者傳給使用者(即:實現者是使用者的屬性),

使用者利用接口調用實現者相應的功能。

       **接口和抽象類的區別 1一個類能夠implements多個接口,而只能extends一個抽象類

                       2,一個抽象類能夠實現部分的方法,而接口都是抽象的方法和屬性

 

Object是Java裏全部類的直接或間接父類,Object類裏面的全部功能是全部java類共有的

1,JVM調用垃圾回收器回收不用的內存(沒有引用指向的對象)前運行finalize(),給JVM用的方法。

      程序顯示的通知JVM回收沒用的內存(但不必定立刻就回收):System.gc();或    Runtime.getRuntime().gc();

 

2,toString()返回對象的字符串表現形式,打印對象時,虛擬機會自動調用toString獲取對象的字符串表現格式,

      如:System.out.println(str.toString());      ==System.out.println(str);

      若是本類不提供(覆蓋)toString(),那麼使用的是Object類裏的相應方法,打印的就是地址。

      如:public String toString(){

                 return ".....";

           }

          

3,基本類型時「==「判斷變量自己的值是否相等;引用類型時,判斷的是地址是否相等。

      equals判斷的是對象內容是否相等。對於本身建立的類,應該覆蓋Object類的equals()方法;

      不然使用的是Object類裏的equals()方法,比的是地址。

     

      覆蓋方法以下:

      /*****************************************************

      public boolean equals(Object o){ 

        if(o==null)  return false;

        if(o==this)  return true;

        if(!(o.getClass()==this.getClass())) return false;

        final Student s=(Student)o;

        return this.name.equals(s.name) && this.age==s.age ;  //比較原則;

      } 

    ******************************************************/

      覆蓋euqals()方法時遵循的原則:

      自反性:a.quals(a);         //true

      對稱性:a.equals(b);<==> b.equals(a);      //true

      傳遞性:a.equals(b);//true         b.equals(c); //true

           --->則:a.equals(c);  //爲true               

     

封裝類(Wrapper class)[U10] 

OverLoading時,基本類型時採用向上匹配原則,

若是沒有基本類型的話就向包裝類轉換,若是尚未就讓這個基本類型在包裝類裏也採用向上匹配原則;

 

基本類型-轉換到-->包裝類

boolean----->Boolean

int-------->Integer      //Integer是引用類型,

int-------->Ddouble           //合法,         但Integer------>Double    非法

double------>Double

   ......  ------->   ......

任何類型----->Object

基本數據類型int能夠向double自動擴展,可是包裝類型之間不能自動的相互轉換,

基本類型數據--->包裝類型

int i=3;

Integer it=new Integer(i);        //手動轉換;基本類型向包裝類型轉換。

int <----> Integer <----> String

轉換時String類型必須爲全數字字符串。如:"2515"    不能爲:"abc265","aec"...等

String str=」123」; int it=Integer,parseInt(str);把字符串轉換成數字。String str2=it+「」;把數字轉化成字符串

 

=內部類============

定義在其餘代碼塊(類體或者方法體)裏的類稱爲內部類;

編譯後每個內部類都會有本身的獨立的字節碼文件,

文件名:Outer$Inner.class-->內部類也能夠有父類和實現接口。也能夠有抽象方法

 

根本位置和修飾符的不一樣分爲四種:

1,member inner class       成員內部類,當實例方法或變量同樣理解。

      1)定義的位置:類之內,方法以外,沒有靜態修飾符(static)。

      2)自己能定義的屬性和方法:只能定義非靜態的屬性和方法。

      3)能直接訪問的什麼:能訪問外部類的全部靜態和非靜態的屬性或方法。

      4)怎麼建立對象:在外部類內的方法內:Outer.Inner inner=new Outer().new Inner();

            在外部類外的類的方法內:Outer.Inner inner=new Outer().new Inner();或

在Outer類裏提供一個getInner()方法,返回內部類的對象,這樣在外部類外的類的方法內也能夠用該成員內部類。

     

2,static inner class 靜態內部類(嵌套內部類),當靜態方法或變量同樣理解。

      static只能修飾內部類,不能修飾外部類。

      1)定義的位置:類之內,方法以外,有靜態修飾符(static)。通常寫在外部類的屬性下面。

      2)自己能定義的屬性和方法:能夠定義靜態和非靜態的屬性或方法。

      3)能直接訪問的什麼:只能訪問外部類的靜態屬性和方法。

      4)怎麼建立對象:在外部類內的方法裏: Outer.Inner inner=new Outer.Inner();

                                 在外部類外的類方法裏:   Outer.Inner inner=new Outer.Inner();

3,local inner class        局部內部類           當局部變量同樣理解。

      1)定義的位置:方法裏面的類,前面不能用public或static修飾。

      2)自己能定義的屬性和方法:只能定義非靜態的屬性和方法。

      3)能直接訪問的什麼:能訪問方法內用final修飾的局部變量(不能與該類內的變量名相同)。

                                       能訪問外部類的全部靜態和非靜態的屬性或方法。

      4)怎麼建立對象:只能在方法內建立對象,如:Inner inner=new Inner(); 對象的做用範圍只在方法內。

4,annonymous inner class         匿名內部類                       如:  Teacher tc=new Teacher(){

      1)沒有名字的類,沒有構造方法。是一個特殊的局部內部類,                 public void teach(){...}

             能夠實現一個接口,   或者一個類,                                           }

             生命週期裏只能產生一個對象(tc),也就是說只能被一個對象(tc)調用,

      2)除了沒有名字外,看匿名內部類所在的位置,他的定義和訪問將和成員內部類、靜態內部類、局部內部類同樣。

                 通常像局部內部類的定義和訪問比較多。

      3)當試圖建立接口或者抽象類對象的時候,用匿名內部類。

           表示類體的{...}緊跟在抽象實例(接口)以後,表示實現該抽象實例(接口)。

           調用匿名內部類的方法只能用寫類時建立的那個對象(tc)。

做用:1,不破壞訪問權限的狀況下,內部類能夠使用外部類的私有成員變量和方法。

           2,將接口公開,將實現類(實現公開的接口)做成內部類隱藏起來,強制要求使用者使用接口,強制下降偶合度。

        3,Java經過接口和內部類兩種機制來實現多繼承。在類內部能夠創建本類的實例,而後調用本類內的其餘方法。

Exception(異常):運行時的概念。

1,Throwable:運行時可能碰到的任何問題的總稱;

      1)Error:指很是嚴重的錯誤,系統不要求程序員處理,也處理不了。如:硬件壞了.....等。

      2)Exception:從代碼的角度是程序員能夠處理的問題;

      UncheckedException(RuntimeException 的子類) (未檢查異常)若是是RuntimeException(或子類)就是爲檢查異常,其餘就是已檢查異常

           程序員當心謹慎徹底能夠避免的異常,系統不要求程序員處理(能夠無論,運行會提示錯誤),

           如:3/0          數組下標越界。

      CheckedExcepiton   (已檢查異常)

           系統要求必須處理異常。

2,異常處理:異常是相對於方法來講的

      1)聲明拋出異常(消極的處理)

           throws(拋棄):寫在方法名的定義上,後面跟要拋棄的異常類型。

           如:public void m1() throws Exception{.}

異常產生時,責任可能並不在當前方法,向外拋棄(把異常拋棄,留給調用者處理)可讓異常找到一個最佳的位置處理

           拋棄過程當中能夠對異常類型進行擴展,可是不能縮小。

           throw(拋出):通常出如今方法實現裏,用來拋出異常對象(或者是產生異常),

           如:throw new FileNotFoundException();

           當代碼出現異常時,代碼不會向下執行,JVM會將異常封裝成相應的異常類的對象,

           而後向外拋出。以後這個方法裏剩下的代碼就不會再執行了。

      對於一個方法的返回值:

           1)正常運行時,要求方法必須返回定義的類型的值。

           2)若是運行不正常(出現異常),方法返回的是異常對象

      方法覆蓋:名相同,參數相同,返回類型相同,訪問權限不能更小,子類拋棄的異常不能比父類更多。

2)try....catch(積極的處理):

           一個try語句後能夠跟多個catch語句;catch時異常子類放上面,異常父類放下面。

           若是沒有父子關係,前後無所謂;

      ---方法---( ){

            try{

                 //可能會出現異常的代碼

                 xxxxxxxxxx;      (1)

                 xxxxxxxxxx;      (2)

           }catch(Exception1 e1){

                 //當try代碼塊出現異常時,執行catch代碼塊。

                 xxxxxxxxx; (3)

           }catch(Exception2 e2){

                 xxxxxxxxx; (4)

           }finally{

                 //無論有沒有異常出現都要執行的代碼。

                 xxxxxxxxx; (5)

           }

                 xxxxxxxxx; (6)

      }

1)若是(1),(2)沒產生異常,(2)執行後直接執行(5),而後執行(6)。

2)若是(1)產生異常,(2)不會被執行,直接跑出try{..},匹配catch,和catch裏定義的類型一致,

執行catch完了後,直接跳到(5)執行,最後再執行(6),若是異常類型都不一致,將導至語法問題。

3)自定義異常類型(業務異常):

           如:class MyException extends Exception{

                      public MyException(String str);

                      super(str);

                 }

Exception異常總結:

一、若是程序用了System.exit(0);則不會執行finally裏的程序

二、在程序return前執行finally裏的程序

三、Java中異常分爲兩類:

1) checked Exception

處理方式1、繼續拋出,消極作法,直到拋出到JVM

處理方式2、用try..catch

2) unchecked Exception (runtime exception)

throws ArithmeticException,IOException應該是出現這兩種異常就向上拋吧。
什麼狀況下一個方法拋出幾個異常?通常來講應該是會拋出幾種異常,而後在一級調用這個方法時處理一下。
若是沒有特殊須要的話要把可能出現的異常都截獲並處理。
try{
  method();
}catch(exception1 e1){
 do something;
}catch(exception2 e2){
 do something;
}……
e1的範圍小於e2.

 

課外考題:12、final, finally, finalize 的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

finally 是異常處理語句結構的一部分,表示老是執行。

finalize 是Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋

此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。

 

Java高級部分=============================================

集合,經常使用的接口,Collection,List Set,SortedSet,Map,SortedMap

用來管理/容納多個對象的對象(或稱爲容器);

面向對象可重用性的體現,對數組做了功能封裝。

Collection是一個接口:是以對象爲單位來管理元素的。

      基本操做:add  remove  size

      遍歷:迭代遍歷

有兩個子接口:List接口和Set接口

1,List接口:元素是有順序(下標),能夠重複。有點像數組。能夠用迭代器(Iterator)和數組遍歷集合。

      List接口裏自己有本身的方法,還有從父接口Collection裏繼承的方法。

      remove(int)刪除某一位置的對象、add(int,Object)往某一位置插入對象 、get(int)查詢某一位置上的元素。

      遍歷:迭代遍歷、for遍歷

      Collections.sort(list); 引入list集合而後對list集合裏的對象(如:Student類)進行排序時,

      只要在讓對象(類)實現Comparable接口,再覆蓋接口裏面的方法(compareTo()方法),

      在compareTo()方法裏寫出進行什麼樣的方式排序,

      Public int compareTo(Object o){

         Work w=(Work)o;

       If(this.salary!=w.salary){return (int)w.salary-(int)this.salary;}

       Else If(this.age!=w.age){return w.age-this.age;}else  retuen this.name.compareTo(w.name);sss

}

      而後在主函數裏使用Collections.sort(list);  ,就對list裏的對象進行排序了,

      而不用管Collections.sort()方法是怎麼實現的,既不用管Collections.sort()方法的實現體。

      排序規則:對象實現Comparable接口,覆蓋compareTo()方法,Collections.sort(List);

     

1)ArrayList[U11] 集合類實現List接口,輕量級,底層是以數組實現的,查詢快,增刪慢,線程不安全,用get(int)方法多時,

 Vector集合也實現List接口,底層也是以數組實現的。但這個類已經放棄了。重量級,查詢慢,增刪快,線程安全。(Vector和HashTable是線程同步的(synchronized),因此線程安全。性能上,ArrayList和HashMap分別比Vector和Hashtable要好。)

2)LinkedList集合類實現List接口,他底層是以鏈表實現的,查詢慢,增刪快,

           用remove(int)、add(int,Object)方法多時,

           本身實現棧(stack),並對棧裏進行增刪操做。

           class MyStack{

                 private LinkedList list=new LinkedList();

                 public void push(Object o){

                      list.addFirst(o);

                 }

                 public void pop(Object o){

                      list.removeFirst();}}

2,Set接口無順序,不能夠重複(內容不重複,而非地址不重複)。只能用迭代器(Iterator)遍歷集合。

      Set接口裏自己無方法,方法都是從父接口Collection裏繼承的,

      遍歷:迭代遍歷

      實現類:保證元素內容不重複。

1)HashSet集合類實現Set接口,底層是以數組實現的。HashSet集合裏不容許有重複對象

      每向HashSet集合類裏添加一個對象時,先使用HashSet集合類裏add(o)方法,

      再調用對象o的hashCode()方法算出哈稀碼,保證相同對象返回相同的哈希碼。

      若是哈稀碼同樣,再調用對象o裏的equals()方法對對象的屬性進行比較是否相等,

集合也能夠構造集合,如:List<Object> list=new ArrayList<Object>(); Set<Object> set=new HashSet<Object>(list);原來在list集合裏的對象是能夠重複的,但被set集合構造以後,重複的對象將被去掉

按這三種順序來理解接口:    1)接口特色;2)接口常見操做(方法);3)接口實現類的特色

Map:對應一個鍵對象和一個值對象,能夠根據key找value,

      (Key--value)不可重複且無序--可重複

      排序(SortedMap是Map的子接口):TreeMap類實現SortedMap接口;對集合進行排序。

      基本操做:put()  get()

      遍歷:鍵遍歷  ketSet()返回鍵的集合(Set)(說明map的鍵是用set實現的,不能重複)

              值遍歷 values() 返回值的集合。

      HashMap類實現Map接口:     查詢快,線程不安全,容許鍵和值對象爲null

      Hashtable類實現Map接口:查詢慢,線程安全

      TreeMap類實現Map接口:SortedMap的實現類,自動對鍵進行排序。

 

 

Iterator 實例

Static void printValue(Map map){

  Collection col=map.values();

Iterator it=col.iterator();

  While(it.hasNext()){

Object obj=it.next();…;

}}

 

 

 

Jdk1.5新特性加了forEach循環方便數組和集合的遍歷(是在泛型的基礎上提出的)

Static void printValue(Map<Integer Product> map){

  Set<Integer> s=map.ketSet();

For(Integer i:s){xxxx}

}

注意:若是須要定位,就得用「普通」的 for,在列表遍歷期間沒法刪除集合對象。

 

 

課外考題、Collection 和 Collections 的區別。

Collection 是集合類的上級接口,繼承與他的接口主要有Set 和List.

Collections 是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線

程安全化等操做

 

 

=======圖形界面(GUI)==================================================

1,選擇容器:圖形界面容器,容器也是一個對象(至關一個圖形界面),用來裝組件的。

JFrame:窗口,至關於一個容器;如一些按鈕,最大化,最小化等一些。默認的佈局管理器是BorderLayout

      JPanel:面版,透明的。默認佈局是FlowLayout, 通常放在窗口裏

      javax.swing.*;存在於該包中。

2,設置佈局管理器

      FlowLayout(): 流式佈局。組件會隨着容器的大小而改變位置,

      BorderLayout():東西南北中分佈組件

      GridLayout():網格佈局。一個格只能放一個組件,

      CardLayout():卡片佈局。如按上一步和下一步。界面是一個卡片式的佈局。

      GridBagLayout():複雜的網格佈局,一個格能夠放多個組件。

      java.awt.*;存在於該包中。

      setLayout():用於設置什麼樣的佈局。

3,添加組件:一個組件就是一個對象,

      JTextField :單行文本框

      JTextArea :多行文本區

      JComboBox:下拉列表

      JScrollPane:左右拉或上下拉按鈕

4,設置事件監聽

AWT事件模型,事件三要素:事件對象,事件源,事件監聽器

1,事件對象:事件也是一個對象。事件對象繼承:java.util.EventObjct類

2,事件源:發生事件的對象,也是報告事件的對象。(點擊b1按鈕,那麼b1按鈕就是事件源)

3,事件監聽器:處理事件的對象。 監聽器接口必須繼承java.util.EventListener接口。

      事件源預先就某種事件註冊監聽器,當事件發生時,事件源就給全部註冊的監聽器發送一個事件對象,

      全部監聽器存在一個數組集合裏(如ArrayList集合),由監聽器作出相應處理。

      事件源能夠同時是多種事件的事件源,就某種事件單獨註冊監聽器。

      事件源就同一種事件,能夠註冊多個監聽器。

      一個監聽器能夠同時註冊在多個事件源當中。

      事件對象中會封裝事件源對象。

      事件監聽接口中的每個方法,都應以對應的事件對象做爲參數類型。

      所謂的事件源給監聽器發送事件對象,其實就是事件源以事件對象爲參數,調用監聽器的方法。

      getSource()方法:是事件對象(EventObject)裏的一個方法,用事件對象e調用(如:e.getSource(); )

           getSource()方法返回的是事件對象裏的事件源

 

 

=======多線程=======================================================

線程:進程中併發的一個順序執行流程。

併發原理:CPU分配時間片,多線程交替運行。宏觀並行,微觀串行。

Tread t=new Thread();表示新建一個線程對象,並不表示線程。

      當調用t.start();才起動線程,當獲得CPU時,就會執行線程t的方法體。

線程三要素:CPU、Date、Code

多線程間堆空間共享,棧空間獨立。堆存的是地址,棧存的是變量(如:局部變量)

建立線程兩種方式:繼承Thread類或實現Runnable接口。

Thread對象表明一個線程。

多線程共同訪問的同一個對象(臨界資源),若是破壞了不可分割的操做(原子操做),就會形成數據不一致的狀況。

在java中,任何對象都有一個互斥鎖標記,用來分配給線程。

synchronized(o){..同步代碼塊. .}

對o(o是臨界資源)加鎖的同步代碼塊,只有拿到o的鎖標記的線程,

           才能進入對o加鎖的同步代碼塊,退出同步代碼塊時,會自動釋放o的鎖標記。

synchronized的同步方法,如:public synchronized void fn(){} 對訪問該方法的當前對象(this)加鎖;哪一個線程能拿到該對象(臨界資源)的鎖,哪一個線程就能調用該對象(臨界資源)的同步方法。

一個線程,能夠同時擁有多個對象的鎖標記

在java中,任何對象都有一個鎖池,用來存放等待該對象鎖標記的線程,

           線程阻塞在對象鎖池中時,不會釋放其所擁有的其它對象的鎖標記。

在java中,任何對象都有一個等待隊列,用來存放線程,

線程t1對(讓)o調用wait方法,必須放在對o加鎖的同步代碼塊中!

      1.t1會釋放其所擁有的全部鎖標記;

      2.t1會進入o的等待隊列

t2對(讓)o調用notify/notifyAll方法,也必須放在對o加鎖的同步代碼塊中!

      會從o的等待隊列中釋放一個/所有線程,對t2毫無影響,t2繼續執行。

當一個現成對象調用yield()方法時會立刻交出執行權,回到可運行狀態,等待OS 的再次調用

線程的生命週期

下面爲線程中的7中很是重要的狀態:(有的書上也只有認爲前五種狀態:而將「鎖池」和「等待池」都當作

是「阻塞」狀態的特殊狀況:這種認識也是正確的,可是將「鎖池」和「等待池」單獨分離出來有利於對程序的理解)

1,初始狀態,線程建立,線程對象調用start()方法。

2,可運行狀態,也就是等待Cpu資源,等待運行的狀態。

3,運行狀態,得到了cpu資源,正在運行狀態。

4,阻塞狀態,也就是讓出cpu資源,進入一種等待狀態,並且不是可運行狀態,有三種狀況會進入阻塞狀態。

1)如等待輸入(輸入設備進行處理,而CPU不處理),則放入阻塞,直到輸入完畢,阻塞結束後會進入可運行狀態。

2)線程休眠,線程對象調用sleep()方法,阻塞結束後會進入可運行狀態。

3)線程對象2調用線程對象1的join()方法,那麼線程對象2進入阻塞狀態,直到線程對象1停止。

5,停止狀態,也就是執行結束。

6,鎖池狀態

7,等待隊列

 

課外問題:7一、簡述synchronized 和java.util.concurrent.locks.Lock 的異同 ?

主要相同點:Lock 能完成synchronized 所實現的全部功能

主要不一樣點:Lock 有比synchronized 更精確的線程語義和更好的性能。synchronized 會自動釋放鎖,

而Lock 必定要求程序員手工釋放,而且必須在finally 從句中釋放。

=======I/O==========================================================================

File:表明了磁盤上的文件或者目錄

I/O:jvm和外部數據源的數據交換。File,db—in-àjvm---out-àfile,db

流一共有三種分類:

方向分:輸入流和輸出流;

單位分:字節流和字符流;

      字節流:

           InputStream/OutputStream 字節流的父接口

(1)FileInputStream/FileOutputStream  文件字節流     ((能夠向下轉換))

           DataInputStream/DataOutputStream  讀寫8種基本類型和以UTF-8讀寫String

           BufferedInputStream/BufferedOutputStream  帶緩衝的輸入/出流

           PrintStream 融合Data和Buffered,  System.out所屬的類

           Piped 管道 用於線程間交換數據

           RandomAccessFile 隨機訪問文件

      字符流:處理字符編碼問題

           Reader/Writer 字符流的父接口

           FileReader/FileWriter 文件字符流,和FileInputStream/FileOutputStream  文件流,

((能夠向下轉換)) 與上面的(1)是相等,

           只不過一個是字節流,下面是字符流,因此兩個沒法相傳

InputStreamReader/OutputStreamWriter 橋轉換 將字節流轉成字符流 在橋轉換的過程當中,能夠制定編解碼方式

           BufferedReader/PrintWriter  有緩衝

      字符流轉換爲字節流時,指定編解碼方式是在橋轉換時指定的。

功能分:節點流和過濾流;

      節點流:用於傳輸數據。

      過濾流:幫助節點流更好的傳輸數據。

      piped(管道節點流):用於兩個線程間傳輸數據。一個線程的輸出,是另外一個線程的輸入。

對象序列化:

      把對象放在流上傳輸ObjectInputStream/ObjectOutputStream

      只有實現了Serializable接口的對象才能序列化

用transient修飾的屬性,爲臨時屬性,不參與序列化,只能修飾對象的屬性。

     

===================網絡=====================================================

1 網絡通訊的本質是進程間通訊。   

2 Tcp協議和UDP協議
TCP:開銷大,用於可靠性要求高的場合。
TCP的過程至關於打電話的過程
UDP:用在對實時性要求比較高的場合。
UDP的過程至關於寫信的過程。

注意:socket是套接字,ip和port(端口號 0~65535個端口,一個端口只能有一個進程)

3,  TCP通訊機制,tcp是面向鏈接的,實現多線程的方法有三個

① 爲每一個客戶分配一個工做線程。

②  建立一個線程池,由其中的工做線程來爲客戶服務。

③  利用JDK的Java類庫中現成的線程池,由它的工做線程來爲客戶服務。

下面覺得每一個客戶分配一個工做線程來實現多線程

 

在服務端

import java.net.*;

import java.io.*;

public class TCPServer2 {

   public static void main(String[] args) throws Exception{

      ServerSocket ss=new ServerSocket(9000);//端口號

      while(true){

           Socket s=ss.accept();//鏈接監聽客戶端

           System.out.println(s.getInetAddress());

           Thread t=new ServerThread(s);//實現多線程鏈接

           t.start();

      }

   }

}

class ServerThread extends Thread{//分配線程

   Socket s;

   public ServerThread(Socket s){

      this.s=s;

   }

public void run(){

   try {

      OutputStream os=s.getOutputStream();//在網絡中獲取輸出流

      PrintWriter out=new PrintWriter(os);

      for(int i=1;i<=30;i++){

      out.println("Hello "+i);//經過網絡發消息給客戶端

      out.flush();

      Thread.sleep(1000);

           }

      } catch (Exception e) {

           e.printStackTrace();

      }

      finally{

           try {

                 s.close();//注意關閉線程而不關閉流

           } catch (IOException e) {

                 e.printStackTrace();

           }

      }

   }

}

在客戶端

import java.net.*;

import java.io.*;

public class TCPClient {

   public static void main(String[] args) throws Exception{

Socket s=new Socket("192.168.0.10",9000);//鏈接服務端的ip和端口

      InputStream is=s.getInputStream();//得到輸入流,讀取服務端發來的信息

      InputStreamReader ir=new InputStreamReader(is);

      BufferedReader in=new BufferedReader(ir);

      for(int i=1;i<=30;i++){

           System.out.println(in.readLine());

      }

      s.close();

   }

}

 

 

4,  Udp 面向無鏈接,不可靠,效率高,資源佔用少 ,先從客戶端發起通訊,讓服務端知道其地址等信息,不一樣的協議其端口號的含義也不同

 

例子:

在客戶端

import java.net.*;

public class UDPClient {

public static void main(String[] args) throws Exception{

DatagramSocket ds=new DatagramSocket();註冊郵箱

String text1="I am here!";

byte[] bs1=text1.getBytes();//轉換成字節用來傳輸

DatagramPacket letter1=new DatagramPacket(

bs1,0,bs1.length,InetAddress.getLocalHost(),9000);

//寫好信(地址和內容)

      ds.send(letter1);//發信    

DatagramPacket letter2=new DatagramPacket(

                      new byte[100],0,100);

//準備空信用來接受服務端的信

      ds.receive(letter2);//收信

      byte[] data=letter2.getData();//獲得信的內容

      int offset=letter2.getOffset();

      int length=letter2.getLength();

   String str=new String(data,offset,length);//轉換成字符串讀取   

      System.out.println(str);

      ds.close();

      }

}

 

 

 

 

 

 

在服務端

import java.net.*;

public class UDPServer {

public static void main(String[] args) throws Exception{

DatagramSocket ds=new DatagramSocket(9000);//服務端口

      while (true) {

      byte[] bs1 = new byte[100];

      DatagramPacket letter1 = new DatagramPacket(bs1, 0, bs1.length);//製做空信封用來收信

      ds.receive(letter1);

      InetAddress address = letter1.getAddress();

      int port = letter1.getPort();

      String str = "北京2008年舉行奧運會";

      byte[] bs2 = str.getBytes();

DatagramPacket letter2 = new DatagramPacket(bs2, 0, bs2.length,address, port);//得到客戶端的ip和port而後將信息發給客戶端

      ds.send(letter2);

           }         

          

      }

 

 

DatagramSocket至關是郵箱有send(發消息)receive(收消息)

DatagramPacket,至關是信,裏面有ip端口,信息內容

============jdk1.5新特性===============

1,  可變參數 至關一個數組 m(String …s)一個方法只能有一個可變參數,且只是最後一個參數

2,  Foreach循環(for(object o:list))方便遍歷數組和集合

3,  枚舉

enum Course{

      UNIX ("Luxw") {

           public void study(){}

      },

      COREJAVA ("Huxz"){

           public void study(){}

      };

  Public void study();

}

使用:

class test { Course [] cs=Course.values(); for(Course c:cs ){System.out.println(s.ordinal+s+s.getName())}}

注意的問題:1枚舉值之間用逗號隔開,最後一個用分號2枚舉中能夠有抽象,但必須在枚舉值中實現;

4,  泛型 泛型解決集合中不安全性,泛型強制集合中都是一個類型

List<Integer>  l=new ArrayList<Integer>();Map<Integer,String> m=new HashMap<Integer,String>();

泛型方法:public static <T> void copy(List<T> l,T[] os){ for(T o:os){l.add(o);}}

                          <T extends Integer> <? Extends Integer>

5,反射  類對象,類加載時把類的信息保存在jvm中就會產生一個相應的對象(記錄類信息的對象),只要類對象存在則類信息就在

  得到類對象應用的三種方式:

           ①Class c1=ArrayList.class; ②Object l=new ArrayList();Class c2=l.getClass();

           ③String className="java.util.ArrayList"; Class c3=Class.forName(className);

           Class[] cs=c1.getInterfaces();//得到接口

           Class c=Animal.class;

           Field[] fs=c.getDeclaredFields();//得到屬性的數組

           Method[] ms=c.getDeclaredMethods();//得到本類全部公私有的方法,getMethods()得到父類全部公開的方法

           Constructor[] cons=c.getDeclaredConstructors();//得到構造方法的數組

           Object o2=c.newInstance();//建立類的對象

           Method m1=c.getDeclaredMethod("study");//找到方法名是study的方法

           m1.setAccessible(true);//設置爲能夠調用

           m1.invoke(o2);//調用m1方法

           Method m2=c.getDeclaredMethod("study", String.class);

           m2.setAccessible(true);

           m2.invoke(o2,"CoreJava");//調用m2的方法,方法的參數是CoreJava

 

 

6,註釋,===註釋是一種類型(總共有四種類型:類,接口,枚舉,註釋)

 

 

定義註釋

如:@Override;

標記:@註釋名

單值:@註釋名(屬性名=屬性值)

多值:@註釋名(屬性1=值1,屬性2=值2,......)

 

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target()

public @interface MyType {
 String authorName();
 String lastModified();
 String bugFixes() default "ok";
 }

在類中應用註釋:

import java.lang.annotation.*;
@MyType(authorName="hadeslee",lastModified="20061207")
  public class Test1 {
  /** Creates a new instance of Test1 */
  public Test1() {
  }
  @Deprecated
  @MyType(authorName="hadeslee",lastModified="20061207",bugFixes="what")
  public void doSth(){
  }

 

 

這裏我定義了一個我本身的註釋類,聲明方式和聲明接口差很少,只不過在interface前面多了一個@符號.
註釋類也能夠用註釋類註釋,如此下去.
@Retention(RetentionPolicy.RUNTIME) 這句表示它的保存範圍是到RUNTIME,也就是運行時,這樣在類運行的時候,咱們也能夠取到有關它的信息.

@Target() 這句表示它的適用對象,它能夠用在哪裏地方,我這裏定義的是它能夠用在類的定義和方法的定義上
而後咱們看咱們是怎麼爲咱們寫的類加上註釋的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

OOAD思想

 

1繼承關係:指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並能夠增長它本身的新功能的能力,繼承是類與類或者接口與接口之間最多見的關係

 

2關聯關係

①   關聯關係是對於兩個相對獨立的對象,當一個對象的實例與另外一個對象的一些特定實例存在固定的對應關係時,這兩個對象之間爲關聯,關係是使用實例變量實現的,好比公司和職員

②   聚合關係是關聯關係的一種,他體現的是總體與部分、擁有的關係,此時總體與部分之間是可分離的,他們能夠具備各自的生命週期,部分能夠屬於多個總體對象,也能夠爲多個總體對象共享;好比計算機與CPU、公司與員工的關係等;表如今代碼層面,和關聯關係是一致的,只能從語義級別來區分,它也是經過實例變量實現的,在java語法上是看不出來的,只能考察類之間的邏輯關係

③   組合也是關聯關係的一種特例,他體現的是一種contains-a的關係,這種關係比聚合更強,也稱爲強聚合;他一樣體現總體與部分間的關係,但此時總體與部分是不可分的,總體的生命週期結束也就意味着部分的生命週期結束;好比你和你的大腦;表如今代碼層面,和關聯關係是一致的,只能從語義級別來區分

④   依賴關係是類與類之間的鏈接,依賴老是單項的(人和車,人和房子),依賴關係在java中體如今局部變量,方法的參數,以及靜態方法的使用。在A類中的方法中使用B類的引用

 

 

 

代碼表示

 class A{

   B b;//聚合

C c=new C();//組合

Public A(B b){this.b=b;}

Public void ect(D d){ d.m(); //依賴}

}

class D{void m(){}}

 

 

 

在UML圖形表示[U12] 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ORACLE


第一天:====================

1,     關係數據庫的三要素: 1實體----》表(存放數據)

                          2屬性---》列

                          3關係---》外鍵

2,    sqlplus經常使用命令

   help index
能夠看到全部的命令,
不會的命令用:
help <命令>;例如:help list

exit       退出SQL*PLUS

desc 表名    顯示錶的結構

show user    顯示當前鏈接用戶

show error    顯示錯誤

show all     顯示全部68個系統變量值

edit       打開默認編輯器,Windows系統中默認是notepad.exe,把緩衝區中最後一條SQL語句調入afiedt.buf文件中進行編輯

edit 文件名   把當前目錄中指定的.sql文件調入編輯器進行編輯

clear screen   清空當前屏幕顯示

 

SQLPLUS到ORACLE的運行圖(見筆記本)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  select  columnname(列名)

  1)  select *

  2)  select id,last_name,dept_id

  3)  select id,last_name "Name",salary*12 anual

  4)  select last_name||' '||first_name

       //若是comm爲null時,nvl(comm,0)等於0;不然等於comm;

  5)  select  last_name,salary*(1+nvl(comm,0)/100) 

  6)  select distinct last_name,first_name 

 

  from  tablename 

  預約義:  做用的時間長   全部的叫這個列名的列都生效

  sql:   當次生效    當前sql的當前表      

 

  order by:

  select id,last_name,dept_id

  from s_emp

  1)order by dept_id;

    order by title;

  2)order by last_name,dept_id;  

    先按名字升序排,名字相同再按dept_id升序排  ,中間用「 ,  」隔開;

  3)order by last_name desc;

    order by dept_id,last_name desc;

    dept_id升序,last_name降序

  4)null

    在oracle裏是最大,也就是升序的時候放在最後面;

  5)order by 2;  <=======> order by last_name

    select * 裏面的第二列

  6)select id,last_name name

    from s_emp

    order by NAME;    

==============================================  select           from         where         order by

 

  select id,last_name,dept_id,start_date

  from s_emp

1)where  dept_id=41;

    where last_name='Smith';   ---->字符串區分大小寫,SQL命令不區分大小寫;

    where start_date='08-mar-90';       

  2)where salary>1000;

  3)where dept_id between 41 and 45;

    包括邊界值

    where dept_id between 45 and 41;  //小的在前,若是反了,查不出記錄  

    //dept_id的值只能是41,43,45三個數中的一個,且三個數都會被計算一次。

  4)where dept_id in(41,43,45);

  5)where commission_pct=null;    查不出記錄

    where commission_pct is null;    

  6)where last_name like 'S%';

      unix:   *    ?

      oracle: %    _ (下劃線)

    查出last_name是以'S_'

    where last_name like 'S_%';  ----> error

    where last_name like 'S\_%' escape '\';       //escape '\'表示「\」爲換碼字符;

  7) 非

    !=  <>

    not between  and

    not in

    not like

    is not null

  8)and > or

    where dept_id=41 and id>5;   

    where dept_id=41 or id>5; 

    ----->where salary>1000 

              and dept_id=41

              or dept_id=42;

    ----->where salary>1000 

              and (dept_id=41

              or dept_id=42 ); 

    ----->where dept_id=41

             or dept_id=42

             and salary>1000;

select s_customer.name,s_emp.last_name

from

s_customer,s_emp

where s_emp.id(+)=s_customer.sales_rep_id;              

//(+)讓員工表補個空值。爲的是讓全部的客戶都有對應的員工

//,由於有些客戶沒有對應的銷售表明,因此設爲空

 

        

 

 

 

 

=================================================================================================


次日:

Single Row Function:

 varchar2:

   1)  nvl('hello','world')-----> 'hello'

       nvl(null,'world')--------> 'world'

   2)  select id,last_name,dept_id

       from s_emp

       where lower(last_name)='smith';

   3)  select id,concat(last_name,first_name),dept_id

       from s_emp;

       concat(last_name,first_name)--->result1;

       concat(result1,title);

       --> concat(concat(last_name,first_name),title);

       System.out.println(stu.toString());

           select substr('String',-4,3)

       from dual;

       dual: dummy table ,爲了維護select的完整性 

            select id,last_name,dept_id

       from s_emp

       where last_name like 'S%';

       where substr(last_name,1,1)='S';

number: round  trunc

  date:日期類型

    1) select sysdate from dual; 

標準的日期格式:

  年:  yy        08

       yyyy      2008

       rr        08

       rrrr      2008

       year      two thousand and eight

  月:  mm        06

       mon       JUN

       month     june

  日:  dd        19

       ddth      19th

       ddsp      ninteen

       ddspth    ninteenth

 星期: d         4

       dy        thu

       day       thursday

 小時: hh24    22

       hh      10

       am  pm       

 分鐘: mi         秒: ss   

  select id,last_name,dept_id,

    to_char(start_date,'yyyy-month-dd,hh24:mi:ss') "sdate"

 from s_emp

 where dept_id=41;

 

 update s_emp

 set start_date=to_date('19-jun-08,11:24:56','dd-mon-yy,hh24:mi:ss')

 where id=100;              

 

 update s_emp

 set start_date=to_date('19-jun-90','dd-mon-yy')

 where last_name='S_abc'; 

 

 select id,last_name,to_char(salary,'$99,999.00')

 from s_emp;     

 

 select id,last_name,

   to_char(start_date,'fmdd-mm-yyyy,fmhh:mi:ss') "sdate"

 from s_emp;      

 

 fm:在不引發歧義的狀況下去掉前置的零和空格

    相似於開關變量,第一次寫打開功能,再寫關閉

 

 Join:數據來源於多張表,叫多表聯合查詢,多個表之間要作鏈接

   1.等值鏈接(內鏈接)  條件:  fk-----pk

     select s_emp.last_name,s_emp.dept_id,

            s_dept.id,s_dept.name

     from s_emp,s_dept

     where s_emp.dept_id=s_dept.id; 

     

 

     oracle:select e.last_name,e.dept_id,d.id,d.name

            from s_emp e,s_dept d

            where e.dept_id=d.id;   

           

    標準sql:select e.last_name,e.dept_id,d.id,d.name

            from s_emp e inner join s_dept d  

            on e.dept_id=d.id

            where e.last_name='Smith';  

           

            select e.last_name,e.dept_id,d.id,d.name

            from s_emp e join s_dept d  

            on e.dept_id=d.id

            where e.last_name='Smith';       

    

     打印出員工的名字,所在部門的名字,以及所在地區的名字

     select e.last_name,d.name,r.name

     from s_emp e,s_dept d,s_region r

     where e.dept_id=d.id

       and d.region_id=r.id; 

      

     select e.last_name,d.name,r.name

     from s_emp e join s_dept d

       on e.dept_id=d.id

       join s_region r

       on d.region_id=r.id;

 

  2.外鏈接(左外,右外,全外)

 

    打印全部的客戶名字,以及所對應的銷售表明的名字 

   

    1)左外:若是左邊對應的右邊的值爲空時,右邊補null

    oracle:select  c.name,c.sales_rep_id,e.id,e.last_name

                          from s_customer c,s_emp e

                          where c.sales_rep_id=e.id(+);  

   標準sql:select c.name,c.sales_rep_id,e.id,e.last_name

           from s_customer c left outer join s_emp e

           on c.sales_rep_id=e.id;

   

    2)右外  :若是右邊對應的左邊的值爲空時,左邊補null

    select  c.name,c.sales_rep_id,e.id,e.last_name

    from s_customer c,s_emp e

    where  e.id(+)=c.sales_rep_id;    

   

 select c.name,c.sales_rep_id,e.id,e.last_name

    from s_emp e right join s_customer c

    on c.sales_rep_id=e.id;

   

    3)全外 :都不補空值(null)

     select c.name,c.sales_rep_id,e.id,e.last_name

     from s_customer c full outer join s_emp e

     on c.sales_rep_id=e.id;  

    

 3.自鏈接: 本表的fk指向本表的pk

   能夠給表起不一樣的別名,再作鏈接。

   打印出員工的姓名和他的經理的名字

   select e.last_name,m.last_name

   from s_emp e,s_emp m

   where e.manager_id=m.id;

 

   打印出全部員工的姓名和他的經理的名字

select e.last_name,m.last_name

from s_emp e,s_emp m

where e.manager_id=m.id(+); 

  

 4.非等值鏈接(t1和t2沒有pk和fk,還想鏈接t1,t2)

     table1: id    value

              1      A

              2      B

              3      C

              4      D

     table2: id    value

              1      A

              2      B

              3      C

              4      D

     請寫出一句sql語句,打印輸出

     AB AC AD BC BD CD 

    

     select  t1.value,t2.value

     from  table1 t1,table2 t2

     where t1.id<t2.id;

    

     請寫出一段sql語句,打印輸出

     AB AC AD BA BC BD CA CB CD DA DB DC

     select  t1.value,t2.value

     from  table1 t1,table2 t2

     where t1.id!=t2.id;

    

   5.笛卡兒鏈接(不給鏈接條件)

    

     請寫出一段sql語句,打印輸出

     AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD

    

     select t1.value,t2.value

     from table1 t1,table2 t2;  

    

 SubQuery:

1.請打印出和Smith在同一部門的員工的姓名,

start_date,dept_id

     1) select dept_id

        from s_emp

        where last_name='Smith'; -----> result1

        select last_name,dept_id,start_date

        from s_emp

        where dept_id=result1;   

       

     2) select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

             select dept_id

             from s_emp

             where last_name='Smith');  

                                                  

   2.主查詢和子查詢靠值聯繫

     1) 值的類型要相同

        select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

             select last_name

             from s_emp

             where last_name='Smith');  

 

     select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

             select salary

             from s_emp

             where last_name='Smith');

 

 select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

             select id

             from s_region

             where id=1);    

 2)值的個數要一致

       select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

                       select dept_id,last_name

                                from s_emp

                       where last_name='Smith');

 

     select last_name,dept_id,start_date

        from s_emp

        where dept_id=(

             select dept_id

             from s_emp

             where last_name='Smith'

            or id=3);  ---->error

        --->改進

        select last_name,dept_id,start_date

        from s_emp

        where dept_id in (select dept_id

                                         from s_emp

                                         where last_name='Smith'

                     or id=3);

                    

     sql----->dbsv

     1)編譯

        a.權限檢測

        b.語法檢測

        c.sql翻譯成內部指令

     2)運行內部指令

    

  3)哪些地方能夠用子查詢

   須要值的地方就能夠用子查詢

   1)select         不能夠

     from           能夠(須要表的時候在這裏寫子查詢)

     where          能夠(須要值的時候在這裏寫子查詢)

     order by        能夠(按select裏列的下標值排序 ,如:order by 2)

     group by                 不能夠

     having                     能夠(跟where用法同樣)

     select *

     from (select e.last_name,e.dept_id,d.id,d.name

           from s_emp e,s_dept d

           where e.dept_id=d.id) e;

          

          

 jobs:

  1.SQL-1.pdf  (4)

 

      2.請打印出公司入職最先的五個員工的姓名(last_name),dept_id,start_date

select *

from (

         select last_name,dept_id,start_date

         from s_emp

         order by start_date

) e  

where rownum  between 1 and 5;

       

 

 

      僞列:rownum(表明顯示在界面上的行號,數據庫自己不提供,查詢時會默認的提供,只有在select中顯示的寫rownum,纔會顯示行號;)

      rowid(數據庫裏自己就有的,表明在數據庫裏存的物理地址)

      select * from s_dept;

      desc s_dept;

 

      分頁:子查詢和rownum

        打印表裏面第五到第十條記錄:

select last_name dept_id,start_date

from(

select e.last_name,e.dept_id,e.start_date,rownum rownumid

         from(

                   select last_name,dept_id,start_date

                   from s_emp

                   order by start_date

         ) e

         where rownum between 1 and 10

) a

where a.rownumid between 6 and 10;

 

 

 

 


第三天:===================================

 Group function(組函數):

  1) select avg(salary),max(salary)

     from s_emp;

     select count(*) from s_emp;

     select count(id) from s_emp;

     select count(commission_pct) from s_emp;

     統計commission_pct列不爲空的值的個數;

     number: max  min  sum  avg  count

     date:   max  min  count

     char:   max  min  count    

  2) select dept_id,avg(salary),count(*)

    from s_emp

    group by dept_id;

    select   from    where   group by   order by

    select dept_id,avg(salary)

    from s_emp

    where dept_id in (41,50)

    group by dept_id;

   

 3) 當select裏面出現組函數和單獨的列並存時,要求必須

    寫group by子句,而且單獨的列必須出如今group by裏面

    select dept_id,avg(salary)

    from s_emp

    group by dept_id;      

    select salary,avg(salary)

    from s_emp  

    group by salary;

   

    若是group by裏出現多列,那麼按照列的聯合分組,

    只有多列的值徹底相同纔會分到一組

    select last_name,first_name,avg(salary)

    from s_emp

    group by last_name,first_name;

請打印出工資低於公司平均工資的人的姓名,

dept_id,start_date

    select last_name,dept_id,start_date

    from s_emp

    where salary<(select avg(salary) from s_emp ); 

4) 只要寫group by,那麼select裏單獨列必須出如今

    group by裏

    select dept_id,last_name,start_date

    from s_emp

    group by dept_id,last_name,start_date;

5)where執行時數據處於獨立個體狀態,裏面不能對組函數

   進行判斷,只能對單獨記錄判斷

   having必定出現group by後面,此時數據處於組的狀態

   因此having只能對組函數或者組的共性進行條件判斷,

 

   請打印出部門平均工資大於1500的這些部門的id以及平均工資

   select  dept_id,avg(salary)

   from s_emp

   where avg(salary)>1500

   group by dept_id;     ------>error  

  ====================================

   select  dept_id,avg(salary)

   from s_emp

   group by dept_id       

   having avg(salary)>1500;   

  

   select  dept_id,avg(salary)

   from s_emp

   group by dept_id  -------> group      

   having salary>1000;   ----->整個組  error   

  

   select  dept_id,avg(salary)

   from s_emp 

   group by dept_id

   having dept_id>40;

  

   select  dept_id,avg(salary)

   from s_emp   

   where dept_id>40

   group by dept_id ; 

  

 6) order by 列名,2,別名;

    原來對order by裏的列沒有任何限制,只要表裏有就能夠

    select  from   where   group by  having  order by

    在order by以前若是出現了group by,那麼order by裏面

    就只能按照組函數或者是組的共性排序

     eg: select dept_id,avg(salary)

        from s_emp

        where dept_id > 40

        group by dept_id

        having avg(salary)>1000

        order by last_name; ------>error

        order by max(last_name); ---->correct

        order by dept_id;    -------->dept_id    

  做業: 請打印出工資低於本部門平均工資的員工的姓名,

         dept_id,start_date 

       select dept_id,avg(salary) asalary

        from s_emp

        group by dept_id;   ---->a1

      select e.last_name,e.dept_id,e.start_date

        from s_emp e,a1

        where e.dept_id=a1.dept_id

          and e.salary<a1.asalay;

    --->select e.last_name,e.dept_id,e.start_date

        from s_emp e,(

             select dept_id,avg(salary) asalary

                                from s_emp

                                group by dept_id

                  ) a1

        where e.dept_id=a1.dept_id

          and e.salary<a1.asalary;       //數據庫表和錶鏈接的時候,比較的是同一元組;

  

 

      

 Define  Variable

 1. select last_name,dept_id,start_date

    from s_emp

    where dept_id=&did; 

    where last_name=&name;

    where last_name='&name';     

 2.預約義 

   1) define varname=value

      define did=41

       簡單,定義出來的變量都是char類型  

      不能寫進sql文件

      查詢一個數是否已經預約義用define varname

      取消用undefine varname

   2) accept varname type prompt '   ' hide    //單獨一句話,爲的是永久性的給varname一個值

  accept did number prompt 'please input dept_id value:' hide

      accept did prompt 'please input dept_id value:'----> char

     

     比define複雜, 能夠指定變量的類型,能夠寫進  .sql 文件,

     在bash下:1)進入csh;

                2)setenv EDITOR VI ;

                3)sqlplus 進入SQL的用戶名和密碼;

                                    4)寫一個要保存進文件的命令;

                5)save sqlfile;

     6)ed   進入vi編輯命令,在最上面加上(accept varname type prompt '   ' hide)語句;

      7)ZZ(保存並退出vi);                 

      8)start sqlfile.sql就能夠運行剛纔保存的命令了。

                

下面是用於實驗預約義的

/*select e.last_name

from s_emp e

where e.dept_id='&deptid';

accept deptid number prompt 'please input dept_id value:' hide

*/      

3) define varname   查看狀態

      undefine varname  取消預約義      

3.哪些地方能夠用變量定義:

   select            

   from

   where              所有能夠

   group by

   having

   order by   

  

   select &col1,&col2,&col3

   from &tab1

   where &con1; 

 

    =======================================================================================


 第四天:

Create table:

 1.db structure

   1)table---> store data             2)view----> select              3)sequence            4)index

 2.create table luxw1

   ( id number(7),

     name varchar2(15),

     registdate date

   );       

   create table luxw2

   (id number(7),

    film blob

   );

    

   1)列一級約束

   create table yesq5

   ( id number(7) constraint yesq5_id_pk primary key,

     name varchar2(15) constraint yesq5_name_nn not null,

     age number(3) constraint yesq5_age_ck_age check(age>18 and age<60),

     sex varchar2(2) default 'M' constraint yesq5_sex_ck_sex check( sex in('F','M') ),

     birthday date default sysdate,

     phone varchar2(15) constraint yesq5_phone_uk unique,

     personid char(18)

       constraint yesq5_personid_nn not null

       constraint yesq5_personid_uk unique,

     class_id number(7) constraint yesq5_class_id_fk references s_dept(id) on delete cascade

   ); 

   2)表一級約束

   create table yesq5

   ( id number(7),   

     name varchar2(15) constraint yesq5_name_nn not null,

     age number(3),

     sex varchar2(2) default 'M',

     birthday date default sysdate,

     phone varchar2(15),

     personid char(18) constraint yesq5_personid_nn not null,

     class_id number(7),

     constraint yesq5_id_pk primary key(id),

     constraint yesq5_age_ck check( age>18 and age<60),

     constraint yesq5_sex_ck check( sex in('M','F') ),

     constraint yesq5_phone_uk unique(phone),

     constraint yesq5_personid_uk unique(personid), 

     constraint yesq5_class_id_pk foreign key(class_id) references s_dept(id) on delete cascade

   );

   五種約束:  無約束的地方不用寫constraint。

   1) not null

   2) unique

   3) primary key

   4) foreign key  references (on delete cascade)

   5) check

 兩種位置定義約束的      區別:

   1) 約束前面是逗號就是表一級,

      約束前面是空格就是列一級;

 2) not null只能定義在列一級

   3) 聯合鍵只能定義在表一級

      eg:聯合惟一: unique(last_name,first_name)

   聯合主健: primary key(product_id,order_id)     

  on delete cascade:該句在子表最後聲明時,說明他的數據隨外鍵的消失而消失

   刪除父表記錄

  1)寫了on delete cascade

    sql: delete from fathertable where id=1;

  2)沒寫on delete cascade  

    sql: delete from sontables where fk=1;

         delete from fathertable where id=1;   

         

 3 用子查詢建表          

  1) 表的列名,列數,類型靠子查詢定

     create table luxw04

     as

       select id,last_name,dept_id,start_date

       from s_emp

       where dept_id in(41,42);

              

     create table asalary

     as 

        select dept_id,avg(salary)

        from s_emp

        group  by dept_id; 

 

 

 

  2) 主sql規定了列名,列的個數,不能定義列的類型

     在建表過程當中只保留了非空(not null)約束,其餘約束丟失  

     create table asalary

     (did,avgsal)

     as

       select dept_id,avg(salary)

        from s_emp

        group  by dept_id;   

  3) 能夠制定約束

     create table luxw06

     (id primary key,

      last_name,

      dept_id references s_dept(id),

      start_date default sysdate

     )

     as

       select id,last_name,dept_id,start_date

       from s_emp

       where dept_id in(41,42);  

         

  約束和數據的關係:

  誰先進入表,誰說了算    

 

 Data dictionary(表的集合):

  1) 表:存放描述數據庫狀態的數據 

        db server在建庫時創建

        由db server維護,在線動態更新

        user只能查詢

  2)user:由用戶建立的 ,屬於這個用戶的。

    all: 用戶有權使用

    dictionary: 保存了全部數據字典的名字,和描述信息

   

  3)查出yesq5表personid列上的惟一性約束的名字

    用到下面這兩個表:

    user_constraints

    user_cons_columns

   

    select cons.constraint_name,cons.constraint_type,cols.column_name

    from user_constraints cons,user_cons_columns cols

    where cons.constraint_name=cols.constraint_name

      and cons.table_name='YESQ5'

      and cols.column_name='PERSONID'; 

     

DML:

  insert:

  * 1) 全表插入,值的順序,類型,個數必須和表裏的列一致

      insert into luxw8

      values(1,'zhangsan','m','12-sep-98');

      insert into luxw8

      values(2,'lisi','f',null);

      insert into luxw8

      values(3,'wangwu','f', to_date('23-06-08','dd-mm-rr'));        

         

      insert into luxw8

      values(4,'lisi','f',&da); 

     

  * 2)選擇插入,列的個數,類型,順序必須和指定的相等

     選擇時非空的列必須出現

insert into luxw8(id,name,sex)

     values(5,'huxz','m');

 

     insert into luxw8(name,id)

     values('wangwu',6);

    

     insert into luxw8(name,sex)

     values('liucy','m');     ----->error 無PK        

   3)insert into luxw8(id,name)

     values('7','liucy')

     values('8','luxw');    ---->error    不能同時添加兩個數據

     insert into luxw8(id,name)

     values(&idd,&na);  

    

   子查詢提供值,值的類型和個數要匹配

     insert into luxw8(id,name)

     select id,last_name

     from s_emp

     where dept_id=45; 

update:

   1) update  luxw8

      set name='sun'

      where id=1;

   2)update  luxw8

      set name='fengwang',sex='m',registdate=sysdate

      where id=2;

delete:

   delete from luxw8

   where id between 2 and 5;  

  

 Transaction(事務):必須具備原子性

 

 ACID

 A:原子性,加錢和減錢都要成功或都失敗,保持原子性;

 C:一致性,數據一致性,如:A向B轉賬5000塊,那B就應該收到5000塊,不能多也不能少;

 I:隔離性,兩個SQL語句的操做只操做本身的,不能影響到另外一個語句,也就是至關於每一個SQL都要有本身的回滾段;

 D:持久性,數據的改變用commit或用rollback,讓數據持久化;

 

  1) 一組不可再分的sql命令組成的集合,   若是分了數據將不統一,如:銀行轉賬

     事務的大小跟業務需求有關

  2) 事務結束時結果

     success:   commit   回滾段內的數據寫到FILE,鎖釋放,其它用戶也能夠看到結果

     fail:      rollback   清空回滾段內容,沒寫到FILE,鎖釋放,其它用戶看不到修改的值,

  3)

     insert update  delete update  delete commit;

     create--->auto commit;

     insert

     update

     delete

     create --->auto commit;

     insert

     update

     rollback;   

     insert update delete  exit      

 

        

 

 

 

 

 

 

 

 

============================================================================

 

 

  第五天: 

DDL:

 alter:改表結構

 1)增長一列,添加到表的最後一列

   alter table luxw8

   add(age number(3) default 18 check(age<40)); 

  

 2)刪除一列(在oracle8i)

   alter table luxw8

   drop (age,registdate);

  

   alter table luxw8

   drop column age;

 

 3)更改列名(在oracle9i)

   alter table luxw8

   rename column oldname to newname;   

 4)更改列(類型,size,添加約束,添加默認值)

   alter table luxw8

   modify(name varchar2(20) default user unique);

   若是表裏沒有數據,隨便改

   若是表裏有數據,改的時候必須符合表裏的數據

   alter table luxw8

   modify(sex not null);  

   非空約束只能用modify子句加

  

 5)添加約束

   聯合鍵約束加的時候只能用add子句

   alter table luxw8

   add unique(personid);

   alter table luxw8

   add constraint luxw8_personid_uk unique(personid);

  

        當A表的PK是B表的FK且B表的PK是A表的FK時,

        只能先讓一個表(A表)的FK爲空,再用add以表結構向該表(A表)添加FK,以下:

   create table product

   ( id number(7) primary key,

     name varchar2(15) not null,

     price number,

     b_id number(7)

   );

   create table bid

   ( id number(7) primary key,

     userid number(7) references users(id),

     bprice number,

     product_id number(7) references product(id)

   ); 

   alter table product

   add foreign key(b_id) references bid(id);

  

 6)刪除約束

   alter table luxw8

   drop constraint luxw8_personid_nn ;

   alter table luxw8

   drop primary key cascade;

        

  7)失效約束

   alter table luxw8

   disable constraint luxw8_personid_uk;

  

   alter table luxw8

   disable constraint luxw8_id_pk cascade;

級聯失效

 

 

8)生效約束

   alter table luxw8

   enable constraint luxw8_personid_uk;

   alter table luxw8

   enable constraint luxw8_id_pk;

   生效時沒法級聯,只能手動一個一個作   

rename oldtablename to newtablename     改表名

 truncate table tablename;  截取表 

drop table tablename cascade constraint;

 刪除父表,而且級聯刪除子表的外鍵約束

Sequence:

   數據庫提供的產生一系列惟一值的對象,用來生成主鍵值;

   它是數據庫裏獨立的對象,不依賴任何表

 

 1)create sequence seq1

   increment by 1   //每次遞增1

   start with 100              //從100開始計數

   maxvalue 99999          //最大值爲99999

   nocycle             //無循環

   nocache;    //沒有緩衝

   

   create sequence sql_seq

       increment by 1

       nocycle;

  

2) nextval:

       若是有cache取出cache下一個可用的值

       若是沒有cache,取出序列下一個可用的值

                insert into  sql_users(id,name,passwd,phone,email)

                values( sql_seq.nextval,'wangwu','123456abc', 12321,'kdfdfk@gmail.com');

               

                select seq2.nextval

                from dual; 

                 

    currval:當前的鏈接最後一次使用序列的值

        select seq1.currval

        from dual;

       

   last_number(column):序列下一個可用的值

        select last_number

        from user_sequences

        where sequence_name='SEQ2';  

       

 3)改序列

   alter sequence seq1

   increment by   maxval   minval   cycle    cache

   序列的起始值不可能改變    

  

 4)刪除序列

   drop sequence seq1;

  

 5) insert  insert insert rollback; 

    只能朝前走                     

==========================================

 view:

   起了名字的查詢語句

   1) create view emp_v1

      as  select id,last_name,dept_id

          from s_emp;

    

     select * from emp_v1;   

    

     簡化select語句的複雜度

     限制數據的顯示

     節省空間

  

 

 

   2) 複雜視圖:裏面包含了函數,鏈接,組函數 

          不能應用DML(增刪改),只能查詢

      簡單視圖:      

               

      create view emp_v3  

      (dept_id,asalary)

      as

         select dept_id,avg(salary)

         from s_emp

         group by dept_id;

        

     update emp_v3

     set asalary=1111

     where dept_id=41;   ---->error

  

  3)create view emp_v4

    as

      select id,last_name,dept_id

      from s_emp

      where dept_id=41

with check option constraint emp_v4_ck; //表示該視圖(emp_v4)裏的數據沒法刪除或改變,但能夠添加數據

  

  

   建立數據庫用戶:

 create user username identified by password

 default tablespace users

 temprory tablespace temp;

 

 alter user username identified by newpassword;

 

 grant resource,connect to username;

 grant create view to cksd0804;

 

 revoke create view from cksd0804;        

 

 

  至少掌握數據庫如下四點:

     1)crud(增刪改查)

     2)create table(建表)

     3)transaction(事務)

     4)create sequence   //sequence:序列

 

 JDBC跟下面有很大的聯繫:

 1  interface

 2  try catch  finally

 3  thread

 4  static{}

 5  socket (url)

 6  encapsulation inheritance poly...   javabean  

 7  collection  map

 

 

 創建表空間  
       create   tablespace   si   datafile   '/u/oradata/en73/si.dat'   size   70M     online  
          default   storage   (   pctincrease   2   );  
  創建用戶  
       create   user   zhangwf  identified   by   pwd  default   tablespace   si   temporary   tablespace   si;  
  給用戶受權  
       grant   dba,   connect,   resource,   create   table   to   si;  
  創建表在用戶SI上  
      create   table   si.tbname(col1   int,col2   varchar2(10));  

修改密碼:alter user zhangwf  identified by   newpwd

 

 

 

 

 

 

 

 

考點:行列轉換, 重複數據的過濾,索引的創建

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

JDBC筆記


第一天:

  OracleDriver{

     public void connectOracle(){

         ......

     } } 

  DB2Driver{

     public void connectDB2(int i){}

  }                

  telnet 192.168.0.200 

  Unix,Linux: echo $ORACLE_SID      在Unix和Linux下查看鏈接的哪一個ORACLE

  windows:  net start       在windows下查看鏈接的哪一個ORACLE

  username

  passwd

  DriverManager.getConnection();

  class OracleDriver implements Driver{ //OracleDriver類的大致實現

     static{  

        OracleDriver d=new OracleDriver();

        DriverManager.addDriver(d);

     }

  }

  class DriverManager{     //DriverManager類的大致實現

     private static List<Driver> dri=new ArrayList<Driver>();

     public static void addDriver(Driver d){

        ......

        dri.add(d);

     }

     public static Connection getConnection(){

        for(Driver d:dri){ 

           if(d!=null)  return d.getconnect();

        }

     } }      

  boolean execute(sql) ---> all  

     boolean 有沒有ResultSet返回

     true:有      false:沒有

     rs=stm.getResultSet();

  ResultSet executeQuery(sql){}-----> select

  int executeUpdate(sql){} -----> insert update delete

  運行程序可能出現的下面幾種異常:

  1 Class not found 

    -------> ojdbc14.jar 

  2 No suitable Driver

    ----->url

  3 Socket Exception 

    ping 200

  4 SQLException ---->  sql

   table: jdbc_users

   sequence:  jdbc_users_seq

   driver=oracle.jdbc.driver.OracleDriver

         url=jdbc:oracle:thin:@192.168.0.200:1521:oradb10g

         username=cksd0804

         password=cksd0804             

         BufferedReader

         1)String str=br.readLine();

         2)String[] s=str.split("=");

         3)if(s[0].equals("driver"){}

         以上三步至關於如下兩步:

         Properties info=new Properties();

         info.load(Inputstream);                //表示(1)加載輸入流,(2)讀取文本內容,(3)解析文本文件,//(4)再存入Properties集合

.properties ------> Map<String,String>

     ------>Properties extends Hashtable<String,String>

JdbcUtil.class.getResourceAsStream("/com/kettas/jdbc/cfg/config.properties");  //爲虛擬路徑,第一個/表明classpath

/com/kettas/jdbc/cfg/config.properties

  /<====>classpath

 /home/java/jdbc/.....  //全路徑

 Student s=new Student();

 第一次加載類時,JVM加載類的順序:

 1. search file ---->Student.class    經過classpath尋找類文件

    path---->command

    classpath--->.class

 2. read Student.class  讀取類文件

 3. Class c----> 得到Student類詳細信息(類對象)

Student s2=new Student();  

  .class----> jdbc.jar--->user--->classpath

  1 分散代碼集中管理(封裝)

  2 變化的內容寫進文件(配置文件)             

配置文件通常格試:config.xml和config.properties

  3  .properties  (是一種特殊的文本文件)

  4  Properties   (是Hashtable的子類)

  5  ExceptionInInitializerError

  6  Class.getResourceAsStream( 虛擬路徑 )

1. jdbc 六個步驟

     1)註冊Driver;

Class.forName("oracle.jdbc.driver.OracleDriver");

     2)得到鏈接

 String url="jdbc:oracle:thin:@192.168.0.200:1521:oradb10g";

Connection conn=DriverManager.getConnection(url,"用戶","密碼");

     3)建立Statement,stm=conn.createStatement();

     4)執行sql,      stm.executeUpdate(sql);

     5)select--->處理結果集

ResultSet rs=stm.executeQuery(sql);

while(rs.next()){            System.out.println(rs.getInt(1)+"------"+rs.getString(2));

          }

     6)釋放資源(rs,stm,conn)

      if(rs!=null)  try{ rs.close();} catch(Exception ee){}

         if(stm!=null)  try{ stm.close();} catch(Exception ee){}

         if(conn!=null) try{ conn.close();} catch(Exception ee){}

  2. 註冊Driver的三種方式   

     1)Class.forName("oracle.jdbc.driver.OracleDriver");

     2)Driver d=new oracle.jdbc.driver.OracleDriver();

       DriverManager.registDriver(d);

     3)程序裏沒有指定

 java-Djdbc.drivers=oracle.jdbc.driver.OracleDriver classname

  3. ResultSet遍歷 

     1) next()---->boolean

     2) get***(int)   get***(columnname) 

        eg: getString("name");

開始時指針指向第一行的上一行,最後指針指向最後一行     的下一行

  4. 三種execute方法的區別

     1)stm.execute(sql)   all   boolean(ResultSet)(返回布爾型,判斷是否有結果集)

     2)stm.executeQuery(String selectsql) --->ResultSet(返回結果集,sql是查詢語句)

     3)stm.executeUpdate(sql)  --->int(db row)  (返回int,判斷改變的行數,通常執行,update,delete,insert)

       ---->delete update  insert 

 

 

Statement和PreparedStatement

  Statement是逐條發送語句(能夠執行多條語句),PreparedStatement是先存儲sql再一塊兒發送(在sql須要設值的時候,效率要高,但只能執行一條語句)例子:

String sql=

"insert into jdbc_users(id,name) values(users_seq.nextval,? )";

pstm=conn.prepareStatement(sql);

pstm.setString(1, names[i]);//1表明是提幾個問號,後面是設值

pstm.executeUpdate();一塊兒提交

  5.JdbcUtil類

     1)分散代碼集中管理(封裝)

     2)常常變化的寫進文件(配置文件)

       config.xml        config.properties

  3)Properties extends Hashtable<String,String>

       專門處理properties文件,提供load(InputStream is)

     4)在程序加載時讀一次文件,因此讀文件的代碼寫在

       靜態代碼塊,裏面只能拋一種類型的錯誤

       ExceptionInInitializerError

     5)利用jvm的類加載器讀字節碼文件的功能,能夠得到

       輸入流,

       InputStream is=JdbcUtil.class

             .getResourceAsStream(虛擬路徑);

       絕對路徑:/是真是的目錄裏面的根

       虛擬路徑:/是classpath

例子:

private static Properties info=new Properties();

         static{          try {

InputStream is=JdbcUtil.class.getResourceAsStream(

"/com/kettas/jdbc/cfg/config.properties");         

info.load(is);

         is.close();

                   } catch (Exception e) {

                            throw  new ExceptionInInitializerError(e);

                   }

         }

 

 

線程ThreadLocal  每個線程對象建立好之後,JVM會爲其分配一塊內存空間用來存放當前線程對象獨佔的數據,(一個線程對象和另外一個獨佔的數據(對象)綁定(如:(tl , conn)表明某一線程的獨佔數據 ))空間以map形式存放獨佔數據,至關於Map集合裏的健對象和值對象

  每一個線程的獨佔數據不共享,即:健對象(tl)和值對象(connection)不共享:Map<ThreadLocal,Object>

 

注意:ThreadLocal沒法直接獲取Map對象,操做Map只能經過ThreadLocalsetget方法

private static final ThreadLocal<Connection> tl

=new ThreadLocal<Connection>();

public static Connection  getConnection() throws Exception{

  Connection conn=tl.get();//用get獲取當前線程的鏈接對象

       if(conn==null){

       Class.forName(info.getProperty("driver"));

         conn=DriverManager.getConnection(info.getProperty("url"),                     info.getProperty("username"),info.getProperty("password"));

       tl.set(conn);//用set把鏈接對象放在當前線程中

       }       return conn;  }

 

線程ThreadLocal的大體實現過程

     public class ThreadLocal<T>{

         public T get(){

            Map m=Thread.currentThread().getMap(); 

            return m.get(this);

                       }

         public void set(T t){

            Map m=Thread.currentThread().getMap();

            m.put(this,t);

                      }

            }

    

     ThreadLocal<Integer> ta=new ThreadLocal<Integer>()   //例子

     ta.set(new Integer(3)); 

 

 

 

 

  7. Driver方展的四個階段 

     1)Jdbc-odbc (橋鏈接)    2)db client(客戶端api)

     3)base net pure java (網絡服務器)  4)pure java native(純客戶端)

    7. 寫程序,向jdbc_users表插入五條記錄

   String[] names={"mary","tom","anna","jerry","george"};

 

 

    

 

 次日:=======================================

Statement 和  PreparedStatement

 1)創建

   stm=conn.createStatement();

   pstm=conn.prepareStatement(sql);

 

 2)執行

   stm.execute(sql);   包含數據的完整的sql命令

   pstm.execute();     數據

 

 3)stm 能夠執行多條sql

   pstm 只能執行一條sql

 4)使用pstm的環境

   a.執行同構sql,用pstm效率高

             執行異構sql,用stm效率高   

   b.構成sql語句時須要外部的變量值,用pstm

   

 

  dao:

   public void update(Account a){ 

     sql=update account set username=?,passwd=?,

         personid=?,balance=?;

     pstm=conn.....

     pstm.setString(1,a.getName());

   }

=======================================

  

 Transaction: 一組不可再分的sql命令,根具體業務有關

 =============================================

 A:原子性    :事務要麼一塊兒成功,要麼一塊兒失敗,如:銀行轉賬

  C:一致性  :如:存錢時,存5000,那麼在數據庫裏的錢就要有5000,不能多也不能少

  I:隔離性   :鏈接db的兩個線程操做db時,要操做個自的元組,不能同時操做同一個元組

  D:持久性--->commit,rollback ,就是讓更改後的數據要麼寫加db要麼不寫進db;

 

  手動劃分事務的邊界,通常寫在業務層(biz)的代碼塊裏。

  劃分事物邊界的時候通常在要劃分的地方加commit和rollback;

   conn.setAutoCommit(false);

     新事物開始

   conn.commit();

     舊事務的結束,新事務的開始

   conn.rollback();

     舊事務的結束,新事務的開始 

   沒有手動劃分,採用的是默認事務提交策略:

   一條sql一個事務

 

 

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

  Connection是線程不安全的,不能在線程間共享鏈接(connection)用ThreadLocal實現安全的鏈接

 

  threada   save   withdraw   transfer

  threadb   save   withdraw

    1.common: 5 個 Connection

  2.singleton: 1 個 Connection              

 3.一個線程內部共享鏈接: 2 個 Connection 

      t1.start();

    t2.start();

  class ThreadA extends Thread{  

     private Connection conn1=null;

     public void run(){

        conn1=JdbcUtil.getConnection();

        save(10000,conn1);

        withdraw();

     }

     public Connection getConn(){return this.conn1;}

  }

class Bank{

  public void save(double balance){   

      conn2=Thread.currentThread().getConn();

      sql="update account set balance=?";

      pstm=conn.prepareStatement(sql);

                        //設置上面問號(?),如pstm.setDouble(int parameterIndex, double x);

      pstm.set***;

      pstm.executeUpdate();

  }

  public void withdraw(double balance){

      conn2=Thread.currentThread().getConn();

      sql="update account set balance=?";

      pstm=conn.prepareStatement(sql);

      pstm.set***;

      pstm.executeUpdate();

  }

}

       

     save  ----> update   insert

     withdraw----> update  insert

     transfer ---> update  insert

                   update  insert

       update()    insert()

       save---->update() insert();           

                                    

  dao: 1)對業務層屏蔽底層數據庫設計的細節  ,只有功能被業務層調用

       2)o-r mapping:就是把對像自動的保存到數據庫的表中

 

   

 

 第三天:=======================================

1 PreparedStatement

  Statement

  stm=conn.createStatement();

  stm.execute(sql);

  String sql="insert into table value(?,?,?);

  pstm=conn.prepareStatement(sql);   

  pstm.set***(int,value);

  pstm.execute(); 

  pstm同構sql,sql語句須要外界變量值

  stm 異構sql

2 Transaction 

  sqls,跟具體業務有關

  ACID 

  biz:

  try{            

        conn.setAutoCommit(false);

        conn.commit(); 

  }catch(Exception e){

        conn.rollback();   

  }

3 ThreadLocal

  1)將Connection作成Thread的屬性

    經過參數的傳遞,保證一個線程一個鏈接   

  2)Thread t1-----> map(線程的獨佔的數據)

    Map: 主鍵ThreadLocal,沒法直接得到Map對象

         操做map只能經過ThreadLocal的set get操做

    eg:讓Thread對象獨佔一個Integer對象

       Integer id=new Integer(3);

       ThreadLocal<Integer> tl=new ThreadLocal<Integer>();

       tl.set(id);

4 Layer 

   1)  app: showinterface 

            業務判斷

         =============================

   save

            transfer

            showResultSet    

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

       view  ---> showinterface

       biz----> 業務處理 

         1)業務判斷

         2)業務處理

            =====================

account.balance+=money;

         3) Connection conn

            stm.execute(sql);

            commit();

         4)return result --->view 

        save():       update    insert

        withdraw():   update    insert

        transfer():   update    insert

                    update    insert

                    update 4   insert  4      

        view---->showinterface

        biz----> 業務處理

 1)業務判斷   如:查看密碼是否正確,或餘額是否不足。

 2)業務處理如:密碼不正確或正確的處理,餘額足時的操做

            account.balance+=money;

          3) 封裝對象     如:用戶註冊

          4)用對象調用dao裏的方法存貯數據

         5)提交事物

        dao:---->data access object

          1)完成對某一張的增刪改查

             update(): update

             insert(): insert

             delete(): delete

             query():  select

   2)接收從業務層傳來的數據(對象),將其存進db

      從db裏面查數據(零散),封裝對象,返回給業務層

       object----relation  mapping

           save():  update()  insert()

        withdraw: update()  insert()

        transfer:  update()  insert();

        update:1       insert: 1   

       

  1  javabean--->Student

     class Student{    

        private Integer id;

        private String name;

        private String sex;

        private String address;

        private int age;

        private String studentId; 

        public Student(String name,String sex,String address,int age,String studentId){

           ......

        } }

  2  create table jdbc_student

     ( id number(7) primary key,

       name varchar2(15) not null,

       sex varchar2(3) check(sex in('f','m')), 

       age number(3),

       address varchar2(20),    

       studentid varchar2(15) not null unique    

     );

  3 class StudentDao{  

       public void insertStudents(Set<Student> stus) throws Exception{}

       public void insert(Student s) throws Exception{

          Connection conn=null;

          PreparedStatement pstm=null;

          try{

            conn=JdbcUtil.getConnection();

            String sql="insert into jdbc_student"

              +" values(jdbc_student_seq.nextval,?,?,?,?...)";

            pstm=conn.prepareStatement(sql);  

            pstm.set***();

            pstm.execute(); 

            sql="select jdbc_student_seq.currval from dual"; 

            s.setId(?);  

            }finally{ 

             JdbcUtil.release(...);

          } }

       public void update(Student s) throws Exception{

           String sql="update jdbc_student set name=?,age=?,address=?,sex=?,studentId=? where id=?";

       }

       public void delete(Student s) throws Exception{

          delete from jdbc_student where studentId=?

       }

       public Student queryById(Integer id) throws Exception{}

       public Student queryByStudentId(String studentId) throws Exception{}

       public Set<Student> queryByName(String name) throws Exception{

    String sql="select * from jdbc_student where name=?";

                pstm=conn.prepareStatement(sql);

                pstm.setString(1,name);

                rs=pstm.executeQuery();

                Set<Student> stu=new HashSet<Student>();

                while(rs.next()){

                   Student s=new Student();

                   s.setId();

                   s.setName();

                   ......

                   stu.add(s);

                }

                return stu;

       }

    }

  4 class StudentBiz{

       public void registStudent(String name,String sex,int age,String address,String studentId) throws Exception{

          1.  判斷     如:判斷密碼是否正確

          2.  封裝對象        如:新建對象

                  3.  dao.insert(s); 

          4.  事務處理           conn.commit 或conn.rollback;

       }

        public void dropStudent(String studentId)...

        public void queryStudent(String studentId)...

        public void updateStudent(String name,String address,String oldstudentId,String newStudentId)....

    }     

    com.kettas.student

      biz

        |--- StudentBiz

             impl

               |---StudentBizImpl

      entity

      dao  

      |--- StudentDao

           impl

               |---StudentDaoImpl

      config

      util

      excp

      view

      test

      sql

 

  Repeatable read 

     select *

     from s_emp for update;

  Serializable  

 

  備份數據庫提升效率策略:

   1) 手動控制事務的大小,節約了db服務器的內存

      減小了回滾帶來損失

   2) 事務結束時寫日誌,減小了查找失敗事務的時間

   3) 刪除備份數據庫表裏的約束,減小數據進入時驗證的時間

      下降數據庫服務器維護索引的資源

   4) 下降數據庫的隔離級別,設置到read uncommited

   5) 插入時選擇PreparedStatement,執行同構sql,減小編譯

      sql命令的時間 

   6)插入時使用批處理,減小網絡傳輸時間。


 

 


第四天:===========================

Statement stm=conn.createStatement();

 

stm2=conn.createStatement(int value1,int value2);

  value1:是否可滾動

     ResultSet.TYPE_SCROLL_INSENCITIVE

  value2:是否可更新   

     ResultSet.CONCUR_UPDABLE

 rs=stm2.executeQuery();  

pstm=conn.prepareStatement(sql,int,int);

 數據庫表數據的分頁

 1.db--sql

   子查詢和Rownum

 2.jdbc---->可滾動的結果集 

   String sql="select * from s_emp order by start_date";

   rs=stm.execute(sql);

  ========================================

 int num=1; 

   rs.absolute(5);

   while(rs.next()){ 

      if(num>5) return;

      .........

   }    

       可用addBatch();方法添加批處理

   int[] a=stm.executeBatch(); //執行批處理

       批處理裏放的是增刪改語句,能夠減小網絡傳輸時間;

   stm批處理裏緩存的是sql命令,如:stm.addBatch(sql);

   pstm批處理裏緩存的是數據,如:pstm.addBatch();

   Object----->db

處理大數據的類型

1,Blob------》二進制的大對象(電影,圖片,壓縮包)

2,clob-------》字符的大對象(文本小說等)

以Blob爲例

第一步:用empty_blob佔一個空位置

      String sql="insert into largetable(id,name,largefile)"

                         +" values(3,'file3',empty_blob())";

                stm.executeUpdate(sql);

第二步:查出位置

        sql="select largefile from largetable where id=3";

                rs=stm.executeQuery(sql);

第三步:讀文件而後插入數據庫

   if(rs.next()){

       Blob blo=rs.getBlob(1);  //得到結果集的列值

//強轉成Blob對象這樣纔有輸出流

      oracle.sql.BLOB bo=(oracle.sql.BLOB)blo;

       OutputStream os=bo.getBinaryOutputStream();

    InputStream is=new FileInputStream(filename);//得到文件的輸入流

       byte[] b=new byte[1024];  每次讀文件的字節數

       int len=0,num=0;

       while(true){

      len=is.read(b);  每次讀的本身長度一個數組

        if(len<=0) break;

         os.write(b,0,len); 向數據庫寫文件

         if(++num%10==0){

          System.out.println("10 k  ok");

        }}

       is.close();

       os.close();

       }       conn.commit();

   

  (類)class(entity)-------table

  (對象)object(persist object)--------row

  (屬性)field------column(oid-----pk)

  relation---------> pk  fk

   class Student{

      private Integer oid;

      String name;

      int age;

      String sex;  

      public Student(String name,int age,String sex){

               }

   }

   Student s1=new Student("zhangsan",18,"male");

   Student s2=new Student("lisi",19,"male");

   Student s3=new Student("zhangsan",20,"male");

各類關係表的創建

 one-to-one( Car ---- License ),一對一:互相保留對方的引用,既互相都以對方爲屬性。

 1.java

   class Car{ 

      //oid

      private Integer cid;    //與數據庫對應的cid不用寫進構造方法

     

      // 業務屬性

      private String manufactory;

      private String productType; 

     

      //關係屬性:其它對象作爲該對象的屬性,關係屬性不用寫進構造方法裏

      private License license;

      // get 和  set

      // 有參和無參的構造方法  

      public Car(String manufactory, String productType, License license) {

                   super();

                   this.manufactory = manufactory;

                   this.productType = productType;

         }

       public void addLicense(License license){

         this.license=license;

         license.addCar(this);

      } 

      public void removeLicense(){  

         this.license.removeCar();

         this.license=null;

      }

   }

   class License{   

      private Integer lid;

      private String serialNum;

      private String LicenseType;

      private Car car;

      // get 和  set

      // 有參和無參的構造方法  

      public void addCar(Car car){

         this.car=car;

      } 

      public void removeCar(){ 

         this.car=null;

      }

   }

   //一對一的數據庫創建

 2. db

   create table jdbc_car

   ( cid number(7) primary key,

     manufactory varchar2(15) not null,

     producttype varchar2(15) not null,

   );

   create table jdbc_license

   ( lid number(7) primary key,

     serialnum varchar2(15) not null,

     licensetype varchar2(15) not null,

     car_id number(7) references jdbc_car(cid) unique

   );

3. dao( CarDao--->jdbc_car , LicenseDao--->jdbc_license)

         //當一個程序須要用到兩個數據庫時,就要創建兩個數據訪問層(dao)

    class CarDao{

      public void insertCar(Car c) throws Exception{

         1.insert into cartable

         2.c.setCid(?);

         3.insert into license 

         4.l.setLid(?);

      }

      public void deleteCar1(Car c) throws Exception{

         1.delete from license

         2.delete from car

         3.c.setOid(null);

         4.license.setLid(null);

         5.c.removeLicense(l);

      }  

      public void deleteCar(Car c) throws Exception{

         1.update license  set  car_id=null

         2.delete from car

         3.c.setOid(null);

         4.license.setLid(null);

         5.c.removeLicense(l);

      }

      public void updateCar(Car c) throws Exception{

          1. update car table;

          2. update license table set car_id=null;

      }

      public Car queryByCid(Integer cid) throws Exception{

        db-->1.select car table

             2.select license table

        內存--> 3. car.addLicense(license);

        4.return car;

                        } 

    }

      main(){ 

         Car c=queryByCarid(222);

         c.addLicense(license);

         dao.update(c);

                     }    

  1. 維護數據庫

  2. 維護內存中的oid (insert delete)

  3. 維護關係(主要對象)

  one-to-one :

    弱耦合:  fk+uk     fk null

    強關聯:  pk+fk     fk not null  

one-to-many(Company----Employee)

 1. java

  class Company{ 

     private Integer cid;

     private String cname;

     private String address;

     private Set<Employee> employees=new HashSet<Employee>();

  }

  class Employee{    

     private Integer eid;

     private String ename;

     private Date birthday;   //  java.sql.Date

     private int age;

     private Company company;

  } 

  //一對多的數據庫創建

 2. db 

  create table jdbc_company

  ( cid number(7) primary key,

    cname varchar2(15) not null,

    address varchar2(15)

   );

  create table jdbc_employee

  ( eid number(7) primary key,

    ename varchar2(15) not null,

    birthday date ,

    age number(3),

    company_id number(7) references jdbc_company(cid)

  );   

  理性思惟,一步一步的往下作就OK了:

 3 dao

  insert(Object o){ 

    1. insert object

    2. object oid

    3. relation

  }           

  delete(Object o){ 

    1. relation

    2. delete object

    3. object oid

  }             

  update(Object o){

    1. update object field

    2. update relation( option )

  }

  Object query(value){ 

    1. query object

    2. query relation

  }

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

many-to-many       ( Course <----> Student )

 

1. java

   class Student{

      private Integer sid;

      private String sname;

      private int age;

      private Set<Course> courses=new HashSet<Course>();

   }                 

   class Course{

     private Integer cid;

     private String cname;

     private int hours;                                

     private Set<Student> students=new HashSet<Student>();

   }

 2. db                   //多對多的數據庫創建

   create table jdbc_student

   ( sid number(7) primary key,

     sname varchar2(15) not null,

     age number(3)

   ); 

   create table relationtable

   ( studentid number(7) references jdbc_student(sid),

     courseid  number(7) references jdbc_course(cid),

     primary key(studentid,courseid)

   );

   create table jdbc_course

   ( cid number(7) primary key,

     cname varchar2(15) not null,

     hours number(5)

   );

 3. dao

    StudentDao    CourseDao

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

 inheritance ---> pojo

 1. java

    class Account{   

       private Integer id;

       private String name;

       private String passwd;

       private String cardId;

       private double balance;

       private String personId;

    }

    class SavingAccount extends Account{

       private String cardType;

       public SavingAccount(String name,String passwd,

            String cardId,double balance,

            String personId,String cardType){ 

          super(name,passwd,cardId,balance,personId);

          this.cardType=cardType;

       }

    }

    class CreditAccount extends Account{ 

       private double overdraft;

    }

2. db ---> one table           //一個超級大表

    create table inheritance_account

    ( id number(7) primary key,

      name varchar2(15) not null,

      passwd varchar2(15) not null,

      cardid varchar2(15) not null unique,

      balance number(10,2),

      personid char(18) not null unique,

      cardtype varchar2(10),

      overdraft number(5),

      atype varchar2(3)

    ); 

3. dao

   class AccountDao{

     public void insert(Account a){

        sql= insert into inheritance_account(.......);

        pstm.setInt(1,....);

        pstm.setString(2,a.getName());

        pstm.setString(3,a.getPasswd());

        pstm.setString(4,a.getCardId());

        pstm.setDouble(5,a.getBalance());

        pstm.setString(6,a.getPersonId());  

        if(a instanceof SavingAccount){ 

           SavingAccount sa=(SavingAccount)a;

           pstm.setString(7,sa.getCardType());

           pstm.setDouble(8,null);

           pstm.setString(9,"SA");

        }else{

          .....

        }

        a.setId(...);

     }

     public void delete(Account a){ 

        sql= delete from table where id=?

        pstm.setInt(1,a.getId());

        pstm.executeUpdate();

     }  

     public void update(Account a){  

        sql= update table set ........ where id=?

        pstm.setString(1,a.getName());

        ................

        pstm.setString(5,a.getPersonId());

        if(a instanceof SavingAccount){

           SavingAccount sa=(SavingAccount)a;

           pstm.setString(6,sa.getCardType());

           pstm.setDouble(7,null);

        }else{       

          ......

        }

        pstm.setInt(8,a.getId());

     }

     public Account queryByCardId(String cardId){

       sql=select id,name,passwd,cardId,balance,personId,cardtype,overdraft,atype

           from table where cardid=?

       pstm.setString(1,cardId);

       rs=pstm.executeQuery();

       if(rs.next()){    

          String type=rs.getString(7);

          if(type.equals("SA"){

            SavingAccount sa=new SavingAccount();

            sa.set****;

          }else{  

            ca.set****

          }

       }

     }

     public Account queryById(Integer id){

     }

   }

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

jobs:

  1. license dao    ----> self

  2. employee dao   ----> self -->update(){self relation}

  3. companydao----> queryByCname()

  4. cardao------> delete2(),queryByCid2()

  5. 改寫bam

     1) value object

     2) dao ---> delete(Account a)

     3) data---->db

     4) biz,view不改

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

1.基本六個步驟

2. Statement 和 PreparedStatement

3. JdbcUtil

    1) ThreadLocal   2) 配置文件

    3) 虛擬路徑( Class.getResourcAsStream())

   

    1) 分散代碼集中管理

    2) 變化的數據寫進文件

4. Transaction

    1)API   2) ACID     3)併發問題   4)隔離級別   

5. Jdbc2.0

    1) Batch

6. ormapping:

   1) dao 步驟

   2) 各類關係表的創建    

7. 1)數據備份時提升效率的方法 

   2)數據分頁  

8.Driver的四個發展階段

 

 

 

 

 

 

 

 

 

 

 

Hibernate


第一&二天:

ORM,即Object-Relationl Mapping,它的做用是在關係型數據庫和對象之間做一個映射,這樣,咱們在具體的操做數據庫的時候,就不須要再去和複雜的SQL語句打交道,只要像平時操做對象同樣操做它就能夠了(把關係數據庫的字段在內存中映射成對象的屬性)

1  hibernate---->ormapping

   1) CRUD    2)HQL    3)mapping file    4)性能  

2 基於hibernate的應用步驟:

  1)javabean(pojo)

  2) relation db  -----> create table

  3)mapping file( object----table )

filename.hbm.xml ----> 跟javabean放在一個路徑

   <hibernate-mapping package="packagename">  

     <class name="classname" table="tablename">

<id name="oidname" column="pkname" unsaved-value="null">

          <generator class="生成器classname"> 

            <param name="type"> value </param>

          </generator>

        </id>

<propertyname="javaproperty" column="dbcolumnname"></property>

     </class>  

     <class>.....</class>

   </hibernate-mapping>

 4) configure file ----> classpath(src)

    hibernate.cfg.xml

    <hibernate-configuration>

      <session-factory>

        <property>

        <mapping resource="filepath">    

 5) application ( base hibernate )

    a.  start hibernate

       Configuration cfg=new Configuration().configure(...);

    B . create sessionfactory

       SessionFactory sf=cfg.buildSessionFactory();

    c.  open Session

       Session sess=sf.openSession(); 

    d.  begin Transaction

       Transaction ta=sess.beginTransaction();

    e.  persist object  

       sess.save(Object o);    oid=null   ;  insert

       sess.delete(Object o);  oid!=null     delete

       sess.update(Object o);  oid!=null     update

       Object o=sess.get(classname.class,id);

    f.  ta.commit()/ta.rollback()

    g.  release resource

       ( sess , sf )   -----   sess

    sess: 線程不安全

    sf: 線程安全, 重量級的組件      

3 hilo

   1) create table  hilotable

     ( value number(7) );

      insert into hilotable

      values(1);

   2) <generator class="hilo"> 

        <param name="table">hilotable</param>

        <param name="column">value</param>

      </generato>    

     

      name= java name

      class= java type

      type= hibernate type (lower)

      table , column= db name (insensitive)   

---------------------one-to-one---------------

1. javabean  ( 雙向(bi),單向 (ui))

2. create table ( fk+uk , pk+fk )

3. mapping file

4. change configure file

5. java app  

    property-ref="car"

  1)雙向的一對一

  2) 沒有寫property-ref, 沒有寫cascade

      sess.update(car);

      a. update  jdbc_car set ***** where cid=?

      b. update  jdbc_license set car_id=? where lid=?

      

     沒有寫property-ref, 有寫cascade

      sess.update(car)

      a. update jdbc_car set **** where cid=?

      b. update jdbc_license set car_id=?  where lid=?

      c. update jdbc_license set sn=?,lt=?,car_id=? where lid=?

  

 有寫property-ref, 有寫cascade

      a.update jdbc_car set **** where cid=?

      b.update jdbc_license set **** where lid=?

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

   class People{

      Integer id;    

      String name;

      int age;

      Set<Hand> hands=new HashSet<Hand>();

   } 

   class Hand{}    

  1. one-to-one  fk+uk(單向)

  2. one-to-one  pk+fk(單向)

  3. one-to-many (單向)

  4. many-to-many (javabean  table  mappingfile)

 

 

 


第三天:==================================

1. 標籤:  類驅動表,真實反應Java裏的類,即:以類爲主

  hibernate-mapping---->package

  class ----> name  table

  id ----> name column  unsaved-value

  generator----> class

  param ----> name

  property----> name  column  unique  not-null  type

  one-to-one----> name  property-ref  cascade   constraint

  many-to-one---> name  column  unique  cascade

  set----> name  table   cascade  inverse

  key----> column

  one-to-many---> class   

2 id 生成器類的別名:

   sequence ,  hilo  , sequencehilo  ,  foreign

   assigned ,  increment ,  identity(mysql) , native

   3 assosiation:

  ===============================

1) one-to-one

     a. fk+uk 

       <class name="Car"....>   

       <one-to-one name="license" property-ref="car"  cascade="save-update"/>

       </class>

       <class name="License"....>   

          .......

          <many-to-one name="car" column="car_id"  unique="true" cascade="save-update"/>

       </class>

     b. pk+uk

      <class name="Car"....>   

         <id> ....</id>

         .....

         <one-to-one name="license" property-ref="car"

            cascade="all"/>

       </class>

       <class name="License"....>   

          <id name="lid"........>

            <generator class="foreign">

             <param name="property"> car</param>

            </generator>

          </id>

          ...

          <one-to-one name="car" constrained="true"

             cascade="save-update"/>

       </class>  

2) many-to-one

    <class name="Company"....>   

      ......

      <set name="employees" table="jdbc_employee">

        <key colum="company_id"/>

        <one-to-many class="Employee"/>

      </set>

    </class>

    </class name="Employee"...>  

      .....

      <many-to-one name="company" column="company_id"

         cascade="save-update"/>

    </class>    

   

  當寫雙向級聯關係時,肯定只有一方維護關係,(通常多的一方維護關係)

   1 one-to-one  用 property-ref

   2 one-to-many  many-to-many     inverse="ture"

一的一方要 設 <set (inverse="false") casecade="save-update" />,多的一方要設<many-to-one inverse=true (casecade="none") />

兩邊都用true或都用false都是不對的,關係最好讓一方維護

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

 many-to-many

 1.     javabean

    class Student{

                            private Integer sid;

                            private String sname;

                            private int age;

                            private String sex;

                            private Set<Course> courses=new HashSet<Course>();

    }

   class Course{

     private Integer cid;

     private String cname;

                    private int hours;

     private Set<Student> students=new HashSet<Student>();

   } 

 2  db table

   create table hibernate_student

   ();

   create table hibernate_relation

   ();

   create table hibernate_course

   ();    

 3 mapping file

         <class name=」Student」 table=」hibernate_student」>

        <id name=」sid」 column=」sid」  unsaved-value=」null」>

        </id>

        <property name=」…」/>

        <set name=」courses」 table=」hibernate_relation」

                                     cascade=」save-update」 inverse=」true」>

     <key column=」student_id」/>

       <many-to-many class=」Course」 column=」course_id」>

        </set>

         </class>

         <class name=」Course」 table=」hibernate_course」>

        <id name=」cid」 column=」cid」  unsaved-value=」null」>

        </id>

        <property name=」…」/>

        <set name=」students」 table=」hibernate_relation」

                                               cascade=」save-update」>

       <key column=」course_id」/>

       <many-to-many class=」Student」 column=」student_id」 />

         </class>

 

1.student and course 沒有inverse=true 就會多一次維護關係

         student and course  都有cascade   

         update(student)

                   1)update student table

                   2)update relation table

                   3)update course table

                   4)update relation table   就會多一次維護關係

  

2.student and course 有inverse=true 就不會維護關係

         student and course  都有cascade   

         insert(student)

                   1)insert student table

                   2)insert course table  

                  

3.student有inverse=true  一方維護關係才正確

         course 沒有 inverse=true

         student and course  都有cascade         

  update(student)

         1)update student table

        2)update course table

        3)update relation table

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

sess.beginTransaction();

sess.save(Object);

   1. insert student table

   2. stm.addBatch(sql1);

   3. insert course table

   4. stm.addBatch(sql2);

   5. insert relation table

   6. stm.addBatch(sql3);

   7. stm.executeBatch();

 ta.commit;

 catch(Exception e){ta.rollbacka();}       

 ===========================================

 得到線程安全的session

 1. 修改配置文件

   <property name="current_session_context_class">thread</property>

 2.在java程序裏獲取session時

   Session sess=sf.getCurrentSession();

 session特色:

 1) 線程安全     

 2) sess在事務結束時會自動關閉,一個事務用一個sess,當數據量過多時,

         能夠用sess.flush(); 將緩存的sql命令發往數據庫執行,執行結果保存在回滾段.

 

 

 

 

 

 

 

 

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

persist:

  Session:一級Cache (緩存session操做過的全部對象 )

  SessionFactory: 二級Cache ,用安全的session時,儘可能使sf關閉時,線程也要關閉;

   (緩存生成的sql,以及hibernate管理過的部分對象

 

Hibernate的對象狀態,即生命週期

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.Transient(臨時,暫時)

  Student s1=new Student("zhangsan",18);

 1)在數據庫裏沒有對應的記錄

  2)通常狀況下,沒有數據庫惟一標識符

      特殊狀況 1)assingned 臨時對象,即新建(new)對象

              2)sess.delete(o)   對象已被刪除

              3)不在Session裏面

     

2.persist(持久化狀態)

  sess.save(s1);  saveOrUpdate()

  Student s2=sess.get(Student.class,123); 

  1)在數據庫裏有對應的記錄

  2)有數據庫惟一標識符  

  3)在Session裏面 

 

3.detached(遊離,脫管狀態)  

  sess.close(); sess.clear();sess.evict()

  1)在數據庫裏有對應的記錄 

  2)有數據庫惟一標識符  

  3)不在Session裏面 

 

Session保留備份(兩個集合)

 class SessionImpl implements Session{

     private LinkedList  entities=new LinkedList();   //實體集合,用於存放臨時對象

     private LinkedList  copy=new LinkedList();  //深度拷貝集合,跟集合的數據同樣,能夠減小訪問DB

     public Serializable save(Object o){  

        1.Serializable pk=.......

        2.db insert

        3.entities.add(o);   

        4.copy.add(o.deepcopy);

        5.return pk;

     } 

    

public void delete(Object o){

        1.db delete

        2.entities.remove(o); 

        3.copy.remove(o.deepcopy);

     } 

     public void close(){

        entities.removeAll();

        copy.removeAll();

     }         

     public void evict(Object o){

        entities.remove(o);

        copy.remove(o.deepcopy);

     }

 }

 sess保留備份的做用:

   優點:

   1) 查詢同一個對象,不用再訪問數據庫,

      直接返回sess裏的數據

   2) 髒的檢測,當檢測到實體集合與深度拷貝集合裏的數據不一樣時,會把改變的對象同步到數據庫裏。

    Student s=new Student("zhangsan",18);

    sess.save(s);

    s.setName("lisi");

    sess.close(); (sess.update(s))  -----> db s name="lisi",在sess關閉前會自動更新髒的數據到db裏。

   

    <class name="Student" table="" dynamic-update="true">

    s.setName("wangwu");

    sess.update(s);    

    1)sess=HibernateUtil.getSession();

      ta=sess.beginTransaction();

      Student s4=new Student("zhangsan",18);

      sess.save(s4);

      s4.setName("lisi");  

      ----> sess沒有關閉前,髒的檢測起做用

      ta.commit();

      db---------> name="lisi" 

    2)sess=HibernateUtil.getSession();

      ta=sess.beginTransaction();

      Student s4=new Student("zhangsan",18);

      sess.save(s4);

      ta.commit();   ----> sess關閉

      s4.setName("lisi");  ----->s4 此時已處在遊離狀態

      db---------> name="zhangsan"  

    3)sess=HibernateUtil.getSession();

      ta=sess.beginTransaction();

      Student s4=new Student("zhangsan",18);  --->臨時

      sess.save(s4);               -----> 持久

      ta.commit();                ---->s4 遊離

      ta2=HibernateUtil.beginTransaction(); --->新的sess

      s4.setName("lisi");    ----->s4 遊離

      ta2.commit;           ---> 關閉新的sess

      db----------->name="zhangsan"

    4)sess=HibernateUtil.getSession();

      ta=sess.beginTransaction();

      Student s4=new Student("zhangsan",18); --->transient

      sess.save(s4);                         --->persist

      sess.evict(s4);                        --->detached

      s4.setName("lisi");  

      ta.commit();                           --->sess.close

      db---------> name="zhangsan" 

       缺點:不適合作大量數據的插入或者修改       

     Student s=new Student("zhangsan",18); -->transient

    sess.save(s);                         -->persist

    sess.evict(s);                        -->detached

    sess.delete(s);    

    detached--->persist--->transient  

  jobs:

   1. m2m---> javabean  table  mappingfile  dao  biz  test

   2. 如何得到線程安全的session

   3. 三種狀態,以及它們之間的轉換

   4. sess髒的檢測

   5. 測試get和load

 

 

 

 

 


第四天:=======================================

1 many-to-many

  1) java 

    class Student

      Set<Course> courses

    class Course

      Set<Student> students  

 2)db

   hibernate_student   relationtable  hibernate_course

       sid             studentid cid       cid

 3)

  <class name="Student" table="hibernate_student">

    <id name="sid..>

    <property>  

    <set name="courses" table="relationtable"  inverse="true" cascade="save-update" >

      <key column="studentid" >

      <many-to-many  class="Course"  column="cid"> 

</set>

  </class>

  <class name="Course" table="hibernate_course" >

    <id.....>

    <property> 

    <set name="students" table="relationtable"

cascade="save-update">

       <key column="cid">

       <many-to-many .....>

    </set>

  </class>  

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

2. hibernate---->ormapping  (object-->db)

   hibernate--->dao

   connection---> not safe ---> ThreadLocal<Connection>

   Session---->not safe---> ThreadLocal(Session)

     1) ThreadLocal<Session>

     2) current_session_context_class   thread

        Session sess=sf.getCurrentSession();

        線程安全,一個事務一個sess,事務結束會自動關閉sess

        ta=sess.beginTransaction();

        Student stu=new Student();

        sess.save(stu);

        ta.commit(); 

   dao: save()   update()   delete()    get()

        saveOrUpdate()

3.Persist

  1)Transient:

      id=null ( assigned ,  sess.delete() )---->saveOrUpdate()

      not in sess

      not in db----not row

        Persistance 

      in db ---- row

      id!=null

      in sess

    Detached

      in db----row

      id!=null

      not in sess 

  2) 一級cache(Session)----> 集合

     session有兩個集合(entities,deepcopy)  

     a.緩存操做過的對象,加快查詢速度  

       sess.get(Student.class,14);

       get--->一級cache---->db

     b.髒的檢測(關閉時)

       在內存中改變對象屬性:

        顯示調用update():detached

        隱含調用update():Persistance(已經持久化的對象,若是被修改,就會隱含調用)

 3)狀態圖

4 Student s=new Student();

   持久化s;

   1) sess.save(s)   sess.saveOrUpdate(s)

   2) 利用持久化對象的擴散

      sess=sf.getCurrentSession();

      Course c=sess.get(Course.class,18);

      c.getStudents().add(s); 

      sess.update(c);

      ta.commit(); 

    A--->B--->C--->D

    save(A);  

    cascade:                     

     a. none(default)

     b. save-update  

     c. all ( save-udpate-delete )  

     d. delete

     e. delete-orphan

        com1-------> delete

        emp1  emp2  emp3 ----> delete-orphan

        delete(com1); ---> emp1 emp2 emp3

        delete(emp1);  --->emp1  

 5 查找Student s

   1) query by id ( get() or  load() )

     Student s=sess.get(Student.class,10);

     Student s=sess.load(Student.class,10);

    

     class SessionImpl implements Session{

        public Student get(Class c,Serializable id){

            1. sql= " select * from student where id=? ";

            2. Student o=data

            3. return o;

                 }

        public Object load(Class c,Serializable id){

             Student s=c.newInstance();

             s.setId(id);

             return s;

                }

          }

     getload

     a. get時先查詢Session的Cache,若是cache裏面沒有,

        再生成sql語句查詢數據庫,默認查詢全部的值 

       

        load先在內存中生成一個只有oid的對象, 且返回

        沒有查詢db,須要其餘屬性時再去查db 

       

     b. get回來的對象,全部的屬性均有值

        load回來的對象只有oid有值,其餘屬性爲null 

    

     c. get---->Student

        load----> SubStudent(cglib.jar)

  

  2) 曲線查詢:

     Student s;

     Course c=sess.get(Course.class,167);

     for(Student s: c.getStudents()){   

        System.out.println(s.getSname());

     }   

 

  3)Query(interface)-----> Hibernate查詢語言:hql(Hibernate query language)

    String hql="from Student s where s.sid>150";

    Query q=sess.createQuery(hql);

    List l=q.list();

 

batch insert/update:9999

  1) sess=sf.getCurrentSession();

    ta=sess.beginTransaction();

    String hql="from Student s";

    List stus=sess.createQuery(hql).list();

    sess.setFlushMode(FlushMode.COMMIT);

    for(int i=1;i<=stus.size();i++){

       if(i%50==0){

          sess.flush();   // batch 裏緩存多少sql命令

            將緩存的sql命令發往數據庫執行,執行結果保存 在回滾段

          sess.clear();

            清空一級cache

       }

       stus.get(i).setName("hello"+i);

       sess.update(stus.get(i));

    }

    ta.commit();      // 回滾段的內容寫回數據文件

    

    1)   存放臨時對象1000塊

 2) Session裏面留有1000個備份對象

 3) hibernate自動使用batch,緩存1000條sql

 

    默認狀況下一個事務一個batch,flush()之後,把一個事務

    劃分紅若干個batch    

   

  2) sess=sf.getCurrentSession();

     ta=sess.beginTransaction();

     String hql="update Student s set s.sname=?";

     Query q=sess.createQuery(hql);

     q.setString(1,"haha");

     q.executeUpdate();    

     ta.commit();                  

    

  總結: Session( entities  deepcopy )

  1. 三種狀態

  2. 持久化一個對象

      save   saveOrUpdate

      persistance(持久保存) object   ---->髒的檢測

  3. 查詢對象:

     1) get  load              ----> 加快速度

     2) relation object    //關係對象

     3) hql       

 

  4. batch update/insert

     1) query----> change----> update

        batch_size  flush()   clear()

     2) hql

    

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

 interfact Transaction{

    public Transaction beginTransaction();

    public void commit();

    public void rollback();

 }  

 class JdbcTansaction implement Transaction{

   public Transaction beginTransaction(){

     .......

     conn.setAutoCommit(false);

   }

    public void commit(){

       conn.commit();

    }

    public void rollback(){

       conn.rollback();

    }

 }     

事務的併發控制

1、多個事務運行時的併發問題

       併發問題概括爲如下幾類:

1    第一類丟失更新:撤銷一個事務時,把其餘事務已經提交的更新數據覆蓋。

2    贓讀:一個事務讀到另外一個事務未提交的更新數據。

虛讀:一個事務讀到另外一個事務提交的新插入的數據。

4    不可重複讀:一個事務讀到另外一個事務已經提交的更新數據。事務A對統一數據重複讀兩次卻獲得不一樣的結果,有可能在A讀取數據的時候事務B對統一數據作了修改

5     第二類丟失更新:這是不可重複讀中的特例,一個事務付給另外一個事務已提交的更新事務。

二數據庫系統提供了四種事務隔離級別供用戶選擇:

A.Serializable(串行化):一個事務在執行過程當中徹底看不到其餘事務對數據庫所作的更新。

B.Repeatable Read(可重複讀):一個事務在執行過程當中能夠看到其餘事務已經提交的新插入的記錄,可是不能看到其餘其餘事務對已有記錄的更新。

C.Read Commited(讀已提交數據):一個事務在執行過程當中能夠看到其餘事務已經提交的新插入的記錄,並且能看到其餘事務已經提交的對已有記錄的更新。

D.Read Uncommitted(讀未提交數據):一個事務在執行過程當中能夠拷打其餘事務沒有提交的新插入的記錄,並且能看到其餘事務沒有提交的對已有記錄的更新。

隔離級別越高,越能保證數據的完整性和一致性,可是對併發性能的影響也越大。對於多數應用程序,能夠有優先考慮把數據庫系統的隔離級別設爲Read Commited,它可以避免髒讀,並且具備較好的併發性能。儘管它會致使不可重複讀、虛讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,能夠由應用程序採用悲觀鎖或樂觀鎖來控制

在hibernate.cfg.xml中設置隔離級別:

<session-factory>
   <!-- 設置隔離層次,併發,缺省時Read Committed: 2 -->

   <property name="connection.isolation">2</property>

<!-- 配置事務實現類 -->

 <property name="transaction.factory_class">

org.hibernate.transaction.JDBCTransactionFactory </property>
       </session-factory>

 

悲觀鎖: 在查詢時加

 1. Student s=sess.get(Student.class,id,LockMode.UPGRADE);

   五種模式

   LockMode.NONE: 查詢時先在cache(緩存)裏找,若是沒有,再到db里加載  無鎖機制。

   LockMode.READ: 無論cache有沒有,都查詢數據庫,Hibernate在讀取記錄的時候會自動獲取。

   LockMode.UPGRADE: 無論cache有沒有,都查詢數據庫,而且 對查詢的數據加鎖,若是鎖被其餘事務拿走, 當前事務會一直等到加上鎖爲止. 利用數據庫的for update子句加鎖。

   LockMode.UPGRADE_NOWAIT: 無論cache有沒有,都查詢數據庫,而且對查詢的數據加鎖, 若是鎖被其餘 事務拿走,當前事務會馬上返回.  ,hiberna Oracle的特定實現,利用Oracle的for update nowait子句實現加鎖             

   LockMode.WRITE:。在作insert,update,delete會自動使用模式.內部使用

                  

 2 .  如下狀況用悲觀鎖:查詢數據時,就給數據加鎖

     1)數據資源被多個事務併發訪問的機會很大

     2)修改數據所需時間很是短 

樂觀鎖,大可能是基於數據版本 (Version)記錄機制實現

1在javabean中加上version的屬性提供set和get方法

2,在數據庫表上加上vershion列

3在映射文件的<id></id>後加上<version>

<version name=」version」 column=」version」/>

 

實現原理:讀取出數據時,將此版本號一同讀出,以後更新時,對此版本號加一。此時,將提 交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,若是提交的數據 版本號大於數據庫表當前版本號,則予以更新,不然認爲是過時數據。

 

 

 

 

第五天:=================================================================================

Inheritance:

 1. javabean

    Account  ---> SavingAccount  CreditAccount

 2. db

    1)one table 

    2)one class one table

    3)subclass---->table

 3. mapping file   

1) one table

<class  name="Account" table="inheritance_table"

                 discriminator-value="AC" >

          <id>  

          <discriminator column="atype" type="string" length="3"/> 在數據庫加一列atype用來分開各類不一樣的父類和子類

          <property>

          <subclass name="SavingAccount" discriminator-value="SA">  

            <property name="">         子類的特別屬性discriminator-value="SA"默認值是SA

          </subclass> 

          <subclass name="CreditAccount" discriminator-value="CA">  

            <property name="">

          </subclass>

       </class>

   2) one class one table 每一個類都有一個表 子類的主鍵同時是父類的外鍵 即父表的主鍵也子表主鍵同樣

      <joined-subclass name="SavingAccount" table="hibernate_savingaccount">

                <key column="id"></key>

                <property name="cardType"></property>

       </joined-subclass>

   3) one subclass one table每一個子類一張表

     <class name="Account" abstract="true">    抽象父類不能new對象,父類沒有對應的表

           <id name="id" column="id" unsaved-value="null">

         <generator class="sequence">

            <param name="sequence">account_seq</param>

         </generator>

       </id>  

       <property name="name"></property>   父類的屬性

      <union-subclass name="SavingAccount" table="hibernate_savingaccount">

        <property name="cardType"></property>

      </union-subclass>

      <union-subclass name="CreditAccount" table="hibernate_creditaccount">

        <property name="overdraft"></property>

      </union-subclass>

      

  </class>

 4. change config file

 5. dao     

    public void insertAccount(Account a){

       sess.save(a);

    }

 6. biz

 7. view

 8. test     

 

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

 class Person{

   private Integer id;   ------> oid

   private String name;  ------>業務屬性

   private int age;  

   private Head head;   ---->業務屬性 

   private Set<Hand> hands=new HashSet<Hand>();  ---->業務屬性

   private Computer computer; ---->關係屬性  

   private Set<Book> books=new HashSet<Book>();---->關係屬性

 } 

 class Hand{

   private String finger;

 }

 class Book{

   private Integer id;

   private String bname;

 }

 class Head{

    private String eye;

 }  

 class Computer{

   private Integer id;

   private String Screen;  

   private Person person;

 }

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

如下標籤和屬性要結合着映射文件看和理解hibernate

base(基礎):

   hibernate-mapping:表示映射文件的根標籤 --> package:表示要映射的類所在的包。

  

   class:該標籤下包含映射的類和DB裏的表--> name:要作映射的類  table:對應DB裏的表 ;

                 optimistic-lock:常常與version連用,做用是一個數據被多個事務訪問時,

                                   若是其中一個事務修改了DB數據,那麼其它事務將不能獲得提交數據,只能從新訪問DB;

                      1 none 無樂觀鎖2 version 經過版本機制實現樂觀鎖

3  dirty 經過檢查發生變更過的屬性實現樂觀鎖4 all 經過檢查全部屬性實現樂

                 dynimic-update:默認值爲"false",當值爲"true"時表示更新被修改的列,而不全表更新;

                 abstract:表示要映射的類是抽象類,不能new對象,只能用他的實現類,不然hibernate會報錯;

                 lazy:表示延時加載,即用到DB裏的數據時纔去DB里加載,默認爲"true"。

  

   id:---> name:表示在類裏的對應的屬性名;  column:表示在DB表裏對應的列名;

                           unsaved-value:未存進DB前或當id爲臨時對象時,默認爲null;

    generator:表示生成器標籤 ---> class:是用哪一種生成器,在Oracle裏是系列(sequence)。

  

   param:參數標籤 ---> name:指代用什麼配置或初始化生成器的值。

  

   property:該標籤用於屬性與表裏的映射----> name:對應類裏的屬性名;

               column:對應DB表裏的列名;  unique:表示DB表裏的列的值是否惟一;

           length:表示DB裏那一列的數據存放長度;  type:DB裏那一列的數據存放類型;

           not null:DB裏那一列的數據是否能夠爲空。

   version:該標籤常常與樂觀鎖連用,表示其它事務是否修改DB裏的值--->

                 name:在類裏對應的屬性名; column:DB裏對應的列名。

assosiation(關聯):在類裏是一個類的屬性是別一個類的類型,在DB裏是多表關聯。

   one-to-one--> name:表示在類裏對應的屬性名;constrained:表示該屬性必須有值;

       property-ref:表示只維護該表裏的屬性列,而不維護以該表的ID爲外健的其它表;

 cascade:級聯操做,即級聯關係屬性,當值爲"save-update"時表示更新A表時,也更新與之對應的B表,(cascade在A表)。

   many-to-one-->name:表示在類裏對應的屬性名;  column:表示在DB表裏對應的列名; lazy:表示當用到該類的對象(A)的屬性(name)時,

會自動去DB里加載這個屬性對應的行,並用這行生成對象保存在該類的對象(A)的屬性裏。

                 cascade  unique

   one-to-many--> class:在類裏對應哪一個類;

   set:該標籤表示類裏的屬性是set集合----> name:表示set集合在該類裏的名稱;

                 table:表示set集合裏的數據在DB裏對應哪一個表;

                 cascade:表示更新cascade所在的表時,級聯更新table對應的表(或name屬性所在的表);

                 inverse:表示只維護該表裏的屬性列,而不維護以該表的ID爲外健的其它表;

                

   key:該標籤表示外健 ----> column:表示表裏的外健名;

  

   many-to-many----> class:在類裏對應的類;column:在表裏對應的外健。

  

inheritance(繼承):

  subclass:用於多個子類作成一張表時 ---> name:表示在類裏對應的子類名; 

                           discriminator-value:在DB表裏對應的列的值;

  discriminator:該標籤用於描述discriminator-value ---> column:表示該值在哪一列 ;

                           type:在DB裏是什麼樣的數據類型; length:在DB裏以什麼樣的長度存儲的。

                          

  joined-subclass:一個類一個表--->name:表示在類裏對應的子類名;  table:在數據庫裏對應哪一個表;

  union-subclass:一個子類一個表---->name  table

 

valuetype(值類型):沒有oidJava對象(某個對象的業務屬性,離開該對象沒法存在)

component:該標籤表示該類(comA)是另外一個類(A)的某一部分(屬性)--->name:表示comA類在A類裏的名字;

   parent:該標籤表示屬於哪一個類---> name:在comA類裏的屬性名;

 set-->.....

   element:值元素(如在map標籤裏表示值對象)---> type:在對象在DB裏存的數據類型;  column:在DB裏對應哪一列;

  

   list ---> name  table

   list-index:表示list集合的下標(在數據庫中自動生成)---> column:對應DB裏table值的哪一列

   idbag:hibernate裏特有的一個集合標籤,可重複無序。----> name  table   

   collection-id:表示給一重複數據的區別---> column:對應DB表裏的哪一列;

   composit-element:該標籤表示裏面的數據是某一集合的組成元素---> class:表示該集合裏的元素是屬於哪個類的; 

map----> name:表示map集合在該類裏的名稱;  table:表示map集合裏存的數據在DB裏對應哪一個表;

 map-key:map集合裏的健對象---> column:表示健對象對應table表裏的一列; type:表示健對象的類型;

query

 

 

 

第六天:==================================

1.optimistic-lock

  1) old: <class  optimistic-lock="all/dirty/version"

                  dynimic-update="true"> 

  2) new: a. javabean ---->version(int)

          b. table----->version(number)

          c. mapping file---> <version> (緊跟在<id>)

2. 1)javabean ---> extends

   2)db ----> a. one table

                ( pk, 父類共性 , 各個子類特性 , 類型 )

              b. one class one table

                父表( pk  共性)

                子表( pk-fk  特性)  

              c. one subclass one table

                 表( pk  共性  特性 )

                 表 ( pk  共性  特性 )

   3) mapping file

      a. one table

       <class>         

         <discriminator column="colname" type="string">

         <subclass name="subname" discrinator-value="SA">

         </subclass>

       </class>      

       b. one class one table

     <joined-subclass name="subname" table="subtablename">

            <key columm="">

            <property>

         </joined-subclass>   

      c. one subclass one table

        1) <class>  <class>

        2) <class name="fatherclassname">

             共性

             <union-subclass name=""  table="">  

                特性

             </union-subclass>

           </class>      

3. valuetype 值對象 (沒有oidjava對象)

  1) one value ---> component (兩個類一張表)

     db: pk  簡單類型   v1property1    v1property2

     mapping:  <component name="javavaluetype name">

                 <parent>

                 <property>

               </component> 

  2) one collection  (兩個類兩張表)

     set:  java---> Set<String>

           db-----> table( id(fk)  value  pk(id,value))

           mapping--->

            <set name="setname" table="">

              <key column="id">//外鍵

              <element column="value" type="string">

     list: java---> List<String>

           db-----> table( id(fk) index  value  pk(id,index))

           mapping--->

            <list name="listname" table="">

              <key column="id">

              <list-index column="index"> 自動生成下標

              <element column="value" type="string">

 

 

 

    idbag: java---> List<String>

           db-----> table( id(fk) key(pk)  value )

           mapping--->

            <idbag name="listname" table=""> 

              <collection-id column="key">

                <generator>

              <key column="id">

             <element column="value" type="string">

  3) one map 

    java---> Map<String,String>

    db-----> table( id(fk) key  value  pk(id,key))

    mapping--->

      <map name="setname" table="">

      <key column="id"> 

      <map-key column="key">

      <element column="value" type="string">    

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

1.query object(Employee): Company--Employee

  1) Company c=sess.get(Company.class,18);

     Set<Employee> employees=c.getEmployees();  

  2) query oid;

     Employee e=(Employee)sess.get(Employee.class,18);

     Employee e=(Employee)sess.load(Employee.class,18);

  3)hql

    String hql="from Employee e where e.name='zhangsan'";

    Query q=sess.createQuery(hql);

    List<Employee> es=q.list();     

    mapping file:

     <query name="querybyname">

        <![CDATA[ from Employee e where e.name='zhangsan']]>

     </query>

    java: Query q=sess.getNamedQuery("queryname"); 

  4) Criteria

     Criteria ct=sess.createCriteria(Employee.class);

     Criterion ce1=Expression.eq("name","zhangsan");

     Criterion ce2=Expression.like("address","W%");

     ct.add(ce1);

     ct.add(ce2);

     List<Employee> es=ct.list();  

  5) 本地sql

    str="select e.NAME as {emp.name},e.AGE as {emp.age}

                 from EMPLOYEE e where e.NAME='zhangsan'"; 

    SQLQuery sq=sess.createSQLQuery(str);

                   sq.addEntity("emp", Employee.class); 

                   str=" select {e.*} from EMPLOYEE e where e.NAME='zhangsan'"; 

    sq.addEntity("e",Employee.class); 

2. 支持多態查詢

   public Account queryById(Integer id){

      String hql="from Account a where a.id=?"

      Account a=query.list().get(0);

   }

3.排序(list()iterate()):

   hql1="from Employee e order by e.eid";   

   Query q1=sess.createQuery(hql1);

   List<Employee> es1=q1.list();  

   hql2="from Employee e where e.age>30"; 

   Query q2=sess.createQuery(hql2);

    List<Employee> es2=q1.list();

        // select * from Employee where e.age>30; --->sql

   Iterator<Employee> et=q.iterate(); --->效率高 

         // select e.eid from employee e where e.age>30--->sql

4. 數據分頁:

   1)sql--->rownum

   2)jdbc---> ResultSet

   3)hibernate--->

     hql="from Employee e order by e.start_date";

     Query q=sess.createQuery(hql);

     q.setFirstResult(5);//從結果集q中的第五行開始

     q.setMaxResult(5);  //獲得五行

     List<Employee> es=q.list();

     list.size===5; 

     q.setFirstResult(5);

     q.setMaxResult(1);

     Employee e=q.uniqueResult();

根據pk查詢

5.根據條件查詢(where)

  hql=" from Employee e "+"where..."

  1)where e.name='zhangsan'

    where lower(e.name)='zhangsan'

  2)where e.age<30

  3)where e.age between 30 and 60

  4)where e.age in(30,40,50)

  5)where e.name like 'S%'

  6)where e.salary>1000 and e.dept_id=41

    where e.salary>1000 or e.dept_id=41

  7)where e.address is null

  8)!= , not between and , not in  ,not like ,is not null

6. 參數綁定:

  1) hql=" from Employee e where e.name=?";

     Query q=sess.createQuery(hql);

     q.setString(1,"zhangsan");

  2) hql=" from Employee e where e.name=:name";

     Query q=sess.createQuery(hql);

     q.setString("name","zhangsan");

     Company c=(Company)sess.get(Company.class,18);

     hql="from Employee e where e.company=:com";

     Query q=sess.createQuery(hql);   

     q.setEntity("com",c);

     public List<Student> query(String name,Integer age){

      StringBuffer sb=new StringBuffer("from Student s ");

      if(name!=null) sb.append(" where s.name=:name");

      if(age!=null && name!=null)

         sb.append(" and s.age=:age");

      if(age!=null && name==null)

         sb.append(" where s.age=:age");

      Query q=sess.createQuery(sb.toString()); 

      if(name!=null) q.setString("name",name);

      if(age!=null)  q.setInt("age",age);

      return q.list();

   }

   public List<Student> query2(String name,int age,String address,String sex){

      Student s=new Student();

      s.setName(name);

      s.setAge(age);

      s.setAddress(address);

      s.setSex(sex);

      Criteria c=sess.createCriteria(Student.class);

      Example e=Example.create(s);

      c.add(e);

      return c.list();

   }

  7. 鏈接:

  sql: inner join ;  outer join ;  no equal join ; self join

 

  hql: inner join --- inner join fetch(迫切內鏈接)

       left outer join -- left outer join fetch(迫切左外鏈接)

       right outer join

       隱式鏈接 

      

  1)left outer join:( left join ) 

      hql="from Company c left join c.employees e";

      Query q=sess.createQuery(hql);

      List<Object[]> list=q.list(); 

      /* Company對象關係屬性沒有被初始化,全部每條記錄

             被封裝成兩個獨立的對象

      */

      sql= select c.*,e.* 

           from  jdbc_company c left join jdbc_employee e

           on c.cid=e.company_id; 

      result:

        cid  cname  address  eid  ename  age

         1   kettas   wdk     1    mary   18

         1   kettas   wdk     2    tom    19

         1   kettas   wdk     3    ann    20

         2    IBM      sd      

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

    hql="select c from Company c left join c.employees e";

    Query q=sess.createQuery(hql);

    List<Company> list=q.list();

    sql= select c.*

        from  jdbc_company c left join jdbc_employee e

        on c.cid=e.company_id;  

 2)left join fetch:

   hql="from Company c left join fetch c.employees e";

   Query q=sess.createQuery(hql);

   List<Company> list=q.list();

   Set<Company> set=new HashSet<Company>(list);

  

   /* list裏的每個Company對象,全部的屬性都有值,

      包括關係屬性也被初始化,而且裏面存有查回來的

      Employee對象

   */   

   sql= select c.*,e.* 

        from  jdbc_company c left join jdbc_employee e

        on c.cid=e.company_id; 

   result:

     cid  cname  address  eid  ename  age

      1   kettas   wdk     1    mary   18

      1   kettas   wdk     2    tom    19

      1   kettas   wdk     3    ann    20

      2    IBM      sd 

3)隱式鏈接: 如:寫hql語句時,hibernate會自動的使用sql對數據庫進行查找。

   hql=" select e from Employee e

         where e.company.cname='kettas'";

   sql= select e.*

        from jdbc_employees e,jdbc_company c

        where e.company_id=c.cid  and c.cname='kettas'

8. 組函數

  sql: avg()  sum()   max()  min()  count()

  hql: avg()  sum()   max()  min()  count() 

                                           

  需求:打印出地區名字,以及該地區公司的個數

  hql=" select c.address,count(*)

        from Company c

        group by c.address

        having count(*)>1 ";

  hql=" select e.dept_id,avg(salary)

        from Employee e

        group by e.dept_id";     

       

9 子查詢:

  1)相關: 請查詢員工數量大於一的公司

    hql=select c  from Company c

        where 1<( select count(*) from c.employees e );

 

 

 2)無關: 查詢工資高於平均工資的員工對象

    hql=select e1 from Employee e1

    where e1.salary>( select avg(e2.salary) from Employee e2);

  3)all(查詢出的全部記錄)

    some/any/in(任意一條記錄) 

   

    打印出公司全部員工年齡大於30的公司

    hql="select c from Company c

         where 30< all(select e.age from c.employees e)";       

    打印出公司有員工年齡大於30的公司

    hql="select c from Company c

         where 30< any(select e.age from c.employees e)";

10.投影查詢:

    hql="select c.cname,c.address,e.ename,e.age

        from Company c left join c.employees e"; 

    Query q=sess.createQuery(hql);

    List<Object[]> list=q.list();

    --->Object[] o1={"kettas","wdk","tom",18};

    result:

       cname   address   ename  age

       kettas    wdk      tom    18

       kettas    wdk      mary   19

       IBM       sd

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

   packate hibernate.test;

   class UserData{

     private String cname;

     private String address;

     private String ename;

     private int age;

     public UserData(String cname,String address,String ename,int age){

      this.cname=cname;

      this.address=address;

      this.ename=ename;

      this.age=age;

     }

   }

   hql=select new hibernate.test.UserData(c.cname,c.address

         ,e.ename,e.age)

        from Company c left join c.employees e; 

   Query q=sess.createQuery(hql);

   List<UserData> list=q.list();  

UserData在session中沒有數據備份,是把零散的數據從數據庫中拿回來本身現封裝的對象。

11.集合過濾:

   Company c=sess.get(Company.class,18);

   c.employees沒有初始化,默認lazy=true  

   取回c的全部員工

   Set<Employee> es=c.getEmployees();

   sql="select * from jdbc_employee where company_id=c.getId()

   取回的是c的年齡大於30的員工

   1)hql="from Employee e where e.company=:com and e.age>30";

     Query q=sess.createQuery(hql);

     q.setEntity("com",c);

     List<Employee> e=q.list(); 

   2)Query q=sess.createFilter(c.getEmployees(),"where this.age>30");

     List<Employee> es=q.list();    

12. batch update

    1)sess

      a. List<Employee> list=sess.createQuery("from Employee").list();

      b. for(int i=0;i<list.size();i++){

            if(i%100==0){

               sess.flush();

               sess.clear();

                                       }

            list.get(i).setName("hello"+i);

                      }

         ta.commit(); 

        

    2) hql="update Employee e set e.ename=:name";

       Query q=sess.createQuery(hql);

       q.setString("name","hello");

       q.executeUpdate();        

      

    3) hql="delete Employee e where e.eid>20";

   

13. SQL語句是對數據庫的表操做,HQL語句是對類的操做。

   

如下是要掌握的內容:

  oracle: create table  ,  create sequence

          select  update  delete  insert  

  jdbc:  基本步驟

         jdbcUtil

         dao 的概念

         Transaction

         association(one-to-one) 

        

  hibernate: mapping file

             Session

   1)標籤  2)三種狀態    3)Session(集合)

   4)association     5)Inheriatance(one table)

   6)hql

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

 

<!--====>     配置文件   <==== -->

         <session-factory>

                   <!--<<  配置事務實現類 ,下面能夠不寫, 默認狀況下爲JDBC>> -->

                   <property name="transaction.factory_class">

                                     org.hibernate.transaction.JDBCTransactionFactory

                   </property>

 

                   <!--<<   配置JDBC裏Batch的大小  >> -->

                   <property name="jdbc.batch_size">50</property>

                   <property name="cache.use_second_level_cache">false</property>

                  

                   <!--<<   得到線程安全的Session  >> -->

                   <property name="current_session_context_class">thread</property>

                  

                   <!--<<   運行時,是否顯示SQL語句   >> -->

                   <property name="show_sql">true</property>

                   <property name="format_sql">true</property>

 

                   <!--<<   配置數據庫方言   >> -->

                   <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>

 

                   <!--<<   配置數據庫鏈接   >> -->

                   <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

                   <property name="connection.username">cksd0804</property>

                   <property name="connection.password">cksd0804</property>

                   <property name="connection.url">jdbc:oracle:thin:@192.168.0.200:1521:ORADB10G</property>

                  

                   <!--<<   c3po  配置鏈接池   >> -->

                   <property name="c3p0.max_size">2</property>

                   <property name="c3p0.min_size">2</property>

                   <property name="c3p0.timeout">5000</property>

                   <property name="c3p0.max_statements">100</property>

                   <property name="c3p0.idle_test_period">3000</property>

                   <property name="c3p0.acquire_increment">2</property>

                   <property name="c3p0.validate">false</property>

 

                   <!-- <<   指定(hibernate管理的)映射文件   >> -->

                   <!--<mapping resource="day1/Users.hbm.xml"></mapping>--> 

<!-- <<   當用tomcat服務器配置的鏈接池時用下面代替上面的鏈接   >>-->

<!--<property name="hibernate.connection.datasource">java:comp/env/oracle/ds</property> -->

 

<!--該路徑是相對於hibernate.cfg.xml的路徑 (相對路徑)-->

                   <!--<mapping resource="orm/o2o/fkuk/bi/Car.hbm.xml"></mapping> -->

                   <!--<mapping resource="orm/o2o/fkuk/bi/License.hbm.xml"></mapping> -->

                   <!--<mapping resource="orm/o2o/fkuk/ui/CarLicense.hbm.xml"></mapping>-->

                   <!--<mapping resource="orm/o2m/bi/CompanyEmployee.hbm.xml"></mapping>-->

                   <mapping resource="orm/m2m/bi/StudentCourse.hbm.xml"></mapping>

         </session-factory>

</hibernate-configuration>

 

Hibernate 的工做原理-------------------------à

 

 

 

 

 

 

 

 

 

 

 

 

HTML&JavaScript


 

Html==================================================================================


Head相關

Meta 描述屬性

Style 樣式

Script 腳本

字體相關

h1 ... h6 字體的大小  一次變小

p  段落標籤 換行且有段間距

pre  預備役標籤,保留你的輸出

font --> size | color  字體變化,設置大小和顏色

b | strong  加粗

center 居中

em 斜體,着重顯示,不一樣的顯示器,着重顯示不同

br  換行符

hr  分割線

圖片/超連接

圖片 img src(名字) | width height(寬高) | alt (圖片找不到的時候顯示的東西) | align(控制寫在圖片以後文字的位置 bootom 下方middle中間) | border (控制圖片邊框)

超級鏈接a href鏈接目標的url) | name(錨點名) | target (4個備選 _new第一次鏈接開一個新窗口,第2,3次在同一個窗口裏刷新  _self本身窗口裏打開  _blank鏈接打開一個新窗口,點幾回開幾個窗口  _top(我在最頂端,把frameset框架替換了,要代替真個框架顯示出來))href=「#」表示本頁面

表格

table (tbody) border | bordercolor | bgcolor | cellsapcing | width height | align

         |- tr

      |- td colspan | rowspan  和並列| 合併行

表單

form --> method | action

         |- input --> type : text | password | checkbox | radio | button | submit | reset | hidden    

         |- select

                                     |- option

         |- textarea --> cols rows

name=value

框架

frameset ---> 不容許出現body  ---> rows cols

         |- frame ---> name | src

C/S           B/S

web 1.0 --->  發佈式體系

web 2.0 --->  強調用戶參與 ---> blog

==================================

internet    ---> 鋪路

web         ---> 車

http  --- 底層傳輸層協議 來自於ARPA 

   --->  無狀態協議

   --->  一次性鏈接  

   --->  80端口

HTML  ---> 標識性語言 --- 被瀏覽器解釋    

                      Active X    

W3C制定的  

<body xxx="xxx">

       xxxx

</body>     

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

<html>

         <head>  ----> 

         </head>

         <body>

         </body>      

</html>

字體相關標籤

<h1 --- h6>

<p>             <pre>

<font size color>

<center>

<br><hr>

<b><strong>

 

圖片\超連接

<img>

 |- src

 |- width height

 |- alt

 |- align

 

<a>

 |- target --->  _new _self _blank _top 若是不加_表示一個frameset的name

 |- href

 |- name

 

表格

<table> --> border | bordercolor | width / heigth | align | cellspacing

 |- <tr>

                   |- <td>   --->  colspan | rowspan

表單

<form>      

         |- method

                   |- get

                            參數以URL方式進行提交  

         參數用來提交給服務器看,須要服務器端主動拿取

                            缺點: 不安全

                                      URL長度有限制

                                       編碼問題

                            |- post       

                                     參數包含在請求體中提交    

                                     服務器端直接從請求中得到數據

                                    

         |- action

                            file:///C:/Documents%20and%20Settings/user/桌面/html/form.html

                            ? --> 鏈接符 表示後面提交參數

                            userName=kettas

                            & --> 參數鏈接符用於多個參數分隔

                            password=123456

                            &radio1=hibernate

                            &heshang=JinChuangGuang

                            &heshang=SunShuai&sel=tianjin

         <input>

</form>

 

框架<frameset>

<html>

<frameset rows="15%, 70%, 15%"> 

         <frame name="title" src="title.html">

         <frameset cols="15%,*">

                   <frame name="leftBar" src="leftBar.html">

                   <frame name="main" src="main.html">

         </frameset>

         <frame name="footer" src="footer.html">

</frameset>

</html>

 

Inputàtype:text文本|password|checkbox多選框||radio單選框|botton|submit|reset

Select下拉列表 option標籤

Textarea

 

 

==================================================================================================


1) Css Cascading Style Sheets)什麼用   

優勢: 1 避免傳統html標籤過於繁瑣的步驟

                                     2 比傳統html標籤更靈活

                                     3 可重用性

<head>

 <style type="text/css">

         h1.rb, h2.rb{

                            color : red;   

                            background-color : black ;

                            }  

                                    

         h1.gy{

                    color :green ;

                  background-color : yellow;

         } 

                                    

         #p1{

                    color : red;

         }

     .mylayout{ //通常用點號「。」後面是css的名字

        color:red;

}

                    </style>

         </head>

         <body>         

                   <h1 class="rb">Hello Css World!</h1>

                   <h1 class="gy">Have a nice day!</h1>

                   <h1 class="rb">Good luck & Have fun!</h1>                      

                   <h2 class="rb">this is h2 line</h2>               

                   <h3 class="rb">this is h3 line</h3>     

                   <p id="p1">this is p line</p>

                   <textarea class=」mylayout」/> class調用css

2) selector{

                   property : value;

          }

 

 

3) 外部引入css  使用的時候和內部同樣

     1) <style type="text/css"></style>

     2) <link rel="stylesheet" type="text/css" href="…/home.css"/>

     3) nested

內部標籤使用 <h1 style="color:blue">this is 3 line</h1>

4,經常使用的css相關標籤

文本相關

   text-align : left | center | right

   text-indent : 10px ;

   color : 制定文字顏色

字體相關

     font-family : 字體:

       「times new Roman" , times , serif ....

     font-weight : normal , bold , lighter , bolder

     font-size : xxxx

               % , smaller , larger .font-size:10pt}

.s1 {font-size:16px}

.s2 {font-size:16pt}

.s3 {font-size:80%}

.s4 {font-size:larger}

.s5 {font-size:xx-large}

 letter-spacing : 字符間隔

 word-spacing : 單詞間隔

  .p1 {text-indent: 8mm}

  .d1 {width:300px}

 .p2 {text-indent:50%}

 

顏色背景

    background-color :

    background-image:url( images/xxxx.jpg )---背景圖片

    background-repeat :  決定顯示方式。

         repeat : 重複顯示

        repeat-x : 左上方開始橫向重複顯示。

         repeat-y : 縱向重複顯示

         *no-repeat : 只顯示一次 。 

        

關於div span

 

邊框相關

  border : style width color

         style : 邊框的種類.

              none , hidden , dotted , dashed, solid , double, groove , ridge, inset , outset

                border-style :

                   border-top-style :

                   border-left-style :

                   border-right-style:

                   border-bottom-style :

 

         border-width:

                   border-top-width:

                   border-left-width:

                   border-right-width:

                   border-bottom-width:

         border-color :

                   border-top-color:

                   border-left-color:

                   border-right-color:

                   border-bottom-color:

 

高度,寬度 :

   width : height :

 

補白:變相的縮進

 

         padding:

            padding-top

            padding-right

            padding-left

     padding-bottom

  margin:

             margin-top

             margin-right

             ....................


 

 

 

 

JavaScript_1:============

動態網頁技術

                   ---> 服務端技術

                   ---> 客戶端技術

javascript 基於解釋性的語言

  動態網頁:

    服務器端動態

 客戶端動態

減小服務器壓力

                            功能受瀏覽器控制 須要看瀏覽器支持什麼

========= 詞法特性 =================

採用unicode字符集,可是僅限於註釋和字符串變量值, 變量和函數的標識符不能使用

Unicode字符集。

基本特徵 :

    變量沒有數據類型 。

    JAVA:

       int a = 123;

       String b = "123";

    Javascript :

       var a = 123;

       var b = "123";

    基本程序控制和java同樣。

==============================================

數據類型和值 :

         弱數據類型 設計的比較簡單 隨着功能越發強大 已經成爲了一個缺陷

      在程序中,變量的值能夠是 :

      三種基本數據類型 :

      數字: 123, 123.22

      文本字符串: "zhongguo" ,"中國", '123' 

      boolean類型: true | false  

                        非0 和  0    非null| null

     

      除基本數據類型之外, javascript 還支持複合類型 :

      Object( 對象 ) , Array( 數組 )

     boolean :

    boolean 的其餘表示方法 :

                1 , 0 和 非0 值 。

                2, 空 和非空 。

      特殊數據類型:null 和 undefine (未定義的).

javascript 是 弱數據類型的語言,其變量沒有數據類型。

全部變量聲明時都使用 var 類型 。 並且統一變量可分別

存儲不一樣類型的值

 

var a = 123;

a = "123";   

var a = 1;

var b = "2";

var c = a + b ;    "12"

 

 

javascript代碼引入到Html

1,代碼直接嵌入

<script language="javascript">

    ......

    ......

</script>

 

2, 引入外部文件

<script type="text/javascript" src="js/functions.js"></script>

<link rel="stylesheet" type="text/css" href="*.css">

 

javascript簡單交互手段

alert( "" );

document.write( "" ) ;

只有function裏纔算局部變量

If、for裏都不算

    建立並使用對象 。

    1,

    var obj = new Object();

   obj.name = "zhangsan" ;

   obj.age =123 ;

   obj.email = "liucy@cernet.com" ;

 

屬性的兩種訪問方式:

   alert( obj.name ) ;

   alert( obj["name"] ) ;

         本質:多個屬性的集合

         缺點:不嚴謹

    var  obj = { name : "zhangsan" , age : 24 , email : "liucy@cernet.com" } ;

   alert( obj.gender ) ;

 

for循環

   第一種

for (i = 0; i <= 5; i++)

{

document.write(i)

document.write("<br>")

}

  第二種使用 for...in 循環語句

for...in 循環中的循環計數器是一個字符串,而不是數字。它包含了當前屬性的名稱或者表示當前數組元素的下標。

<script type="text/javascript">

// 建立一個對象 myObject 以及三個屬性 sitename, siteurl, sitecontent。

var myObject = new Object();

myObject.sitename = "布啦布啦";

myObject.siteurl = "blabla.cn";

myObject.sitecontent = "網頁教程代碼圖庫的中文站點";

//遍歷對象的全部屬性

for (prop in myObject)    prop是數組元素的下標和java

{                      foreach有不一樣的含義

document.write("屬性 '" + prop + "' 爲 " + myObject[prop]);

document.write("<br>");

}

 

 

 

建立並使用數組

     1,

     var arr = new Array();

     var[0] = 1 ;

     var[1] = 3 ;

     2,

     var arr = [ 1,2,3,4,5,6 ] ;

     3,

     var arr = [ 1,,,,6] ;

     4,

     var arr = [ 1, 4.4, "sd" , true]  相似一個集合

不須要指定數組長度

使用變量 :

    變量須要先聲明,後使用 。

    未付值的變量初始值是undefine .

   重複聲明 :

      使用 var 重複聲明是合法的. 若是重複聲明中有初始值的話, 則至關於付值

      語句 , 沒有初始值的話,變量保留之前的值 .

  遺漏聲明 :

     若是使用了一個未聲明的變量 , javascript會對這個變量做隱式聲明。

      可是全部隱式聲明的變量,都會成爲全局變量,即便聲明是發生在函數體

       以內的 。

函數聲明和使用 :

    function name( a , b , c ) {}

   支持內聯函數 :

  function a(){

         function b();

         b();

  }

  內聯函數只能在做用域內使用

  變量做用域 :

      javascript中不存在塊做用域, 聲明在塊中的變量,在塊的外面同樣能夠使用

   if(){

           var a = 10 ;

       }

   alert( a ) ; //合法 。

   做爲數據的函數 :

         function a( x, y ){  .... }

         var b = a ;//用變量存函數;

         b( 1 , 2 ) ;//至關於a(1,2);

思考:

         var student = new Object();

         student.name = "zhangsan";

 

   經過構造函數建立函數

   var a = new Function( "a" , "b" , "return a + b " );

  a , b , 新建對象的參數名稱 , 若是有多個能夠依次填入 :

   new Function( "a" , "b" , "c" , ... " return a + b + ... + n ; " ) ;

      調用 : a( 10 , 20 ) ;

   經過函數直接量:

       var a = function ( x , y ){ return x + y ; }

    參數數量驗證:arguments.length

    變量做用域:

         不存在塊做用域注意這裏所說的塊並非函數塊

window.parent

JavaScript_2:==================

javascript中的常見事件

    通常性事件

          onclick            單擊事件

          ondblclick      雙擊事件

          onmouseomove    鼠標移動

          onmouseover     鼠標移入

          onmouseout      鼠標移出

          onmousedown   鼠標鍵按下

          onmouseup       鼠標鍵鬆開

         適用 幾乎所有的可顯示元素(標籤) 。

   頁面相關事件

         onload   :   頁面加載時觸發。即把頁面全部的東西都下載完時觸發              <body>

         onscroll :   頁面滾動時觸發。                        <body>

         onstop   :   按下stop按鈕時觸發。               <body>

         onresize :   調整大小時觸發 。                       <body>

         onmove   :   窗口移動時觸發。                     <body>

   表單相關事件

        onblur   : 當前元素失去焦點時觸發。 <input>

        onchange : 當前元素失去焦點,而且值發生變化時觸發。<input>

        onfocus  : 當前元素得到焦點時觸發,指光標移到當前處,即得到焦點 。  <input>

        onsubmit : 表單被提交時觸發  <form onsubmit=」return tes()」>

==============================================

DOM : W3C提供的一組規範 能夠在獨立於平臺的前提下修改文檔的內容和結構。

DOM  將文檔的內容封裝到對象及對象的屬性和關係中 。

經過操做DOM對象及對象的屬性,達到修改文檔內容及結構的目的 。

DOM裏有各類方法,用於修改文檔內容和結構;

能夠將DOM理解爲文檔內容的樹狀表示法 。

<table>

   <tbody>

       <tr><td>zhangsan</td><td>20</td></tr>

       <tr><td>lisi</td><td>21</td></tr>

   </tbody>

</table>         

用於遍歷XML文檔的DOM方法:

    document.getElementById( "" )       XMLElement

    document.getElementsByTagName( "name" )    array

用於處理XML文檔的DOM屬性 :

     childNodes      Array     //返回的是一個數組

     firstChild       XMLElement     //第一個子標籤

     lastChild           XMLElement                 //最後一個子標籤

     nextSibling       XMLElement  //同級的下一個標籤

     previousSibling   XMLElement //同級的上一個標籤

     parentNode      XMLElement    //直接父標籤

經過 "." 訪問element屬性 。

    document對象爲DOM的內置對象,表明XML文檔的根

    在HTML文件中能夠理解爲body標籤 。

    document.createElement( "div" ) ;

    document.createTextNode( "text" ) ; 建立文本

var txtA = document.createTextNode("hello");    //建立文本內容

var colA = document.createElement("td");  //建立標記

colA.appendChild(txtA);    //添加子標記

     element.getAttribute( Name ) ;

     element.setAttribute( "name" , value ) ;

     element.appendChild() 

     element.insertBefore( newNode , targetNode ) ;

     element.removeAttribute( node )

     element.removeChild( node ) ;

     element.replaceChild( newNode , oldNode ) ;      //用newNode替換oldNode

     element.hasChildnodes()

瀏覽器差別。

    1) table 和 tbody

2) 設置屬性   ff     element.setAttribute( "name" , "value" ) ; 

                            ie     element.name = value

3

設置css   ff   element.setAttribute("style","color:blue" ) ;

              ie            element.style.cssText = "color:blue" ;

              ff            element.setAttribute("class","xxx" ) ;

              ie            element.className ;

 

1 變量沒有數據類型 ---> 值有

                   基本數據類型 :

                            數字 | 字符串 | boolean

                                                                           |-  0,非0 | null 和非null

                   複合類型:

                   數組(沒有固定長度,能夠裝任何類型的值)

                   對象(只有屬性沒有方法) 

2 變量能夠重複聲明

3 變量若是沒有通過聲明,系統會自動對其作隱式聲明(做爲全局變量)

4 function 函數名(a, b){}

5 經過構造方法建立函數: var fun = new Function("");

         經過函數直接量建立函數: var fun = function(){}

6 做爲變量函數

         var fun;

         function testFun(a, b){

                    return a+b;

         }                                 

         fun = testFun; 

         fun(1,2);  

7 事件句柄:onclick……

8 DOM ---> getElementById

              getElementsByTagName

 


 

9各類表單驗證=====================

1) 兩次輸入密碼是否相同

<FORM METHOD=POST ACTION="">

<input type="password" id="input1">

<input type="password" id="input2">

<input type="button" value="test" onclick="check()">

</FORM>

<script>

 

function check(){

with(document.all){

if(input1.value!=input2.value) {

alert("false")

input1.value = "";

input2.value = "";

}

else document.forms[0].submit();

}}

</script>

 

2)6. 驗證油箱格式

<SCRIPT LANGUAGE=javascript RUNAT=Server>

function isEmail(strEmail) {

if(strEmail.search(/^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/) != -1)

return true;

else alert("oh");

}

</SCRIPT>

<input type=text onblur=isEmail(this.value)>

 

3)表單項不能爲空

<script language="javascript">

function CheckForm(){

if (document.form.name.value.length == 0) {

alert("請輸入您姓名!");

document.form.name.focus();

return false;

}

return true;

}

</script>

 

4) 比較兩個表單項的值是否相同(密碼比較)

<script language="javascript">

function CheckForm()

if (document.form.PWD.value != document.form.PWD_Again.value) {

alert("您兩次輸入的密碼不同!請從新輸入.");

document.ADDUser.PWD.focus();

return false;

}

return true;

}

</script>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

servlet


Servlet是位於Web 服務器內部的服務器端的Java應用程序,與傳統的從命令行啓動的Java應用程序不一樣,Servlet由Web服務器進行加載,該Web服務器必須包含支持Servlet的Java虛擬機

* 它們不是獨立的應用程序,沒有main()方法。* 它們不是由用戶或程序員調用,而是由另一個應用程序(容器)調用。

* 它們都有一個生存週期,包含init()和destroy()方法。

 

要使用Servlet,必須導入包servlet-api.jar。這裏使用的服務器是Tomcat,其主目錄結構爲 :

                |- bin : 用於存放可執行命令( catalina.sh )

           |- conf : 用於存放tomcat須要的配置文件.

           |- lib : 存放tomcat在運行時要用到的類文件(jsp-api.jar、servlet-api.jar、...).

           |- webapps : 最重要的一個目錄,其下放置各類Servlet文件、網頁文件(JSP HTML ...)、

                                                 配置文件以及資源文件.此目錄的結構 :

                              |- 應用目錄(好比是一個學生管理網站,就在webapps文件夾下建一個StudentManage目錄)

                                       |- WEB-INF目錄

                                                 |- classes目錄, 放置全部的Servlet文件或其餘類文件

                                                 |- lib目錄, 放置本應用所要用到的類文件(jar包)

                                                 |- web.xml 配置文件

                                       |- 資源文件(好比圖片), 網頁文件(JSP HTML ...)

                                                                            

           |- logs : 日誌文件 .

           |- work : 內部臨時文件.

           |- temp : 臨時文件.

安裝tomcat  環境變量的配置,和配jdk差很少servlet-api.jar;jsp-api.jar

1  Servlet接口、GenericServlet類、HttpServlet :

         Servlet是最頂層的接口,其提供的方法有 :

                   init(ServletConfig config) : void   // 初始化  

                   getServletConfig() : ServletConfig  // 取得該Servlet配置信息

                   getServletInfo() : String                        // 取得相關信息

                   service(ServletRequest req, ServletResponse res) : void   //核心方法

                   destroy() : void   // Servlet生命週期結束時候執行的方法

                   顯然咱們最關心的是service方法,其餘的幾個方法在實現的時候是千篇一概、無關痛癢的。故提

         供了GenericServlet類,此類實現了Servlet接口,咱們在使用Servlet的時候,只需繼承這個類而後

         覆蓋其中的service方法(拋出ServletException、IOException異常)便可。

                   因爲Servlet基本上是在http協議下使用的,故提供了HttpServlet這個類,此類繼承自

         GenericServlet類,咱們在使用Servlet時,只需繼承HttpServlet類而後覆蓋如下方法 :

                   service( HttpServletRequest request ,

                                      HttpServletResponse response )

                                      throws ServletException , IOException : void

                   注意:HttpServletRequest和HttpServletResponse分別是從ServletRequest和ServletResponse繼承

                   此外,HttpServlet還提供了doPostdoGet方法,參數和返回值與service方法同樣。只是service

         方法能夠針對客戶端的任何請求類型(GET和POST),而doPost和doGet方法分別只能對應客戶端的POST方式

         請求和GET方式的請求。

HttpServlet-----àextends   GenericServlet ----à implements Servlet

使用GenericServlet實例 :

         package com.kettas.servlet;

         import javax.servlet.* ;

         import java.io.* ;

         public class GenDateServlet extends GenericServlet{

                   @Override

                   public void service( ServletRequest request , ServletResponse response )

                            throws ServletException ,IOException

                   {                response.setContentType( "text/html" ) ; // 設置響應內容類型

                                      PrintWriter out = response.getWriter();// 得到文本寫入流

                                      // 給客戶端迴應的html文本

                                      out.println( "<html>" ) ;

                                      out.println( "<body>" ) ;

                                      out.println( "<h1>Hello Servlet !</h1>" );

                                      out.println( "</body>" ) ;

                                      out.println( "</html>" ) ;

                                      out.flush();// 刷新寫入

                   }}

         配置文件web.xml以下 :

                   <?xml version="1.0" encoding="UTF-8"?>

                   <web-app xmlns="http://java.sun.com/xml/ns/javaee"

                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

                      version="2.5">          

                            // Servlet文件路徑

                            <servlet>

                                     <servlet-name>query</servlet-name>

                                     <servlet-class>com.kettas.servlet.GenDateServlet</servlet-class>

                            </servlet>      

                            // 指定映射,說明在瀏覽器中輸入".../query"則對應當前Servlet                              

                            <servlet-mapping>

                                     <servlet-name>query</servlet-name>

                                     <url-pattern>/query</url-pattern>

                            </servlet-mapping>

                   </web-app>

使用HttpServlet簡單實例 :

         package com.kettas.servlet ;

         import javax.servlet.* ;

         import javax.servlet.http.* ;

         import java.io.* ;

         public class LoginServlet extends HttpServlet{

                   @Override

                   public void service( HttpServletRequest request , HttpServletResponse response )

                            throws ServletException , IOException

                   {   response.setContentType("text/html; charset=GB2312"); // 注意設置編碼的方式

                            request.setCharacterEncoding("GB2312");

                            PrintWriter out = response.getWriter();

                            // 取得客戶端提交的數據

                            String name = request.getParameter( "userName" ) ;

                            String pwd = request.getParameter( "password" ) ;

                            out.println("<html>");

                            out.println("<body>");

                            out.println("<h1>");

                            out.println("Name : " + name + "   " + "Password : " + pwd);

                            out.println("</h1>");

                            out.println("</body>");

                            out.println("</html>");

                            out.flush();

                   }}

配置文件web.xml片斷 :

                            <servlet>

                                     <servlet-name>login</servlet-name>

                                     <servlet-class>com.kettas.servlet.LoginServlet</servlet-class>

                            </servlet>                                     

                            <servlet-mapping>      

                                     <servlet-name>login</servlet-name>

                                     <url-pattern>/login</url-pattern>

                            </servlet-mapping>

請求轉發 :

         實現不一樣servlet之間的數據傳遞,這樣即可實現業務邏輯和顯示邏輯的分離

         實例 :

                   (1) 第一個servlet,負責業務

                            package com.kettas.servlet ;

                            import javax.servlet.* ;

                            import javax.servlet.http.*;

                            import java.io.*;

                            import java.util.* ;

                            public class ForwardA extends HttpServlet{

                                     @Override

                                     public void service( HttpServletRequest request , HttpServletResponse response )

                                               throws ServletException , IOException

                                     {           System.out.println( "=== This is forward A ===" ) ;

                                                  // 將業務部分的數據存儲在request對象中,傳遞給下一個servlet使用

                                                  Date d = new Date();

                                                  request.setAttribute( "date" , d ) ;

                                                  /* 注意轉發的過程

                                                      * 首先得到一個知道下一棒地址的"接力棒"對象,而後將這個"接力棒"傳給下一個

                                                      * servlet,這樣便將請求轉發了。

                                                      */

                                                  RequestDispatcher disp = request.getRequestDispatcher( "/forwardB" ) ;

                                                  disp.forward( request , response ) ;

                                     }

                            }

                            注意 : 1 這種請求轉發的方式是共用一個鏈接的,無論你中途通過了多少個servlet,正因如此,

                                                這些servlet才能共享request中存儲的數據。

                                        2 只有最後一個servlet,才能在客戶端瀏覽器中顯示。

                   (2) 第二個servlet,負責顯示

                            package com.kettas.servlet ;

                            import javax.servlet.* ;

                            import javax.servlet.http.*;

                            import java.io.*;

                            import java.util.* ;

                            public class ForwardB extends HttpServlet{

                                     @Override

                                     public void service( HttpServletRequest request , HttpServletResponse response )

                                               throws ServletException , IOException

                                     {       response.setContentType( "text/html" );

                                                  PrintWriter out = response.getWriter();

                                                  out.println( "<h2>This is forwared B</h2>" ) ;

                                                  // 經過getAttribute方法,從request中取得數據

                                                  // 因爲此方法返回的是Object對象,故要強轉

                                                  Date d = (Date)request.getAttribute( "date" ) ;

                                                  out.println( "<h2>" + d + "</h2>" ) ;

                                                  System.out.println( "=== This is forward B ===" ) ;

                                                  out.flush();

                                     }

                            }

                   (3) web.xml片斷 :

                                     <servlet>

                                               <servlet-name>a</servlet-name>

                                               <servlet-class>com.kettas.servlet.ForwardA</servlet-class>

                                     </servlet>                                 

                                     <servlet-mapping>

                                               <servlet-name>a</servlet-name>  

                                               <url-pattern>/forwardA</url-pattern>

                                     </servlet-mapping>

                                     <servlet>

                                               <servlet-name>b</servlet-name>

                                               <servlet-class>com.kettas.servlet.ForwardB</servlet-class>

                                     </servlet>                                 

                                     <servlet-mapping>

                                               <servlet-name>b</servlet-name> 

                                               <url-pattern>/forwardB</url-pattern>

                                     </servlet-mapping>

    頁面跳轉的兩種方式 1)request.getRequestDispatcher(「/forwardA」).forward(request , response); 這種跳轉是在服務器內部是servlet之間跳轉,顯示的老是最後一個servlet  A-àB--à----àD

                        2)response.sendRedirect(「mayservlet/query」) 它實際上是在客戶端的url發生改變,至關一次新的請求,故不能傳遞數據,但能在不一樣的應用中跳轉

關於Cookie, 在客戶端瀏覽器保存用戶狀態的一種機制

         servlet中的Cookie含有三個屬性: name, value, maxAge

         maxAge = 60 表示:此cookie在客戶端存在1分鐘

         兩個特殊值:

         maxAge = -1 表示 : 此Cookie生命週期由保存它的瀏覽器決定 ,(瀏覽器開則生,關則死),默認的

         maxAge = 0  表示 : 刪去之前的相應cookie存儲

         Cookie應用實例 :

                   package com.kettas.servlet ;

                   import javax.servlet.*;

                   import javax.servlet.http.*;

                   import java.io.*;

                   public class CookieServlet extends HttpServlet{

                            @Override

                            public void service( HttpServletRequest request , HttpServletResponse response )

                                     throws ServletException , IOException

                            {// 建立一個新的Cookie對象, 構造參數分別爲Cookie的name和value屬性

                                     Cookie c = new Cookie( "test" , "1234567890" );

                                     // 將Cookie對象加入response中,這樣才能被帶入客戶端

                                     response.addCookie( c ) ; 

                                     // 從請求中獲取客戶端Cookie數組

                                     Cookie[] cookies = request.getCookies();

                                     response.setContentType( "text/html" );

                                     PrintWriter out = response.getWriter();

                                     out.println("<html>");

                                     out.println( "<body>" ) ;

                                     out.println( "<h1>Cookie List</h1><hr/><p></p>" ) ;

                                     if( cookies != null ){

                                               for( Cookie cookie : cookies ) {

                                                        out.println( "<h2>" + cookie.getName() + "=" + cookie.getValue() + "</h2>" ) ;

                                               }

                                     }else{

                                                 out.println( "<h2>No cookie</h2>" ) ;

                                     }

                                     out.println( "</body>" ) ;

                                     out.println("</html>");

                                     out.flush();

                            }

                   }          

6  關於HttpSession, 在服務器端保存用戶狀態的一種機制

         (1) 獲取HttpSession對象的方法 :

              // 參數爲true,表示若存在對應的HttpSession對象,則返回。若不存在,則建立一個新的。

              // 若參數爲false,表示若存在對應的HttpSession對象,則返回。若不存在,則返回null。

                    HttpSession session = request.getSession(true);

         (2) 對HttpSession對象, 進行存取數據的操做

         // 兩個參數,分別爲命名屬性和對應的數據

         session.setAttribute("name", data);

         // 一個參數,命名屬性,注意返回的爲Object對象,要強轉

         session.getAttribute("name");

    (3) 比較Session和request :

        request :

            建立 : 當用戶請求到達服務器的時候

            銷燬 : 當本次請求的應答回到客戶端的時候.

                   客戶端的一次請求應答之間

        session :

            建立 : 當用戶第一次調用request.getSession( true )

            銷燬 : 超時 ( 兩級超時限制 )

                          1) 內存 ---> 文件 .

                             2) 從文件系統銷燬 .      

        session的原理 :

             給每一個瀏覽器一個cookie,這個cookie的name屬性爲"jsessionid",value屬性爲這個session

             對應的ID值。

    (4) 當瀏覽器拒絕cookie時能夠用URL把session的id提交給服務器

       如 : http://localhost:8989/servletapp/forwardB;jsessionid=37D50D093CCD4A37CC1118785E38F438

                 "url;jessionid="+ session.getId()

       response.encodeURL("url") :對url進行編碼

7  ServletConfig對象和ServletContext對象

       (1)ServletConfig : 用來保存一個Servlet的配置信息的(好比 : name, class, url ... )

                這些配置信息沒什麼大用處,咱們還能夠在ServletConfig中保存本身在web.xml文件中定義的數據

                此時的web.xml文件片斷以下 :

                        <servlet>

                                       <!-- 本身定義的,要保存在ServletConfig對象中的數據 -->

                                   <init-param>

                                            <param-name>jdbc.driver</param-name>

                                            <param-value>oracle.jdbc.driver.OracleDriver</param-value>

                                   </init-param> 

                                   <init-param>

                                            <param-name>jdbc.user</param-name>

                                            <param-value>yinkui</param-value>

                                   </init-param>

                                   ...

                                   <servlet-name>query</servlet-name>

                                   <servlet-class>com.kettas.servlet.Query</servlet-class>

                              </servlet> 

                     在Servlet中取得這些數據 :

                                    // getServletConfig方法繼承自父類GenericServlet

                                     ServletConfig sc = this.getServletConfig();

                                     // 顯然,getInitParameter方法返回的只能是字符串類型數據

                                     String driver = sc.getInitParameter("jdbc.driver");

                                     String user = sc.getInitParameter("jdbc.user");

            注意: 1 ServletConfig對象只能從web.xml文件中獲取自定義數據(字符串數據),不存在setAttribute

                             方法去存入自定義數據。

                           2 在Servlet中,若要覆蓋父類的init(ServletConfig config)方法,必須這麼作 :

                               public void init( ServletConfig config ){

                                             // 覆蓋以前調用父類的這個方法, 不然ServletConfig對象會丟失

                                             // 此時this.getServletConfig()返回的是null, 那樣咱們就不能使用它了

                                             super.init( config ) ;

                                   ...   }                              

       (2)ServletContext : 用來保存數據的全局惟一對象,一個應用中只有一個ServletContext對象

                       1 : 經過web.xml文件,在ServletContext對象中存入數據

                                 此時的web.xml文件片斷以下所示 :

                                          <!-- 在此處寫入咱們要存入ServletContext對象中的數據 -->

                                          <context-param>

                                                       <param-name>jdbc.driver</param-name>

                                                       <param-value>oracle.jdbc.driver.OracleDriver</param-value>

                                               </context-param>

                                               <context-param>

                                                        <param-name>jdbc.url</param-name>

                                                        <param-value>jdbc:oracle:thin:@192.168.0.201:1521:kettas</param-value>

                                               </context-param> 

                                               ...

                                               <servlet>

                                                        <servlet-name>...</servlet-name>

                                                        <servlet-class>...</servlet-class>

                                               </servlet>    

                                     取得其中的數據 :           String driver = servletContext.getInitParameter("jdbc.driver");

                       2 : 經過setAttribute方法,在ServletContext對象中存入數據

                               servletContext.setAttribute("name", data); // 兩個參數分別爲命名屬性以及對應的數據

                               // 取得ServletContext對象中的數據, 參數爲命名屬性

                               // 返回的是Object對象, 故要強轉

                               servletContext.getAttribute("name");

                       3 : 取得ServletContext對象的三種方法(this指代當前Servlet)

                                 (1) ServletContext sc = this.getServletContext();

                                 (2) ServletContext sc = this.getServletConfig().getServletContext();

                                 (3) ServletContext sc = request.getSession(true).getServletContext();

                                 ServletContext對象的一個重要方法 :                                                 

                                   InputStream is = sc.getResourceAsStream( "fileName" ) ;

                                           fileName : 使用的是虛擬目錄, 不依賴於實際路徑/books/ajax.pdf

                                         最左邊一個"/" : web 應用的根目錄 

                                    // 得到實際路徑        String path = ctx.getRealPath( "/books/ajax.pdf" )

監聽事件和過濾器

         監聽包括三種狀況,分別是HttpRequestSessionServletContext監聽。

經常使用的是implements  servletContextListener(全局變量)兩個方法 public void contextInitialized(ServletContextEvent arg0)

                                                             arg0.getServletContext()

Session監聽事件所示 :

import javax.servlet.http.HttpSession;

import javax.servlet.http.HttpSessionEvent;

import javax.servlet.http.HttpSessionListener;

import com.kettas.upp02.util.Constant;

public class SessionListener implements HttpSessionListener {

         public void sessionCreated(HttpSessionEvent ent) {

                   HttpSession session = ent.getSession();

                   synchronized (this) {

                            ServletContext ctx = session.getServletContext();

                            Integer counter = (Integer) ctx.getAttribute("sessionCount");

                            ctx.setAttribute("sessionCount", counter.intValue() + 1);

                            System.out.println(Constant.LOGO + "SessionCount:"

                                               + (counter.intValue() + 1));

                   }}

         public void sessionDestroyed(HttpSessionEvent ent) {

                   HttpSession session = ent.getSession();

                   synchronized (this) {

                            ServletContext ctx = session.getServletContext();

                            Integer counter = (Integer) ctx.getAttribute("sessionCount");

                            ctx.setAttribute("sessionCount", counter.intValue() - 1);

                            System.out.println(Constant.LOGO + "SessionCount:"

                                               + (counter.intValue() - 1));

                   }

         }}

         在web.xml文件中配置以下 :

                   <listener>

                            <listener-class>shop. SessionListener </listener-class>

                   </listener>

                  

         其餘兩個監聽事件的實現同上並沒有二致。                                    

過濾器       // 實現Filter接口

import java.io.IOException;

                                     import javax.servlet.*;

                                     public class EncodingFilter implements Filter{

                                     //銷燬時執行,不必覆蓋

                                               public void destroy() {}

                                               //發送請求時執行

                                               public void doFilter(ServletRequest request, ServletResponse response,

                                                                 FilterChain chain) throws IOException, ServletException {

                                                        //設置發送請求和接收請求時的編碼方式,統一才能達到過濾做用

                                                        request.setCharacterEncoding("UTF-8");

                                                        response.setCharacterEncoding("UTF-8");

                                                        try {

                                                                 chain.doFilter(request, response); 請求轉發

                                                        } catch (RuntimeException e) {

                                                                 e.printStackTrace();

                                                        }}

                                               //加載時執行,也不必執行

                                               public void init(FilterConfig arg0) throws ServletException {}

                                     }

                   web.xml文件中:

                     //配置當發生什麼要的請求時,讓那個過濾流執行操做

                        <filter>

                                     <filter-name>encodingFilter</filter-name>

                                     <filter-class>filter.EncodingFilter</filter-class>

                            </filter>

                            <filter-mapping>

                                     <filter-name>encodingFilter</filter-name>

                                     <url-pattern>/*</url-pattern>

                            </filter-mapping>

9,解決亂碼問題  1)response.setContentType(「text/html;charset=gbk2312」)

                 2)requset.setCharacterEnconding(「gbk」)  ------是post的時候

                 3)在server.xml中加URLEncoding=「gbk」------是get發送數據的時候

10,servlet的生命週期

        1Servlet在容器中運行,其實例的建立及銷燬等都不是由程序員決定的,而是由容器進行控制的。

建立Servlet實例有兩個時機:1客戶端第一次請求某個Servlet時,系統建立該Servlet的實例:大部分的Servlet都是這種Servlet。

2,Web應用啓動時當即建立Servlet實例,即load-on-startup     <load-on-startup>1</load-on-startup>

Servlet的生命週期經過javax.servlet.Servlet接口中的init()service()destroy()方法來表示。

每一個Servlet的運行都遵循以下生命週期。

1)加載和實例化:找到servlet類的位置經過類加載器加載Servlet類,成功加載後,容器經過Java的反射API來建立Servlet實例,調用的是Servlet的默認構造方法(即不帶參數的構造方法),

2)初始化:容器將調用Servlet的init()方法初始化這個對象。初始化的目的是爲了讓Servlet對象在處理客戶端請求前完成一些初始化的工做,如創建數據庫的鏈接,獲取配置信息等。對於每個Servlet實例,init()方法只被調用一次

3)請求處理:Servlet容器調用Servlet的service()方法對請求進行處理。要注意的是,在service()方法調用以前,init()方法必須成功執行

4)服務終止:容器就會調用實例的destroy()方法,以便讓該實例能夠釋放它所使用的資源

考點 2)從始至終只有一個對象,多線程經過線程池訪問同一個servlet

Servlet採用多線程來處理多個請求同時訪問,Servelet容器維護了一個線程池來服務請求。

線程池其實是等待執行代碼的一組線程叫作工做者線程(WorkerThread),Servlet容器使用一個調度線程來管理工做者線程(DispatcherThread)。

當容器收到一個訪問Servlet的請求,調度者線程從線程池中選出一個工做者線程,將請求傳遞給該線程,而後由該線程來執行Servlet的service方法。

當這個線程正在執行的時候,容器收到另一個請求,調度者線程將從池中選出另一個工做者線程來服務新的請求,容器並不關係這個請求是否訪問的是同一個Servlet仍是另一個Servlet。

當容器同時收到對同一Servlet的多個請求,那這個Servlet的service方法將在多線程中併發的執行。

3)、如何現實servlet 的單線程模式

<%@ page isThreadSafe=」false」%>

 

 

 

 

 

 

 

 

 

 

JSP

1  JSP 語法:

   jsp中嵌入java代碼的方式 :

        1) 表達式標籤 <%=  1 + 1 %>

            a) 計算表達式的返回值 .

            b) 能將返回值在網頁上顯示出來 .

               不能出現 ";"

               <%= 1+1%>則在網頁上顯示2

        2) 聲明標籤 : <%!    %>

            用來聲明變量和函數, 在聲明標籤中聲明的變量和函數, 能夠在本頁面的其餘的java代碼中使用.

            聲明的位置是首是尾皆無妨. 建議儘可能少聲明變量, 由於jsp最終要被解釋爲servlet, 聲明的變

            量在servlet中就體現爲實例變量, 在多個線程訪問這個servlet的時候, 因爲實例變量被多個線

            程共享使用(實例變量線程不安全, 局部變量線程安全), 有可能出現問題, 而且很差解決.

        3) 普通腳本 :  <%   %>   普通腳本是不能嵌套的

            <%

              for( int i = 0 ; i < 10 ; i++ ){

                      <%= 1+ 1 %>

              }

            %>

指令元素 : 用來講明一個jsp文件自身的一些特色.

              以便服務器(tomcat)做出正確的處理 .

    頁面指令 :

    <%@page contentType="text/html;charset=utf-8" %>

    <%@page import="java.util.*" %>

    標籤庫指令

<%@taglib %> 

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

    包含指令 :靜態包含

      用來包含其餘jsp的源代碼 (靜態包含).

      所謂靜態包含, 就是先將引入的jsp頁包含入本頁面中, 而後解釋爲同一個servlet

      <%@include file="xxx"%>  靜態包含包含的是源代碼,考慮變量衝突,而且xxx後面不能傳參數   

動做元素                

    <jsp:include page="/a.jsp" />   

    動態包含: 包含的是對方的輸出結果, 分別解釋爲不一樣的servlet.

    動態包含實例 :

      

 

(1) header.jsp :

                <%

                   String text = request.getParameter( "text" ) ;

            %>

                   <center>

                   <h1>       

                   <font color="blue">

                   <%

                      if( text != null ){

                     %>                  

                            <h1><%=text%></h1>

                      <%

                     }else{

                       %>

                            <h1>Welcome to kettas</h1>

                        <%

                   }

                             %>

                   </font>

                   </h1>  

         </center>  

 

 

 

 

 

 

 

      

       (2) body.jsp :

                <%@page contentType="text/html" %>

                            <html>

                            <body>

<!-- 至關於<jsp:include page="/header.jsp?name=This is param"/> -->                   

         <jsp:include page="/header.jsp">

                   <jsp:param name="text" value="This is param"/>

                            </jsp:include> 

                   <h1>This is body</h1>

                            <%

                                     for(int i = 0 ; i< 3 ; i++ ){

                            %>

                            <h1><%= new java.util.Date() %></h2>

                            <%

                                     }

                            %>                                         

                            <%

                                     for( int i =0 ; i < 3 ; i++ ){                 out.println( "<h2>" + new java.util.Date() + "</h2>" ) ;

                            }

                       %>

                            </body>

                   </html>

    <jsp:forward page="/b.jsp" />

       頁面轉向 : 至關於servlet中的"接力棒"轉向, 是在同一個鏈接中的頁面轉向.

    <% response.sendRedirect("/a.jsp"); %>

頁面轉向 : 鏈接已經換了一個.

 

        

 

 

 

4  jsp 中的隱含9對象 . (能夠直接拿來使用)

    request ----> HttpServletRequest .

    response ---> HttpServletResponse .

    session ----> HttpSession .

    application -> ServletContext .

                   |-> web.xml

                   |-> setAttribute, getAttribute.

                   |-> 全局惟一 . 

    如下四個用的不多, 知道有這個東西便可  

    out  ---------> response.getWriter();<% out.println()%>

    config -------> ServletConfig <在xml中也能夠配置servlet,能夠配置初始化參數>

    exception  ---> Exception

    page    ------> Object

    至關重要的隱含對象, 重點說明之

    pageContext --> javax.serlvet.jsp.PageContext

    關於pageContext :

               1, 自己也是一個能存儲命名屬性的做用域 .

                     setAttribute("name", data)

                     getAttribute("name")

                     pageContext 做用域和聲明週期 .

                     聲明週期只侷限在本頁面 .

                     在同一頁面的不一樣標籤之間傳遞數據 .(本頁面共享數據)

                     同時保證數據不流傳到其餘頁面上 .             

               2, 能夠管理其餘做用域中的命名屬性 .

                    pageContext.getAttribute("name");

                    pageContext.getAttribute("name",int scope);

                            scope 值爲:

                       PAGE_SCOPE

                       REQUEST_SCOPE

                       SESSION_SCOPE

                       APPLICATION_SCOPE

                       爲了選擇做用域

                    pageContext.setAttribute( "name" , value );

                    pageContext.setAttribute( "name" , value , int scope );  

                    pageContext.findAttribute( "name" ) ;

                    按照從小到大的順序依次查找做用域中的命名屬性 .

                    pageCOntext --> request ---> session  --> application

                            pageCOntext.findAttribute( "a" ) ;

               3, 得到其餘全部的隱含對象 .

                   pageContext.getRequest() ---> request

                   pageCOntext.getSession()

                   pageCOntext.getConfig()

                   pageCOntext.getOut()

               注意 :  隱含對象在表達式標籤和普通腳本中均可以使用

                                           <%= request.getParameter("name") %>

                                       <%  sesison.getAttribute() %>

                            可是在聲明腳本中不能用, 好比 :

                                       <%!

                                            void fn(){

                                                     session.getAtrreibute();

                                            }

                                       %>

5  JSP的幾個頁面指令 :

         頁面指令  : 向服務器說明頁面自身的特徵,以便服務器

           1 <%@page contentType="text/xml;charset=utf-8" %> 客戶端--->>服務端的編碼

           2 <%@page import="" %> 引入名字空間      

           3 <%@page pageEncoding="GBK/GB2312/utf-8"%>(網頁的靜態內容亂碼想到pageEncoding,

                jsp文件文本編輯器所採用的編碼)--->服務器內部使用的用來指定jsp 源文件所採用的編碼方式.           

           4 <%@page isELIgnored="false" %> EL一種表達式語言,默認值不一樣的服務器不同,最好明確寫出            

                 ${ 1+1 } (false:顯示結果。true:顯示 ${ 1+1 }源代碼)           

           5 <%@page errorPage="/error.jsp"%>

                 指定錯誤頁面 .

                 jsp ---> 業務代碼 .

           6 <%@page isErrorPage="true|false"%>當是TRUE時就會有exception的隱含對象

             <%@page isErrorPage="true" errorPage="/other.jsp"%>  不能這樣轉

             A(源頁面) -------------------------> B(錯誤頁面)

             errorPage="B"           isErrorPage="true"          

           7 <%@page session="true"%>--默認值, 表示本頁面是否須要session對象.

             在servlet中只有直接調用才能獲得,而jsp中默認是有的

             <%@page language="java"%>默認的語言

             <%@page extends="XXX" %>服務器本身決定

             <%@page buffer=""%>   服務器本身決定調節

6  JSP(Servlet)中從鏈接池獲取鏈接

       1) 創建鏈接 .

       2) 執行SQL   .

       3) 處理結果  .

       4) 釋放資源 .   

     Connection pool  鏈接池

     DataSource 

     LDAP ( Light directory access protocal )輕量級目錄訪問協議

     JNDI ( java naming director interface ) Java 命名目錄接口

  使用鏈接池 :

    1) 配置鏈接池

        改配置文件 conf/context.xml  

                    <Resource driverClassName="oracle.jdbc.driver.OracleDriver" 

                     注:jar包應該放在外邊的lib包中,由於它是給tomcat用的

                                            url="jdbc:oracle:thin:@127.0.0.1:1521:XE"

                                            username="kettas"

                                            password="kettas"

                                            maxActive="2"  最大鏈接數

                                            type="javax.sql.DataSource" 鏈接類型

                                            auth="Container"  通常不改

                                            name="oracle/ds" 

                                            />

    2) 使用DataSource   

       用法:%@page import="javax.naming.*"%>

                <%

                     Context ctx = new InitialContext();

                     DataSource ds = (DataSource)ctx.lookup("java:comp/env/oracle/ds");tomcat特色:必須加java:comp/env/*

                     Connection conn = ds.getConnection();

                     out.println( "<h1>get connection!</h1>" );

                     conn.close();

                   %>

處理javabeanJSP標籤

         (1) 關於javabean要求:

                        1 具備無參的構造函數 .

                        2 針對每個成員變量,因改提供相應get/set

                        3 implments Serializable(實現才能對象序列化)

         (2) <jsp:useBean />

                      使用一個保存在某個做用域(pagecontext , request ,session, application)中的javabean .

                      <jsp:useBean id="user" class="beijing.User" scope="session"/>

                         實際上執行的代碼爲 : User u = session.getAttribute("user");

                         id的含義 : 1, 爲要使用的javabean取個名字.  

                                            2, javabean在session做用域中的命名屬性.

                         class : java bean 的類型.

                         scope : 指定一個做用域(page,request,session,application), 若不指定, 則由小到大.

         (3) <jsp:setProperty /> 五種設置屬性的方法

                   <jsp:setProperty name="" property="" value=""/>

                            name: 被操做的javabean 的名字. 即useBean中的id

                            property: 屬性名稱 id , name , phone

                            value: 值 

                   <jsp:setProperty name="" property="" param=""/>

                       param:表示該屬性的值來自於客戶端提交的參數. param用來指定這個參數的名字.   

                   <jsp:setProperty name="" property=""/>

                       客戶端提交的參數名稱和成員變量的名稱正好一致. 省略param

                   <jsp:setProperty name="" property="*"/>

                       用一個標籤爲全部的屬性賦值, 屬性的值來自於客戶端提交的參數,

                       參數名字和屬性名字 一一對應.

         (4) <jsp:getProperty />

                   使用javabean中的屬性, 可用於頁面顯示 .

                 <jsp:getProperty name="" property=""/> 

                            name: 被操做的javabean 的名字. 即useBean中的id

                            property: 屬性名稱 id , name , phone

                   使用片斷以下 :    

                            <html>

                                     <body>           

                                               <h2><jsp:getProperty name="user" property="name" /></h2>

                                               <h2><jsp:getProperty name="user" property="id"/></h2>

                                               <h2><jsp:getProperty name="user" property="phone"/></h2>

                                               <h2><jsp:getProperty name="user" property="password"/></h2>

                                     </body>

                            </html>

使用自定義的標籤

         (1) 構思, 好比寫一個對指定名字說hello的標籤, 應該是<前綴:hello user="zhagnsna"/>

         (2) 寫類

                   要實現的基礎接口 :  javax.serlvet.jsp.tagext.SimpleTag

                            其中含有五個方法 :

                             doTag         ---> 實現標籤的功能 .

                               setJspContext ---> pageContext .

                               setParent     ---> 父標籤的實現類                         

                              setJspBody    ---> JspFragement

                               getParent  

                 要實現五個方法, 顯得很繁瑣, javax.servlet.jsp.tagext.SimpleTagSupport類實現了這個

                 基礎接口, 咱們在寫類時只須要繼承這個類, 而後覆蓋doTag方法便可.

             類以下 :

                package com.kettas.tag ;

                            import javax.servlet.http.*;

                            import javax.servlet.jsp.tagext.* ;

                            import javax.servlet.jsp.* ;

                            import java.io.* ;

                            public class HelloHandler extends SimpleTagSupport{

                                               private String user ;

                                               public void setUser( String user ){

                                                        this.user = user ;

                                               }                  

                                               public String getUser(){

                                                        return user ;

                                               }             

                                               @Override

                                               public void doTag() throws JspException , IOException{

                                                        PageContext ctx = (PageContext)this.getJspContext();

                                                        ctx.getOut().println( "hello " + user  );

                                                        ctx.getOut().flush();

                                               }

                            }

         (3) 寫tld配置文件(位置爲 : /WEB-INF/***.tld)

                   <?xml version="1.0" encoding="UTF-8"?>

                   <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

                            "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

                   <taglib>

                            <tlibversion>1.0</tlibversion>

                            <jspversion>2.0</jspversion>

                            <shortname>mytag</shortname>

                            <!-- 指定命名空間 引入標籤時使用 -->

                            <uri>liucy@cernet.com</uri>

                            <tag>

                                     <!-- 標籤名 -->

                                     <name>hello</name>

                                     <!-- 標籤對應的類 -->

                                     <tag-class>com.kettas.tag.HelloHandler</tag-class>   

                                     <!-- 標籤體之中是否含有內容 -->

                                     <body-content>empty</body-content>

                                     <!-- 標籤屬性 -->

                                     <attribute>

                                               <name>user</name>

                                               <type>java.lang.String</type>

                                               <required>true</required>

                                               <rtexprvalue>true</rtexprvalue>

                                     </attribute>

                            </tag>

                   </taglib>

         (4) 在jsp文件中使用

                   <%@page contentType="text/html"%>

                   <%-- 注意引入自定義標籤的方式, prefix屬性指定標籤前綴, 前綴解決不一樣標籤庫標籤重名 --%>

                   <%@taglib uri="liucy@cernet.com" prefix="liucy"%>

                   <html>                                       

                            <body>

                                     <h2>

                                               <liucy:hello user='<%= request.getParameter( "name" )%>'/>

                                     </h2>

                            </body>

                   </html>

                   自定義一個循環標籤 :

                            : =================================================================

                                    

 

package com.kettas.tag ;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

import java.io.*;

public class LoopHandler extends SimpleTagSupport{

private int begin ;

private int end ;

public void setBegin( int begin ){

         this.begin = begin ;

         }                    

         public int getBegin( ){

                  return begin ;

                   }              

         public void setEnd(int end ){

                   this.end = end ;

         }                

         public int getEnd( ){

         return end ;

                   }

         @Override

         public void doTag()throws JspException ,IOException{

           // JspFragment對象能夠獲取標籤體內部的內容

           JspFragment f = this.getJspBody();

           PageContext ctx = (PageContext)this.getJspContext();

  for( int i = begin ; i < end ; i++){

                   f.invoke( ctx.getOut() );

                              }

                   }

         }

 

                  

         配置文件以下 :=================================================================

                  

 

<?xml version="1.0" encoding="UTF-8"?>

         <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

                            "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

                   <taglib>

                            <tlibversion>1.0</tlibversion>

                            <jspversion>2.0</jspversion>

                            <shortname>mytag</shortname>

                            <uri>liucy@cernet.com</uri>

                            <tag>

                            <name>hello</name>

                            <tag-class>com.kettas.tag.HelloHandler</tag-class>   

                            <body-content>empty</body-content>

                            <attribute>

                            <name>user</name>

                            <type>java.lang.String</type>

                            <required>true</required>

                            <rtexprvalue>true</rtexprvalue>

                            </attribute>

                            </tag>

                            <tag>

                            <name>loop</name>

                            <tag-class>com.kettas.tag.LoopHandler</tag-class>

                            <!-- 標籤體內含有內容, 而且是非腳本的內容 -->

                                     <body-content>scriptless</body-content>

                            <attribute>

                            <name>begin</name>

                            <type>int</type>

                   <required>true</required>                                                 <rtexprvalue>true</rtexprvalue>

                            </attribute>

                            <attribute>

                            <name>end</name>

                  <type>int</type>

                  <required>true</required>

                   <rtexprvalue>true</rtexprvalue>

                  </attribute>

                   </tag>

         </taglib>

 

                            使用以下 :======================================================================

                                     <%@taglib uri="liucy@cernet.com" prefix="liucy"%>

                                     <liucy:loop begin="0" end="3">

                                               <h2>Hello !</h2>

                                     </liucy:loop>

                                     如此即可連續在網頁上輸出三個"Hello !"

 

 

9  EL表達式( ${ } )

           (1) 完成一些簡單運算.

                 數學運算

                          + - * % /      ${ a + b }

                 布爾運算

                 >       gt  ( great than )

                 <       lt  ( less than )

                 >=      ge  ( great equal )

                 <=      le  ( less equal )

                  !=      ne  ( not equal )

                 ==      eq  ( equal )

                 ${ a > b }   ${ a gt b }

            邏輯運算

                     && || !

                     and or not 

            非空運算 :

                   a == null

                   ${ not empty a }

                      |-> a 不存在返回true

                      |-> a 存在 返回false 

           (2) 經過EL表達式,快捷的訪問做用域中的命名屬性

               <%= session.getAttribute( "name" )%>

               用EL表達式 : ${ name }

           (3) 快速訪問javabean的屬性.

               <jsp:getProperty name="user" property="name"/>

               用EL表達式 : ${ user.name }

           (4) 經常使用隱含對象 .

               ${ param } 

               ${ param.age }

               ${ param.name }

               至關於 : <%= request.getParameter( "name" ) %>

               用來訪問客戶端提交的參數.

               ${ cookie.age }

               實際要執行的代碼 :

                         Cookie[] c = request.getCookies();

                         for( Cookie a : c ){

                                    if(a.getName() == "age"){

                                            a.getValue();

                                            ...

                                    }

                         }

10 JSP寫的一套核心標籤, 有了這套標籤, 根本不須要自定義標籤了

         (1) 準備

                   須要standard.jar, jstl.jar兩個jar包, 放入Tomcat 6.0/lib目錄中(或者是/WEB-INF/lib)

(2)core<%@tagliburi="http://java.sun.com/jsp/jstl/core"

prefix="c"%>

         forEach循環

     ①通常用法 至關普通的for循環

<c:forEach begin =」1」 end=」10」 varstatas="st">

                ${ st.count }</c:forEach>

 

               

 

② 迭代循環 集合

<c:forEach var="u" items="${ users }">

                                  ${ u .name}

                 </c:forEach>

如果map集合${ user.key}獲得值的集合

             set 

                        (1)<c:set var="a" value="1234"/>  

                        (2)<c:set var="a">

                        xxxxx

                        </c:set>  把標籤體內全部的輸出都看成var的值,不直接顯示在網頁上

                             使用須要調用${a}

                   remove    

                        <c:remove var="a"/>

                                    ${a}

                   url

                        <c:url var="date" value="/jspapp/date.jsp">

                        <c:param name="age" value="23"/>

                        <c:param name="name" value="lisi"/>

                        <c:param name="passwd" value="ffff"/>

                        </c:url>

 

                        <a href="${date}">test</a>

                        /jspapp/xxx.jsp?age=23  

<a href="/jspapp/xxx.jsp?age=23&name=lsis&passwd=123">

                          test

                        </a>

                      if swith

               <c:if test=」s{4>2}」>xxxxx</c:if>

 

                      <c:choose>

                          <c:when test="a">

                                    cccccccc

                          </c:when>

                          <c:when test="b"></c:when>

                          ....

                      </c:choose>

                      <c:choose>

                          <c:when test="">

                                    cddddddd

                          </c:when>

                          <c:when test="">

                           sssss

                          </c:when>

                          <c"when test="">

                           xxxxxx

                          </c:when>

                          <c:otherwise>

                         

                          </c:otherwise>

                      </c:choose> 


 


 

第五天:===========================

MVC :

   M : model ( 業務邏輯與業務數據 ): javabean

   V : view ( 顯示邏輯 )

        將數據按照用戶的    要求顯示出來 .

        對同一份數據而言,能夠 以 多種形式

        體現 ( 類表, 屏圖,柱圖 等等 )

           用JSP實現。

   C : controller ( 控制器 , 負責程序的流程控制 )

       接收用戶請求 , 根據業務邏輯的執行狀況 返回

       相應的結果 .

                 用Servlet來實現。

===================================================

好處 :

   1) 各司其職, 解耦合 .

      代碼可重用。

================================================

前端控制器(Servlet)的工做指責 :

  1) 可以接受全部的用戶請求 .

      <url-pattern>*</url-pattern>

  2) 能跟據請求的不一樣 調用 不一樣的處理(javabean) .

      a, 請求的不一樣 ---> url ---> servletpath

         http://loxxx:8080/app/login

         http://loxxx:8080/app/query

         request.getServletPath() --> path

          

          login=A f1 f2 f3

         

=================================

query=B

          delete=C

         

      b, 經過一個配置文件,向servlet說明 被調用

         組件 和 serlvetpath 之間的對應關係 .

      C, 要求全部的被調用的組件 必須按照某個接口

         的規發來進行開發 .這樣才能由servlet正確的

         調用 . 

        

Action的主要做用是得到參數,讓業務(Biz)處理,而後把處理的結果返回給Action再返回給Servlet。

         public interface Action{

          public String  execute( request , response )

         }

         LoginAction

            execute( Request , response ){

            String name = request.getParameter( .. ) ;

            String pwd = request.getParameter( "" );

                 UserBiz biz = new UserBiz();

                 biz.login( name , pwd );

                 return "ok.jsp|error.jsp" ;

          }

         UserBiz

            login( userName , password )

 

        Servlet ---> Action ---> Biz 

       1) biz 實現業務邏輯

       2) 寫Action

           a, 準備參數

           b, 調用biz

           c, 根據biz的運行結果,返回對應URL

       3)在配置文件中, 指定servletpath 與 Action之間的對應關係 .

       4) 編寫下一個JSP

   ============================================

   ProductBiz

      |-> Collection<Product> getAllProducts();

      return Collection;

     

      QuerProductAction

      |-> execute()

            |-> biz.getAllProducts(); --> disp.jsp

                 return disp.jsp;

 

MVC的大至執行順序:

1,用戶發送請求>2獲取用戶的servletpath>3根據servletpath在配置文件中查找javabean的名字,>4返回名字>5,execute>6,複雜業務計算>7,返回下一個頁面的URL>8根據URL轉向下一個頁面>9把頁面返回給用戶。

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Struts 1.2

第一天:

MVC : M : 業務邏輯,業務數據 ( 能夠重複利用 ) java Bean ( VO BO) EJB    其實struts1沒有實現業務層,也沒法實現

V : 顯示邏輯 ,同一份數據 ,對應多種顯示方法. JSP代碼實現。

C:流程控制器 , Servlet代碼實現。javabean Servlet javabean 其實他有兩個部分組成:

       1,系統核心控制器 由Struts 1 框架提供,就是 ActionServlet

2,業務邏輯控制器 由Struts 1框架提供就是用戶本身寫的Action 實例

 在struts-config.xml配置文件中的一些屬性: >

Struts : 基於mvc的軟件框架 . Struts :

1使用struts須要完成的準備工做 :

1) 前置控制器 (ActionServlet) .

 2) 定義了配置文件的格式 . /WEB-INF/struts-config.xml

 3) 提供了一個父類, Action , 要求全部的javabean 都來繼承這個父類 , 覆蓋其中的方法 .  使用struts1須要完成的準備工做 : version 2.0  version 1.2.x  下面是1.2的版本

1) 獲取struts的jar包 --> 拷貝到WEB-INF/lib

2) 對struts提供的前端控制器( ActionServlet ) 在 本身的web.xml中 進行配置

3) 確保struts用到的配置文件被放置到指定的位置 . struts1.2.7/webapps/struts-blank.war 解

         壓以後,從中拷貝struts-config.xml到咱們 本身的應用裏 .

4) 將struts提供的jar包配置到classpath中. struts.jar : 編譯時依賴

 

2經常使用的業務流程

0) 寫jsp , 這個jSP中有用戶須要的鏈接或表單,

1) javabean , 經過它裏面的方法,完成業務邏輯 .

2) 寫Action , 調用javabean ,並根據javabean的結果,返回不一樣的頁面 .

3) 在配置文件中對Action進行配置 .

4) 寫jsp login.do http://localhost:8989/strutsapp/ok.jsp Resource file

1) 編寫資源文件. a, properties

2) 在struts-config.xml中對資源文件進行配置 . 通知struts, 要使用的資源文件的名稱 .

3) 在jsp中使用資源文件的內容 . 編程時使用key 顯示時看到的是value

errors.header //errors會在全部錯誤的開頭自動加上該key所表明的值(value), errors.footer //errors會在全部錯誤的結尾自動加上該key所表明的值(value), ActionForm : 用來保存客戶端提交的數據 .

name password ----> Object |->name |->password

1) 寫一個類( ActionForm ) , 用於保存客戶端提交的參數.

2) 編輯配置文件, 告知struts,什麼樣的請求 使用哪一個ActionForm 對象 .

3) Actionexecute方法中, ActionForm對象中獲取數據 .經過ActionForm作驗證 .

1) 在配置文件中說明,哪些請求是須要作驗證的 .

2) 在ActionForm裏編寫驗證代碼 . @Override validate() ActionMessage ---> Resource

3) 在錯誤頁面上顯示錯誤信息 .

0) 編寫biz對象的方法,用於處理用戶請求 . |-> 測試功能

1) 編寫用戶發送請、求的頁面

                           2) 根據表單的參數 編寫 ActionForm

3) 編寫Action對象.execute方法 |-> 調用biz對象的方法. |->

根據biz方法的返回結果,返回不一樣的ActionForward

4) 對ActionForm , Action 進行配置 .

5) 編寫與 ActionForward 對應的jsp頁面 .

 

次日:具體實現

  <form-beans>

        <form-bean name="" type=""/>

  </form-beans>

  <action-mappings>

        <action path="" type="" name="" validate="true" input="">

                 <forward name="" path="" redirect="true"/>

        </action>

  </action-mappings>

<html:errors />

3,經常使用配置文件  最原始的Action接口,驗證登錄的實例

         (1) web.xml文件 :

                   <?xml version="1.0" encoding="utf-8"?>                 

                   <web-app xmlns="http://java.sun.com/xml/ns/javaee"

                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

                      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">   

                     

                       <!—在web.Xml配置前端控制器 -->

                            <servlet>           

                                     <init-param>

                                               <param-name>config</param-name>

                                               <param-value>/WEB-INF/struts-config.xml</param-value>

                                     </init-param>

                                     <init-param>

                                               <param-name>debug</param-name>

                                               <param-value>2</param-value>

                                     </init-param>  

                                     <init-param>

                                               <param-name>detail</param-name>

                                               <param-value>2</param-value>

                                     </init-param>

                                     <servlet-name>actionServlet</servlet-name>

                                     <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

                                     <load-on-startup>3</load-on-startup>

                            </servlet>

                           

                            <!-- 對任意請求,都採用Struts提供的那個ActionServlet進行轉發 -->

                            <servlet-mapping>

                                     <servlet-name>actionServlet</servlet-name>

                                     <url-pattern>*.do</url-pattern>

                            </servlet-mapping>

                           

                   </web-app>

                  

         (2) struts-config.xml文件 :

                   ActionServlet<?xml version="1.0" encoding="utf-8" ?>

                   <!DOCTYPE struts-config PUBLIC

                             "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"

                             "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

                   <struts-config>

                   <form-beans>

<!-- 將表單提交的數據封裝爲一個對象 name屬性對應Action中的name  本身手動寫的actionform-->

                                     <form-bean name="loginForm" type="com.kettas.struts.LoginForm"/>

                      <!—動態actionForm

<form-bean name="regForm" type="org.apache.struts.action.DynaActionForm">

                            <form-property name="userName" type="String"/>

                            <form-property name="age" type="java.lang.Integer"/>

                         </form-bean>

                            </form-beans>

                           

                            <!-- 指定映射 指定請求路徑對應指定Action

                                      name屬性指定與此Action對應的表單對象

                                      validate指定是否採用表單驗證 input指定如果表單驗證出錯 要去的頁面 -->

                            <action-mappings>

                                     <action path="/login" type="com.kettas.struts.LoginAction" name="loginForm"

                                               validate="true" input="/login.jsp">

                                               <forward name="ok" path="/ok.jsp" redirect="true"/>

                                               <forward name="error" path="/error.jsp"/>

                                     </action>

                            </action-mappings>

                           

                            <!-- 指定資源文件 注意 : 以WEB-INF/classes爲根目錄 -->

                            <message-resources parameter="res.AppResources"/>

                   </struts-config>

                  

         (3) 表單對象  本身手動寫actionForm

                   package com.kettas.struts ;

                   import org.apache.struts.action.* ;

                   import javax.servlet.http.* ;

                   // 要繼承ActionForm類

                   public class LoginForm extends ActionForm{

                            // 成員變量的名字要和客戶端參數一一對應.

                            private String userName ;

                            private String password ;

                            // 添加get、set方法

                            。。。。。。。。

                             

                            /***********************************************

                             * 用於對錶單的數據進行驗證, 該方法在調用execute以前

                             * 被前端控制器調用,根據他的返回結果,來判斷驗證是否

                             * 成功

                             ************************************************/

                            @Override

                            public ActionErrors validate( ActionMapping mapping ,

                                                                  HttpServletRequest request )

                            {// errors用於存放錯誤的集合

                                      ActionErrors errors = new ActionErrors();

                                      if( userName == null || userName.trim().length() == 0 ){

                                              // ActionMessage對象用來裝載錯誤信息 初始化參數爲資源文件中的鍵

                                              ActionMessage m = new ActionMessage( "errors.username.required" );

                                              errors.add( "error" , m );    

                                      } 

                                      if( password == null || password.trim().length()<3 ){

                                               ActionMessage m = new ActionMessage( "errors.password.required" ) ;

                                               errors.add( "error" , m ) ;

                                      }           

                                      // 若返回的對象size爲0 則說明驗證經過 不然進入Action中input屬性指定的頁面中        

                                      return errors ;

                            }

                   }

                  

                   // 在input指定的頁面中要顯示ActionErrors中的錯誤信息 則要用到標籤 : <html:errors/>

                      errors.header : 錯誤信息的頭    

                      errors.footer : 錯誤信息的主體

                      引入標籤庫 : <%@taglib uri="http://struts.apache.org/tags-html" prefix="html"%>

                  

                   // <bean:message key="login.password"/> : 用於顯示資源文件中指定鍵值對應的內容

                      因爲規範的jsp頁面中除了標籤是不能含有靜態文本內容的,故這個標籤會被大量使用

                      引入標籤庫 : <%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>

(4) Action : 的實現

                   package com.kettas.struts ;

                   import org.apache.struts.action.* ;

                   import javax.servlet.http.* ;

                   import com.kettas.biz.*;

                  

                   public class LoginAction extends Action{

                            @Override

                            public ActionForward execute( ActionMapping mapping , ActionForm form ,

                                                                           HttpServletRequest request ,  HttpServletResponse response )                                                                                                                                         

                            {        // 傳統的獲取表單數據方式

                                      // String name = request.getParameter("userName" ) ;

                                      // String pwd = request.getParameter("password" ) ;                                                         

                                      // 獲得表單對象 從中獲取表單數據

                                      LoginForm lf = (LoginForm)form ;

                                      // 調用biz對象,返回下一個頁面 .

                                      try{

                                              UserService biz = new UserService();     

                                              biz.login( lf.getUserName() , lf.getPassword() ) ;

                                             

                                              ActionForward af = mapping.findForward("ok");

                                              return af ;

                                      }catch( Exception e ){

                                                request.setAttribute( "errorMessage" , e.getMessage() ) ;

                                                return mapping.findForward( "error" );

                                      }

                            }                                                                                                                                                   

                   }

                  

         (5) Biz的實現 :

                   package com.kettas.biz ;

                   public class UserService{

                            public void login( String name , String pwd ){

                                     if( ! name.equals( "liucy" ) ){

                                               throw new RuntimeException( "user " + name + " not found" ) ;    

                                     }

                                     if( ! pwd.equals( "12345" ) ){

                                               throw new RuntimeException( "Invalid password" ) ;

                                     }

                            }

                   }

 

 

 

4,資源文件 .國際化

 1, 默認資源文件 : 當沒有專門爲每一個用戶準備資源文件

                  時 ,使用默認資源文件 .

  <message-resources parameter="res.AppResources"/>

2,其餘資源文件在命名上有一個規定 .

     默認資源文件名_國家縮寫 .

     AppResources_zh

     AppResources_ja

  內容上是鍵值對  login.username=USER NAME:  前面是名稱後面是顯示的值

在jsp上的使用:<bean:define id="add"> <bean:message key=" login.username "/></bean:define>

3, 全部的資源文件要以utf-8的編碼來編寫 .若是不是的話要進去如下轉換。

     a,用中文編寫一個臨時的資源文件a.properties ( 中國字 GBK )

                       臨時文件中的編碼   臨時文件的名字   新文件的文件名

 b, native2ascii -encoding       GBK         a.properties     AppResources_zh.properties

.        

    

5struts 中的異常處理 :==================

  ---> Action ---> Biz ---> Dao

      Action中對異常進行捕獲 .

      try{

              biz.fn();       

              return mapping.findforward( "ok" ) ;

      }catch( Exception e){

              return mapping.findforward( "error" );

      }

          系統級異常:

     * 因爲沒個具體的技術操做致使的異常 ,

     * 系統級異常一般是定義好的類型( SQLException , IOException )

     * 通常發生在DAO層 .

     * 在處裏上要粒度粗一些 RuntimeException

     應用級異常 

     * 因爲用戶違反了特定的業務邏輯致使的異常

     * 應用級通常是用戶自定義的異常 .    

     * 通常發生在 biz 層 . 

     * 粒度細一些 .

    

     最好作一個異常的體系結構

    

     實例 :

     (1) struts-config.xml文件 :

               <?xml version="1.0" encoding="UTF-8" ?>

                            <!DOCTYPE struts-config PUBLIC

                                      "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"

                                      "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

                            <struts-config>

                                     <form-beans>

                                               <form-bean name="loginForm" type="com.kettas.struts.LoginForm"/>

                            動態actionForm

                           <form-bean name="regForm" type="org.apache.struts.action.DynaActionForm">

                                    <form-property name="userName" type="String"/>

                                    <form-property name="age" type="java.lang.Integer"/>

               </form-bean>

                                     </form-beans>

                                    <!-- 全局變量 可用在一些struts標籤中 如<html:link /> -->

                                <global-forwards>

                                        <forward name="login" path="/login.jsp"/>

                                </global-forwards>

                                     <action-mappings>

                                               <action path="/login" type="com.kettas.struts.LoginAction" name="loginForm"

                                                        validate="true" input="/login.jsp">

                                                        <!-- 將Action中拋出的異常捕獲 並跳轉到對應的錯誤頁面

                                                                  在錯誤頁面中 仍是用標籤<html:errors />來顯示錯誤

                                                                  可見 這裏key標籤中指定的資源文件內容已經被封裝到

                                                                  ActionErrors對象中去了 -->

                                                        <exception type="com.kettas.struts.expt.SystemException"

                                                                 path="/error.jsp" key="errors.system"/>

                                                        <exception type="com.kettas.struts.expt.UserNotFoundException"

                                                                 path="/error.jsp" key="errors.user"/>

                                                        <exception type="com.kettas.struts.expt.PasswordException"

                                                                 path="/error.jsp" key="errors.pwd"/>

                                                       

                                                        <!-- redirect="true"表示在一個新的鏈接中打開指定頁面

                                                                  默認在同一個鏈接中打開指定頁面 -->

                                                        <forward name="ok" path="/ok.jsp" redirect="true"/>

                                                        <forward name="error" path="/error.jsp"/>

                                               </action>                                          

                                     </action-mappings>

                                     //引入資源文件

                                     <message-resources parameter="res.AppResources"/>

                            </struts-config>

                           

                   (2) 定義根系統異常 做爲其餘一切系統異常的父類 這一步是有意義的

                            package com.kettas.struts.expt ;

                            // 繼承至RuntimeException類而不是Exception 如此無需trycatch捕獲可自動拋出異常

                            public class SystemException extends RuntimeException{

                                     // 注意寫這三個構造函數 後面都這麼寫

                                     public SystemException( ){

                                               super();       

                                     }        

                                     public SystemException( String msg ){

                                               super( msg ) ;

                                      }              

                                     public SystemException( Throwable t ){

                                               super( t );

                                     }}

                            // 定義根業務異常 做爲其餘一切業務異常的父類

                            package com.kettas.struts.expt ;

                            public class BizException extends RuntimeException{

                                     ..

                            }

                            // 密碼錯誤異常 繼承至根業務異常

                            package com.kettas.struts.expt ;

                            public class PasswordException extends BizException{

                                     ...

                            }

                            // 用戶未發現異常 繼承至根業務異常

                            package com.kettas.struts.expt ;

                            public class UserNotFoundException extends BizException{

                                     ...

                            }

                   (3) dao的實現 :

                            import ...

                            // 因爲是採用tomcat的鏈接池獲取鏈接故這裏引入這兩個名字空間

                            import javax.sql.* ;

                            import javax.naming.* ;

                           

                            public class UserDao{

                                     public User queryByLoginName( String loginName ){

                                               Connection conn = null ;

                                               PreparedStatement pstm = null ;

                                               ResultSet rs = null ;  

                                               String sql = "select id , loginname , password from liucy_users where loginname=?" ;

                                               User u = null ;

                                               try{

                                                        // 從鏈接池中獲取鏈接的三個步驟        

                                                        Context ctx = new InitialContext();

                                                        DataSource ds = (DataSource)ctx.lookup( "java:comp/env/oracle/ds" ) ;         

                                                        conn = ds.getConnection();                                                    

                  

                                                        pstm = conn.prepareStatement( sql ) ;

                                                        pstm.setString( 1 , loginName ) ; 

                                                        rs = pstm.executeQuery();

                                                        if( rs.next() ){

                                                                 u = new User();

                                                                 u.setId( rs.getInt( 1 ) ) ;

                                                                 u.setLoginName( rs.getString(2 ) ) ;

                                                                 u.setPassword( rs.getString( 3 ) ) ;

                                                        }                                    

                                                        return u ;

                                               }catch( Exception e){ 

                                                         e.printStackTrace();

                                                         // 拋出前面定義的系統異常 拋給biz 再從biz拋出 拋給Action 而後被系統捕獲

                                                         throw new SystemException( e );

                                               }finally{

                                                        if( rs != null ) try{ rs.close(); }catch( Exception e){}

                                                        if( pstm != null ) try{ pstm.close();}catch( Exception e ){}

                                                        // 因爲是鏈接池中的鏈接 故不會真的關閉 只是被鏈接池回收

                                                        if( conn != null ) try{ conn.close();}catch( Exception e ){}

                                               }}}

                   (4) biz的實現 :

                            public class UserService{

                                     public void login( String name , String pwd ){

                                               UserDao dao = new UserDao();

                                               User u = dao.queryByLoginName(name);

                                               if( u == null ){

                                                        // 拋出用戶不存在業務異常

                                                        throw new UserNotFoundException( "user " + name + " not found" ) ;

                                               }

                                               if( ! u.getPassword().equals( pwd ) ){

                                                        // 拋出密碼錯誤業務異常

                                                        throw new PasswordException( "Invalid password" );

                                               }}}

                   (5) Action的實現 :

                            public class LoginAction extends Action{

                                     @Override

                                     public ActionForward execute( ActionMapping mapping , ActionForm form ,

                                                                           HttpServletRequest request ,  HttpServletResponse response )                                             {    LoginForm lf = (LoginForm)form ;

                                                /*

                                                try{

                                                */             

                                                        // 這裏會自動拋出biz和dao中的異常 拋給struts處理

                                                        UserService biz = new UserService();     

                                                        biz.login( lf.getUserName() , lf.getPassword() ) ;

                                                        ActionForward af = mapping.findForward("ok");

                                                        return af ;                                          

                                                /*

                                                // 若本身處理異常 則比較麻煩,能夠在struts配置文件配置

                                                }catch( SystemException e ){

                                                         request.setAttribute( "errorMessage" , "System is busy" ) ;

                                                         return mapping.findForward( "error" );

                                                }catch( UserNotFoundException  e){

                                                         request.setAttribute( "errorMessage" , e.getMessage() ) ;

                                                         return mapping.findForward( "error" ) ;

                                                }catch( PasswordException e ){

                                                         request.setAttribute( "errorMessage" , e.getMessage() ) ;

                                                         return mapping.findForward( "error" ) ; 

                                                }catch( Exception e ){

                                                         request.setAttribute( "errorMessage" , "you catch an error" );

                                                         return mapping.findForward( "error" ) ; 

                                                }  

                                                */                                         

                                     }}                                                                                                  

4  ActionMessages對象 :

         public class MessageAction extends Action{     

                   @Override

                   public ActionForward execute( ActionMapping mapping , ActionForm form ,        

                                                        HttpServletRequest request , HttpServletResponse response )                                     

                   {ActionMessages messages = new ActionMessages();

                            // 用資源文件內容初始化

                            ActionMessage m1 = new ActionMessage( "msg1" );

                            ActionMessage m2 = new ActionMessage( "msg2" ) ;

                            messages.add( "message" , m1 ) ;

                            messages.add( "message" , m2 ) ;

                            request.setAttribute( "msgs" , messages );

                            return mapping.findForward( "ok" );                

                   }                                                                                                                                                   

         }

         // 在jsp中顯示ActionMessages內容

         <html>

                   <body>

                            This message jsp

                            <!-- name指定命名屬性 -->

                            <html:messages id="m" name="msgs">  

                                     <h1>${m}</h1>

                            </html:messages>

                   </body>

         </html>

<bean:message />

<html:errors />

 

html: 處理頁面的顯示問題

bean: 定義變量和javabean  <c:set />

logic: <c:if > <c:forEach> 

       <forward name="ok" path="/path.jsp"/>

 

html:

  <html:link /> <===> <a href="">

 

  <html:link forward="xxxx" page="xxx">Test</html:link>

      page : 指向一個明確的鏈接地址 .

      forward : 全局的forward 的 邏輯名字 .

    * 能夠自動加應用名稱

    * 能夠使用邏輯名字 .

    * 在不支持cookie的狀況下, 自動增長jsessionid

  <html:link forward="ok"></html:link>

 

 

 <html:form action="/login.do" method="">

    <input type="text" name="age"/>

    <html:text property="age"/>

   

    <input type="password" name=""/>

    <html:password />

   

    <select name="">

       <option>aaa</option>

    </slelect>  

   

    <html:select>

       <html:option></html:option>

    </html:select>              

   

    <input type="hidden" name="" value=""/>

    <html:hidden />

</html:form>  

 

 

<html:messages id="" name="">

</html:messages>           

name : 被迭代的消息結合在做用域中的名字 .

id   : 當前整備迭代的消息對象 .

* 被該標籤迭代的集合類型是 ActionMessages類型 .

  集合中的每一個元素都是 一個 ActionMessage , 他

  可以封裝資源文件中的數據 .

<html:errors />

 

定義一個變量:id表示變量名,value:表示變量值

<bean:define id="a" value="1234"/>

<bean:define id="">

         XXXXXXXX

</bean:define>

定義命名屬性:

<bean:define id="a" name="data"/>

Action ---> a.jsp

request.setAttribute( "a" , "hello")

${ a }

 

 

 

 

 

 

 

第三天標籤的使用======================================================================================

5  struts標籤 :

 

<html:link forward="login"page="/webdir/login.jsp">

Test</html:link>

      page : 指向一個明確的鏈接地址 .

      forward : 全局的forward的邏輯名字, 在配置文件中指定的 :

    <global-forwards>

<forward name="login" path="/login.jsp"/>

      </global-forwards>

    * 能夠自動加應用名稱

    * 能夠使用邏輯名字, 在配置文件中說明實際路徑

    * 在不支持cookie的狀況下, 自動增長jsessionid

   

     在html中表單標籤用struts標籤代替 :

     <!-- action中無需寫應用名 會自動添加上 -->

       <html:form action="/login.do" method="">

         <-- <input type="text" name="age"/> -->

             <html:text property="age" value=""/>  

       <!-- <input type="password" name="pwd"/> -->

              <html:password property="pwd"/>

 <!--<select name="">

<option>aaa</option>

 </slelect> --> 

      <html:select>

         <html:option></html:option>

      </html:select>              

              

   <!-- <input type="hidden" name="" value=""/> -->

               <html:hidden />        

      </html:form>  

            

      html :

           <html:link  forward|page="/" >

           <html:form action="" method="">

            <html:text property="" value=""/>

            <html:password  property=""/>

            <html:select property=""/>

        <html:option/>

        <html:radio  property=""  />

        <html:checkbo property=""/>

      </html:form>

      <html:errors/>             

      <html:messages id="m" name="">

                 ${m}

      </html:messages>

                

     bean :

      <!-- 在當前頁面範圍內 定義一個變量 -->

       <bean:define id="" value=""/>

        <bean:define id="">

                      ...

        </bean:define> 

       <!-- 將某一個命名屬性對應的值賦予變量 -->

       <bean:define id="a" name="student"/>

  <bean:define id="a" name="student" property="name"/> 

 至關於 : String a = student.getName();

 <!-- 將客戶端提交的指定表單數據賦予變量 -->      

       <bean:parameter id="a" name="age"/>

       <!-- 將客戶端提交的指定cookie的值賦予變量 -->

        <bean:cookie id="c" name="JSESSIONID"/>  

        <!-- 顯示資源文件內容 -->

        <bean:message key=""/>

             

      logic :

      <logic:present parameter|cookie|name="age">

                       xxxxxxx ;

                       xxxxxxx ;

                       xxxxxxx ;

                   </logic:present> 

                   <logic:notPresent >

                       Xxxxx

                   </logic:notPresent>

                  

 <logic:greaterThan  parameter="age" value="23">

                      

 </logic:greaterThan>  

 <logic:greateThan cookie="age" value="23"> 

                       cxddddd

 </logic:greateThan >

<logic:greateThan name="student"property="age"value="23">

 </logic:greateThan>

                  

<logic:equal>

  <logic:notEqual>

 <logic:greaterThan>

 <logic:lessThan>

 <logic:greaterEqual>

 <logic:lessEqual>   

 <!-- 循環標籤 -->

 <logic:iterate id="" collection="">

 </logic:iterate>

 

 

=================================================

request ----> ActionForm  ---> Action  

簡化對ActionForm 的開發 .直接在配置文件配置,不用寫單獨的類

DynaActionForm ( 動態 ActionForm )

    1) 在配置文件中配 .

      <form-beans>

           <form-bean name="" type=""/>

           <form-bean name="regForm" type="org.apache.struts.action.DynaActionForm">

              <form-property name="userName" type="String"/>

              <form-property name="age" type="java.lang.Integer"/>

           </form-bean>

      </form-beans>

    2) Action中使用. 

         execute( ActionForm form ){

                 DynaActionForm af = ( DynaActionForm )form ;

                     af.get( "age" ) ;

                     af.get( "userName" ) ;

         }  

================================================

login , register , query

      

關於MappingDispatchAction, DispatchAction, LookupDispatchAction

      (1) MappingDispatchAction : 允許一個action中包含多個方法,分別處理與之對應的請求

      實例 :

           配置文件 :

                      <form-bean name="dynaLoginForm" type="org.apache.struts.action.DynaActionForm">

                            <form-property name="userName" type="java.lang.String"/>

                            <form-property name="password" type="java.lang.String"/>

                      </form-bean>

                     

                      <form-bean name="dynaRegForm" type="org.apache.struts.action.DynaActionForm">

                            <form-property name="userName" type="java.lang.String"/>

                            <form-property name="password" type="java.lang.String"/>

                            <form-property name="email" type="java.lang.String" />

                      </form-bean>

                      ...

                      ...

                      <action parameter="login" path="/login" type="com.kettas.struts.

                            UserSelfServiceAction" name="dynaLoginForm">

                            <exception type="com.kettas.struts.expt.SystemException" path="/error.jsp"

                                  key="errors.system"/>

                            <exception type="com.kettas.struts.expt.UserNotFoundException"

                                  path="/error.jsp" key="errors.user"/>

                            <exception type="com.kettas.struts.expt.PasswordException" path="/error.jsp"

                                  key="errors.pwd"/>

                            <forward name="ok" path="/ok.jsp" redirect="true"/>

                      </action>                                 

                     

                      <action parameter="register" path="/reg" type="com.kettas.struts.

                            UserSelfServiceAction" name="dynaRegForm">

                            <forward name="ok" path="/regok.jsp"/>

                      </action>

                      ...

                     

                 Action :

                      public class UserSelfServiceAction extends MappingDispatchAction{

                            // 用於處理用戶登錄請求 .

                            public ActionForward login( ActionMapping mapping , ActionForm form ,

                                                  HttpServletRequest request , HttpServletResponse response )

                          {

                                  DynaActionForm daf = (DynaActionForm)form ;

                                  String userName = (String)daf.get( "userName" );

                                  String password = (String)daf.get( "password" ) ;

                                 

                                  UserService biz = new UserService();

                                  biz.login( userName , password );

                                  return mapping.findForward( "ok" ) ;

                            }                               

                            // 負責處理用戶的註冊請求

                            public ActionForward register( ActionMapping mapping , ActionForm form ,

                                                  HttpServletRequest request ,   HttpServletResponse response )

                          {

                                   DynaActionForm daf = ( DynaActionForm ) form ;

                                   System.out.println( daf.get( "userName" ) ) ;

                                   System.out.println( daf.get( "password" ) ) ;

                                   System.out.println( daf.get( "email" ) ) ;

                                   return mapping.findForward( "ok" ) ;

                          } }                 

      (2) DispatchAction :

           1 將相關的操做合併在同一個Action中處理,這些相關的操做,必須使用同一個ActionForm 

           2 客戶端提交的參數值決定使用Action中的哪一個方法

           3 不能覆蓋execute方法,爲每個請求單獨寫一個方法

           4 採用DispatchAction的方式簡化了配置文件

          

           實例 :

                 配置文件 :

                 <!-- parameter指定客戶端請求中決定action方法的那個參數 -->

                 <action parameter="method" path="/all" type="com.kettas.struts.

                      DispatchActionSample" name="allForm">

                      <exception type="com.kettas.struts.expt.SystemException" path="/error.jsp"

                            key="errors.system"/>

                      <forward name="ok" path="/ok.jsp" redirect="true"/>

                      <forward name="regOk" path="/regok.jsp"/>

                 </action>

                

                 Action :

                      public class DispatchActionSample extends DispatchAction{    

                            public ActionForward login( ActionMapping mapping , ActionForm form ,

                                                  HttpServletRequest request , HttpServletResponse response )

                            {

                                  DynaActionForm daf = (DynaActionForm)form ;

                                  String userName = (String)daf.get( "userName" ) ;

                                  String password = (String)daf.get( "password" ) ;

                                  UserService service = new UserService();

                                  service.login( userName , password ) ;

                                  return mapping.findForward( "ok" ) ;

                            }

                            public ActionForward register( ActionMapping mapping , ActionForm form ,

                                                   HttpServletRequest request ,   HttpServletResponse response )

                            {

                                   DynaActionForm daf = (DynaActionForm)form ;

                                   System.out.println( daf.get( "userName" ) );

                                   System.out.println( daf.get( "password" ) ) ;

                                   System.out.println( daf.get( "email" ) ) ;

                                   return mapping.findForward( "regOk" ) ;

                            }}

                 客戶端 :

                      <a href="/webdir/all.do?method=login">登陸</a>

                      <a href="/webdir/all.do?method=register">註冊</a>

                      Method有不一樣的參數,對應處理的action方法

      (3) LookupDispatchAction :

            (1) 不能覆蓋父類的execute方法,爲每個按鈕單獨寫一個方法

            (2) 覆蓋父類getKeyMethodMap方法,在這個方法中指明按鈕的值與方法名稱的對應關係

            (3) 按鈕的值,不能直接寫死在程序中,要來自於資源文件             

            (4) 在配置文件中對Action進行配置

                <action parameter="指明按鈕的名稱" path="" type="" name="" ></action>  

            (5) 適合一個表單多種請求方式的時候                    

              

            實例 :

                 配置文件 :

                      <action parameter="btn" path="/math" type="com.kettas.struts.MathAction"

                            name="allForm">

                            <forward name="ok" path="/submit.jsp"/>

                      </action>

                     

                 Action :

                      public class MathAction extends LookupDispatchAction{

                            // 覆蓋父類getKeyMethodMap方法,在這個方法中指明按鈕的值與方法名稱的對應關係

                            @Override

                            public Map getKeyMethodMap(){ 

                                  // 按鈕的值應來自於資源文件 在map中保存是資源文件中的key,values是對應的方法

                                  Map m = new HashMap();

                                  m.put( "btn.add" , "addOperate" );

                                  m.put( "btn.subtract" , "subOperate" ); 

                                  return m ;

                            }

                            // 加法運算

                            public ActionForward addOperate( ActionMapping mapping,  ActionForm form ,

                                                  HttpServletRequest request , HttpServletResponse response )

                            {                      

                                   DynaActionForm daf = (DynaActionForm)form ;

                                   Integer a = (Integer)daf.get( "a" ) ;

                                   Integer b = (Integer)daf.get( "b" ) ;

                                   int ret = a.intValue() + b.intValue();

                                   request.setAttribute( "ret" , ret ) ;

                                   return mapping.findForward( "ok" ) ;                             

                            }

                           

                            // 減法運算

                            public ActionForward subOperate( ActionMapping mapping, ActionForm form ,

                                                  HttpServletRequest request , HttpServletResponse response )

                            {

                                   DynaActionForm daf = (DynaActionForm)form ;

                                   Integer a = (Integer)daf.get( "a" ) ;

                                   Integer b = (Integer)daf.get( "b" ) ;

                                   int ret = a.intValue() - b.intValue();

                                   request.setAttribute( "ret" , ret ) ;

                                   return mapping.findForward( "ok" ) ;

                            }

                      }

                     

                 客戶端 :

                      <%@page contentType="text/html"%>

                      <%@page isELIgnored="false"%>

                      <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

                      <%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>

                      <html>

                            <body> 

                                  <!-- 爲變量賦值 得到資源文件的值 -->

                                  <bean:define id="add">

                                       <bean:message key="btn.add"/>

                                  </bean:define>                

                                  <bean:define id="sub">

                                       <bean:message key="btn.subtract"/>

                                  </bean:define>                              

                                 

                                  <form action="/strutsapp/math.do" method="GET">

                                       Number A :<input type="text" name="a"/><br/>

                                       Number B :<input type="text" name="b"/><br/>

                                       <!-- 按鈕的name屬性與action配置中的parameter屬性是對應的 -->

                                       <input type="submit" name="btn" value="${add}"/>

                                       <input type="submit" name="btn" value="${sub}"/>                             

                                  </form>

                                 

                                  <!-- 顯示計算結果 -->

                                  <c:if test="${!empty ret}">

                                       <h2>ret = ${ret}</h2>

                                  </c:if>

                            </body>

                      </html>

      ================================== ====================================================

n m ( m-1 ) * n ---> Begin

    (m-1)*n + n ---> end

   select id

     from

           ( select id , rownum rn from product ) 

     rn> ? and rn < ? 

======================================================

   ResultSet

   1) 改bug.

   2) 增長上一頁 , 下一頁 功能 .

   3) 總頁數 經過 ServletContextListener

      保存到ServletContext對象中 .

 

第五天:

Validation --> 表便驗證 .

 Overide

 validate()

   1) dynaActionForm

   2)

   3) 

validation  :

         1,varliator.jar | jakarta-ora.jar .

             |-> 在這些類中實現了通用的驗證方法.

         2, validator-rules.xml .

             |-> 至關於類的使用說明. 寫給struts看的.

               not null --->class ---> function

         3, validation.xml :

              |-> 至關於程序員編寫的需求說明書 .

            loginForm

               |--> userName

                       |--> not null .

Validation框架的使用方式 :

  1) 程序員負責編寫需求說明書 . 說明

      哪些表單 , 哪些數據,須要作什麼驗證 .

  2) struts 經過閱讀validator-rules.xml,

     調用相應方法,實現驗證邏輯 .

===============================================

使用validation框架的準備工做 :

  1) 保證validation.jar , jakarta-ora.jar

      保存在應用的/WEB-INF/lib

  2) 保證兩個配置文件 validator-rules.xml

     validation.xml 要保存到/WEB-INF 中 .

  3) 將validation以插件的方式嵌入到struts中.

     修改 struts-config.xml ,插件的配置標籤

     能夠從validator-rules.xml的註釋中拷貝.

  4) 確保須要驗證的請求 validate="true"

      <action path="login" type="xxxAction"

                 name="xxxForm" validate="true"

                 input="xxx.jsp"/>

 5) 若是要經過Validation做驗證的話 .

       ActionForm   

            - DynaValidatorActionForm  在validation.xml配置文件中的form標籤中的屬性爲path

          - DynaValidatorForm     在validation.xml配置文件中的form標籤中的屬性爲name

       DynaActionForm

          - org.apache.struts.validator.DynaValidatorForm

          - DynaValidatorActionForm 

  6) 將錯誤提示信息從validator-rules.xml中拷貝到本身的資源文件中 .

編輯需求說明書( validation.xml ) 提出本身的驗證需求

 formset

       |-> form

                      |-> field

       |-> form

tiles .  

<script>

      function fn(){

            xxxxxxxxx ;

            xxxxxxxxxx;

            return false ;

      }

</script> 

<form action="" method="" onsubmit="return xxxx();">

</form> 

1) 將validation寫的javascript代碼嵌入到本身的網頁中. 

   <html:javascript formName=""/>

2) 獲取javascript驗證函數的名字 .

    allForm ---> valdiateAllForm

    abc -------> validateAbc

login.do

regster.do

AllForm

MappingDisaptcherAction

 

<action path="/login" type="" name="all" validate="true" >

<action path="/reg" type="" name="all" validate="true">

 

9  struts中的模板

(1) 在struts-config.xml文件中指定使用模板 : 經過插件件的方式

              <action-mappings>   ... </action-mappings>

              <plug-in className="org.apache.struts.tiles.TilesPlugin" >

                    <!-- 指定模板配置文件的路徑 -->

                  <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />

                  <!-- 使模板識別生效 -->

                  <set-property property="moduleAware" value="true" />

              </plug-in>

             

      (2) tiles-defs.xml文件 :

           <?xml version="1.0" encoding="UTF-8" ?>

           <!DOCTYPE tiles-definitions PUBLIC

                  "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"

                  "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">

           <tiles-definitions>

             <!-- template.jsp是個模板頁面 裏面只有一個頁面佈局 -->            

             <definition name="base" path="/tiles/template.jsp">

               <!-- 向模板頁面的指定位置插入其餘頁面 -->

                 <put name="header" value="/tiles/header.jsp"/>

                 <put name="menu" value="/tiles/menu.jsp"/>

             </definition>

             <!-- 繼承至上面的添加了部份內容的模板 再添加新的內容 -->

             <definition name="register" extends="base">

                      <put name="body" value="/tiles/regBody.jsp"/>

             </definition> 

            

             <!-- 繼承至上面的添加了部份內容的模板 再添加新的內容 -->                              

             <definition name="login" extends="base">

                      <put name="body" value="/tiles/loginBody.jsp"/>

             </definition>

           </tiles-definitions>

          

      (3) template.jsp頁面 :

           <%@page contentType="text/html;charset=utf-8"%>

           <%@taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>

           <html>

                 <body>

                      <table width="100%" height="100%">

                            <tr height="10%" bgcolor="gray">

                                  <td colspan="2" align="center">

                                 <!-- 指定此地能夠插入新的頁面 -->

                                 <tiles:insert attribute="header"/>

                            </td>

                            </tr>

                            <tr height="90%">

                                  <td width="15%" bgcolor="blue">

                                        <!-- 指定此地能夠插入新的頁面 -->

                                        <tiles:insert attribute="menu"/>

                                  </td>

                                  <td width="85%" align="center">

                                        <!-- 指定此地能夠插入新的頁面 -->

                                        <tiles:insert attribute="body"/>

                                  </td>

                            </tr>

                      </table>

                 </body>

           </html>

          

      (4) 使用的時候 頁面格式以下 register.jsp :

           <%@taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>

          

           <!-- definition屬性指定tiles-defs.xml文件中裝配完成的頁面名稱 -->

           <tiles:insert definition="register"/>

          

           <!-- 若在tiles-defs.xml文件中沒有聲明 則要這麼寫 :

           <tiles:insert page="/tiles/template.jsp">

                 <tiles:put name="header" value="/tiles/header.jsp"/>

                 <tiles:put name="menu" value="/tiles/menu.jsp"/>

                 <tiles:put name="body" value="/tiles/regBody.jsp"/>

           </tiles:insert>

           -->

   一個客戶在瀏覽器的地址欄輸入了以下:

URL: http://www.tarena.com/webdev/account/deposit?accno=1212&amt=1000

調用 EG 的方法 F 能夠得到初始參數interestRate的值。

在accountServlet中調用HttpServletRequest的getRequestURI返回H    ,

調用getQueryString返回B ,調用getContextPath返回 A   ,

調用getServletPath返回 C ,調用getPathInfo返回 D 。  

A.    /webdev

B.    accno=1212&amt=1000

C.    /account

D.    /deposit

E.    Servletconfig

F.    getInitParameter

G.    HttpServlet

H.    /webdev/account/deposit

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Struts 2

1,  Struts2的體系和struts1的體系差異很大,由於struts2使用WebWork的設計核心,而不是原來struts1的設計核心。Struts2大量使用攔截器來處理用戶請求,從而容許用戶的業務邏輯控制器與Servlet API分離。

2,  struts2框架的大體處理流程以下:

①瀏覽器發送請求,例如請求 /mypage.action[U13]     /report/myreport.pdf等

②核心控制器FilterDispatcher根據請求決定調用合適的Action

③WebWork的攔截器鏈自動對請求應用通用功能,例如 workflow,validation或文件下載和上傳

④回調Action的execute方法(其實能夠是任意方法),該方法execute方法先得到用戶的請求參數,而後執行某種數據操做,調用業務邏輯組組件來處理用戶請求。

⑤Action的execute方法處理結果信息將被輸出發哦瀏覽器中,能夠是html頁面,pdf還有jsp,Velocity,FreeMarker等技術模板。 

 

3,在struts2 中的web.xml配置  加攔截器(攔截器是整個struts的核心技術)

    <?xml version="1.0" encoding="GBK"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <!-- 定義Struts2的FilterDispathcer的Filter -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

 <!-- FilterDispatcher用來初始化struts2而且處理全部的WEB請求。 -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3,  struts.xml的配置
<struts>
 <!-- include節點是struts2中組件化的方式 能夠將每一個功能模塊獨立到一個xml配置文件中 而後用include節點引用 -->
    <include file="struts-default.xml"></include>
    <!-- package提供了將多個Action組織爲一個模塊的方式
        package的名字必須是惟一的 package能夠擴展 當一個package擴展自
        另外一個package時該package會在自己配置的基礎上加入擴展的package
        的配置 父package必須在子package前配置 
        name:package名稱 extends:繼承的父package名稱
        abstract:設置package的屬性爲抽象的 抽象的package不能定義action 值true:false
        namespace:定義package命名空間 該命名空間影響到url的地址,例如此命名空間爲/test那麼訪問是的地址爲                    

http://localhost:8080/struts2/test/XX.action    -->
    <package name="com.kay.struts2" extends="struts-default" namespace="/test">
        <interceptors>
            <!-- 定義攔截器 name:攔截器名稱  class:攔截器類路徑  -->
            <interceptor name="timer" class="com.kay.timer"></interceptor>
            <interceptor name="logger" class="com.kay.logger"></interceptor>
            <!-- 定義攔截器棧 -->
            <interceptor-stack name="mystack[U14] ">
                <interceptor-ref name="timer"></interceptor-ref>
                <interceptor-ref name="logger"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 定義默認的攔截器 每一個Action都會自動引用 若是Action中引用了其它的攔截器 默認的攔截器將無效 -->
        <default-interceptor-ref name="mystack"></default-interceptor-ref>
        <!-- 全局results配置 -->
        <global-results><result name="input">/error.jsp</result> </global-results>
        <!-- Action配置 一個Action能夠被屢次映射(只要action配置中的name不一樣)
             name:action名稱 class: 對應的類的路徑  method: 調用Action中的方法名 -->
        <action name="hello[U15] " class="com.kay.struts2.Action.LoginAction">
            <!-- 引用攔截器 name:攔截器名稱或攔截器棧名稱  -->
            <interceptor-ref name="timer"></interceptor-ref>
            <!-- 節點配置 name : result名稱 和Action中返回的值相同
                type : result類型 不寫則選用superpackage的type struts-default.xml中的默認爲dispatcher
             -->
         <result name="success" type="dispatcher">/talk.jsp</result>

<result name="error" type="dispatcher">/error.jsp</result>

<result name="input" type="dispatcher">/login.jsp</result>

<!-- 配置Action返回cancel時重定向到Welcome的Action-->

         <result name="cancel" type="redirect-action">Welcome</result>

          <!—異常處理  result表示出現異常時返回的name爲success的結果處理—》

<exception-mapping exception=」java.lang.Exception」 result=」success」/>
         <!-- 參數設置 name:對應Action中的get/set方法 -->
         <param name="url">http://www.sina.com</param>
        </action>
    </package>

          <!—引用國際化文件的base名-->

<constant name=」struts2.custom.i18n.resources」value=」messageResource」
</struts>

 

4,struts2的action編寫

例1 HelloWorld.jsp

<% @ page contentType = " text/html; charset=UTF-8 " %>
<% @ taglib prefix = " s " uri = " /struts-tags " %>
[U16] < html >
< head >
    < title > Hello World! </ title >
</ head >
< body >
    < h2 >< s:property value ="message[U17] " /></ h2 >
</ body >
</ html >

例1 classes/tutorial/HelloWorld.java

 import com.opensymphony.xwork2.ActionSupport;

 public class HelloWorld extends ActionSupport  {
     private String message[U18] ;
     public String getMessage()  {
         return message;
    }
   public void tring setMessage(String message)  {
         this.message=message;
    }
    @Override
     public String execute[U19] ()  {
        message = " Hello World, Now is " + DateFormat.getInstance().format( new Date());
         return success;
    }
}

例1 classes/struts.xml中HelloWorld Action的配置

< package name ="ActionDemo" extends ="struts-default" >
    < action name ="HelloWorld" class ="tutorial.HelloWorld" >
        < result > /HelloWorld.jsp </ result >
    </ action >
</ package >

 

4,  攔截器的編寫

  編寫權限控制器

public class AuthorityInterceptor extends AbstractIntercepto[U20] r {   

    private static final long serialVersionUID = 1358600090729208361L;   

    //攔截Action處理的攔截方法   

    public String intercept(ActionInvocation invocation) throws Exception {   

        ActionContext ctx=invocation.getInvocationContext();   // 取得請求相關的ActionContext實例

        Map session=ctx.getSession();   

        String user=(String)session.get("user"); //取出名爲user的session屬性     

        //若是沒有登錄,或者登錄全部的用戶名不是aumy,都返回從新登錄   

        if(user!=null && user.equals("aumy")){   

            return invocation.invoke();[U21]    

        }   

        //沒有登錄,將服務器提示設置成一個HttpServletRequest屬性   

        ctx.put("tip","您尚未登陸,請登錄系統");   

        return Action.LOGIN;           

    }   

}

 

Struts2.xml的配置文件

<struts>    

    <include file="struts-default.xml"/>     

       

    <!--授權限控制的Action請求配置-->   

    <package name="authority" extends="struts-default">   

        <interceptors>   

            <!--定義一個名爲authority的攔截器-->   

            <interceptor  class="com.aumy.struts.example.intercepter.AuthorityInterceptor"  name="authority"/>

            <!--定義一個包含權限檢查的攔截器棧-->   

            <interceptor-stack name="mydefault">  

                <interceptor-ref name="defaultStack"/>   <!--配置內建默認攔截器--> 

                <interceptor-ref name="authority"/>  <!--配置自定義的攔截器-->   

            </interceptor-stack>   

        </interceptors>   

           

        <default-interceptor-ref name="mydefault" />[U22]    

        <!--定義全局Result-->   

        <global-results>   

            <result name="login">/login.jsp</result>   

        </global-results>   

           

        <action name="show" class="com.aumy.struts.example.LoginAction"  

            method="show">   

            <result name="success">/show.jsp</result>   

        </action>   

        <action name="add" class="com.aumy.struts.example.LoginAction"  method="add">

            <result name="success">/add.jsp</result>   

        </action>   

    </package>   

</struts>  

 

 

 

還要一種方法攔截器,能夠對某個action的方法進行攔截 編碼相似action攔截器

  public class MyInterceptor3 extends MethodFilterInterceptor {   

    @Override  

    protected String doIntercept(ActionInvocation invocation) throws Exception {   

        System.out.println("use MethodFilterInterceptor");   

        String result = invocation.invoke();   

        return result;   

    }  

}

只是在配置的時候和其餘interceptor有些區別:

<interceptor name="myInterceptor3" class="com.langhua.interceptor.MyInterceptor3">  

                <param name="excludeMethods">execute,login</param>  <!-- execute,login兩個方法不須要攔截

               <!—addmessage 方法須要攔截 能夠指名多個方法,只須要用逗號隔開

 <param name="includeMethods">addmessage</param>     

</interceptor>  

 

 

6,攔截結果的監聽器,用來精肯定義在execute方法執行以後,在處理物力資源轉向以前的動做,這個監聽器是經過手動註冊到攔截器內部的

 

public class MyListener implements PreResultListener[U23]  {   

    public void beforeResult(ActionInvocation invocation, String resultCode[U24] ) {   

        System.out.println(「放回的邏輯視圖是:」+resultCode);   

    }   

}

而後再在攔截器裏面調用  invocation.addPreResultListener(new MyListener());  
監聽器是在這個攔截器完成別的攔截器以後調用的

 

 

5,struts2的標籤庫  相比struts1,struts2提供了大量的標籤,且更增強大  ,且主要有,1 UI 用戶界面標籤(html頁面顯示)   2 非UI 主要是數據訪問,邏輯控制的標籤   3 Ajax支持的標籤

 

 

6,Struts2 的(客戶端和服務端)校驗更爲方便更容易國際化處理

7,國際化處理:

8,支持文件的上傳和下載

Struts1和Struts2的區別和對比:

Action 類:
• Struts1要求Action類繼承一個抽象基類。Struts1的一個廣泛問題是使用抽象類編程而不是接口。
• Struts 2 Action類能夠實現一個Action接口,也可實現其餘接口,使可選和定製的服務成爲可能。Struts2提供一個ActionSupport基類去實現經常使用的接口。Action接口不是必須的,任何有execute標識的POJO對象均可以用做Struts2的Action對象。

線程模式:
• Struts1 Action是單例模式而且必須是線程安全的,由於僅有Action的一個實例來處理全部的請求。單例策略限制了Struts1 Action能做的事,而且要在開發時特別當心。Action資源必須是線程安全的或同步的。
• Struts2 Action對象爲每個請求產生一個實例,所以沒有線程安全問題。(實際上,servlet容器給每一個請求產生許多可丟棄的對象,而且不會致使性能和垃圾回收問題)

Servlet 依賴:
• Struts1 Action 依賴於Servlet API ,由於當一個Action被調用時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。
• Struts 2 Action不依賴於容器,容許Action脫離容器單獨被測試。若是須要,Struts2 Action仍然能夠訪問初始的request和response。可是,其餘的元素減小或者消除了直接訪問HttpServetRequest 和 HttpServletResponse的必要性。

可測性:
• 測試Struts1 Action的一個主要問題是execute方法暴露了servlet API(這使得測試要依賴於容器)。一個第三方擴展--Struts TestCase--提供了一套Struts1的模擬對象(來進行測試)。
• Struts 2 Action能夠經過初始化、設置屬性、調用方法來測試,「依賴注入」支持也使測試更容易。

捕獲輸入:
• Struts1 使用ActionForm對象捕獲輸入。全部的ActionForm必須繼承一個基類。由於其餘JavaBean不能用做ActionForm,開發者經 常建立多餘的類捕獲輸入。動態Bean(DynaBeans)能夠做爲建立傳統ActionForm的選擇,可是,開發者多是在從新描述(建立)已經存 在的JavaBean(仍然會致使有冗餘的javabean)。
• Struts 2直接使用Action屬性做爲輸入屬性,消除了對第二個輸入對象的需求。輸入屬性多是有本身(子)屬性的rich對象類型。Action屬性可以經過 web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業務對象,可以用做輸入/輸出對象。這種 ModelDriven 特性簡化了taglib對POJO輸入對象的引用。

表達式語言:
• Struts1 整合了JSTL,所以使用JSTL EL。這種EL有基本對象圖遍歷,可是對集合和索引屬性的支持很弱。
• Struts2能夠使用JSTL,可是也支持一個更強大和靈活的表達式語言--"Object Graph Notation Language" (OGNL).

綁定值到頁面(view):
• Struts 1使用標準JSP機制把對象綁定到頁面中來訪問。
• Struts 2 使用 "ValueStack"技術,使taglib可以訪問值而不須要把你的頁面(view)和對象綁定起來。ValueStack策略容許經過一系列名稱相同但類型不一樣的屬性重用頁面(view)。

類型轉換:
• Struts 1 ActionForm 屬性一般都是String類型。Struts1使用Commons-Beanutils進行類型轉換。每一個類一個轉換器,對每個實例來講是不可配置的。
• Struts2 使用OGNL進行類型轉換。提供基本和經常使用對象的轉換器。

校驗:
• Struts 1支持在ActionForm的validate方法中手動校驗,或者經過Commons Validator的擴展來校驗。同一個類能夠有不一樣的校驗內容,但不能校驗子對象。
• Struts2支持經過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用爲屬性類類型定義的校驗和內容校驗,來支持chain校驗子屬性

Action執行的控制:
• Struts1支持每個模塊有單獨的Request Processors(生命週期),可是模塊中的全部Action必須共享相同的生命週期。
• Struts2支持經過攔截器堆棧(Interceptor Stacks)爲每個Action建立不一樣的生命週期。堆棧可以根據須要和不一樣的Action一塊兒使用

 

 

 

 

 

Ajax部分

1定義:多種應用異步通訊,可以數據的局部刷新,使用戶有不間斷的體驗

ajax 的四項技術:

javascript, css, dom, XMLHttpRequest

 

2四者之間的關係:

1. javascript 建立XMLHttpRequest 對象並用它與web server 通訊得到數據;

2. javascript 使用dom 的api 將數據更新到頁面;

3. javascript 將css 應用到HTML 的元素上

Ajax的傳輸步驟------------------------------à

 

 

 

 

3 ajax 的編程步驟

1. 建立XMLHttpRequest 對象xhr;

2. 使用xhr 的open 函數打開資源;open("GET or POST" , "傳向的頁面"+若是是GET要加參數(不用加/));

3. 使用xhr 的onreadystatechange 屬性註冊處理應答的回調函數的句柄;(爲何只傳句柄?若是傳display()的話至關於傳入的是函數值,

而傳入display()的話是將整個函數傳給它,當有變化時交個這個函數來處理傳入display()還會出錯?)

4. (在使用POST 方法使用)使用xhr 的setRequestHeader 設置請求頭。一般設置content-type

請求頭,可能的值是:application/x-www-form-urlencoded 和text/xml;

5. 使用xhr 的send 方法發送請求;

6. 編寫回調函數處理應答:在此函數裏經過xhr 的readyState 屬性判斷通訊是否結束(等於4 結束);而後再經過xhr 的status 屬性判斷web server 是否正確處理應答(等於200 正確),若是正確處理應答,應答的文本存放在xhr 的responseText 屬性中,應答是xml 再將生成的xml 文檔放在xhr 的responseXML 中 傳XML文檔只能用POST方法傳

 

res.getCharactorEncoding();可得到res的字符編碼

res.setCharactorEncoding("UTF-8");

 

用DOM api 解析XML 文檔的步驟:

1. 建立DocumentBuilderFactory:

DocumentBu ilderFactory dbf = DocumentBuilderFactory.newInstance();

2. (可選)設置dbf 的屬性:

設置合法性檢測: dbf.setValidating(true);

設置處理名字空間: dbf.setNamespaceAware(true);

3.建立DocumentBuilder:

DocumentBu ilder db = dbf.newDocumentBuilder();

4a.解析XML 文檔:

Document doc = db.parse(xmlResource);

4b.生成XML 文檔:

Document doc = db.newDocument();

 

4 XMLHTTPRequest的屬性和方法介紹

 方法屬性:

open(string method, string url, boolean asynch, string username, string password):post仍是get,url地址,同步仍是異步 後面三個參數是可選的

void send(content):

string getAllResponseHeaders()

void setRequestHeader(string header, string value):這個方法爲HTTP請求中一個給定的首部設置值。它有兩個參數,第一個串表示要設置的首部,第二個串表示要在首部中放置的值。須要說明,這個方法必須在調用open()以後才能調用。

string getResponseHeader(string header):

onreadystatechange :每一個狀態改變時都會觸發這個事件處理器,一般會調用一個JavaScript函數、回調函數

readyState:請求的狀態。有5個可取值:0 = 未初始化,1 = 正在加載,2 = 已加載,3 = 交互中,4 = 完成

responseText:服務器的響應,表示爲一個串

responseXML:服務器的響應,表示爲XML。這個對象能夠解析爲一個DOM對象

statusText:HTTP狀態碼的相應文本(OK或Not Found(未找到)等等)

 

5 kettasAjax 封裝XMLHttpRequest 四個方法說明:

1.kettasAjax.doGetText(url, textHandler, async):

用GET 方法發出請求到url, 返回的文本responseText 做爲回調函數textHandler 的參數。

textHandler 的簽名相似function(txt).

2.kettasAjax.doGetXml(url, xmlHandler, async):

用GET 方法發出請求到url, 返回的XML Document 也就是responseXML 做爲回調函數

xmlHandler 的參數。xmlHandler 的簽名相似function(doc).

3.kettasAjax.doPostText(url, textHandler, body, async):

用POST 方法將請求體body 發送到url, 返回的文本responseText 做爲回調函數textHandler

的參數。textHandler 的簽名相似function(txt).

4.kettasAjax.doPostXml(url, xmlHandler, body, async):

用POST 方法將請求體body 發送到url, 返回的XML Document 也就是responseXML 做爲

回調函數xmlHandler 的參數。xmlHandler 的簽名相似function(doc).

 

 

6 AJAX全稱爲"Asynchronous JavaScript and XML"(異步JavaScript和XML),是指一種建立交互式網頁應用的

網頁開發技術。它允許網頁的部分刷新,比起傳統的整個頁面刷新,傳輸的數據量大大減小,這樣就顯著提升了

用戶瀏覽web頁面的速度。

1)  獲取ajax核心對象XMLHttpRequest的標準JavaScript函數 :

      function createXhr(){

           // 判斷是IE瀏覽器仍是其餘瀏覽器,而後返回對象

           if(window.ActiveXObject){

                 return new ActiveXObject("Microsoft.XMLHTTP");

           }else if(window.XMLHttpRequest){

                 return new XMLHttpRequest();

           }else{ throw new Error("Does not ajax programming");}

      }

                

          

      注 : 下面的筆記中,都用 createXhr()這個函數獲取XMLHttpRequest對象

     

2)  實例 : 在網頁中驗證電子郵箱輸入的格式

      (1) 網頁文件

           <title>Validate Email Format</title>

           <!-- createXhr()以及其餘工具函數都在utils.js中 -->

           <script type="text/javascript" src="js/utils.js"></script>

          

           <script type="text/javascript">             

                 //如下是標準的步驟,要牢記

                 var xhr = null;

                 function validateEmail(){

                      xhr = createXhr();// 獲取XMLHttpRequest對象

// 要提交到服務器的請求,escape函數用於除去字符串兩端空格,$函數根據id得到對象(此方法在util.js中)  vm是servlet的訪問地址

                      var url = "vm?mail=" + escape($("mail").value);

                      /* 指定發送的方式、接受請求的頁面(或servlet)、是否採用異步回調

                       * 參數也能夠是("GET", url, true)

                       * true是默認的,故可省略不寫,表示採用異步回調

                       */

                      xhr.open("GET", url);

                      // 指定異步回調函數

                      xhr.onreadystatechange = displayStatus;

                     

                      // 若採用POST方式提交請求,這裏就必須發送請求體,這裏是GET方式,故爲NULL

                       //請求體的設置xhr.setRequestHeader(「Content-Type」,」application/x-www-form-urlencoded」);

                      xhr.send(null);

                 }

                 //異步回調函數的實現

                 function displayStatus(){

// readyState是服務端狀態, 0表明無狀態,1表明創建鏈接,2準備發送數據,3正在發送數據 ,等於4代表對請求響應完畢,該返回客戶端的數據都返回了

                      if(xhr.readyState == 4){

                            // status是客戶端狀態,等於200代表數據已經存在於緩存,能夠直接拿來使用了

400 url出錯,500內部出錯

                            if(xhr.status == 200){

                                  var status = $("mailFormatStatus");

                                  // 得到服務器返回的文本數據

                                  var mailStatus = xhr.responseText;

                                  if(mailStatus == "true"){

                                       status.innerHTML = "valid email format";

                                  }else{ status.innerHTML = "invalid email format"; }

                            }else{// 得到客戶端狀態值以及對應的描述性文本

                                  errorHandler(xhr.status, xhr.statusText);}

                      }else{ status.innerHTML = "please wait..."; }}

           </script>

           </head>

           <body>

                 <h2>Please enter an email address to validate</h2>

                 <input type="text" id="mail" onblur="validateEmail()"/><br/>

                 <div id="mailFormatStatus"></div>

           </body>

           </html>

          

      (2) Servlet文件ValidateEmailFormatServlet.java片斷

                 protected void doGet(HttpServletRequest request, HttpServletResponse response)

                      throws ServletException, IOException {

                      // 注意這裏不是"text/html" 由於咱們只須要返回純文本字符串便可 故用"text/plain"

                      response.setContentType("text/plain;charset=gbk");

                      String mail = request.getParameter("mail");

                      String status = "false";

                      if(mail != null){

                            Pattern p = Pattern.compile("\\S+@\\S+");

                            Matcher m = p.matcher(mail);

                            if(m.matches()) status = "true";

                      }

                      PrintWriter out = response.getWriter();

                      out.print(status);

                      out.flush();

                      //這裏關閉與否 應該無關痛癢

                      out.close();

                 }

      (3) web.xml片斷

                 <servlet>

                      <description>

                      </description>

                      <display-name>

                      ValidateEmailFormatServlet</display-name>

                      <servlet-name>ValidateEmailFormatServlet</servlet-name>

                      <servlet-class>

                   com.kettas.ajax.xhr.day1.ValidateEmailFormatServlet</servlet-class>

              </servlet>

                 <servlet-mapping>

                      <servlet-name>ValidateEmailFormatServlet</servlet-name>

                      <url-pattern>/vm</url-pattern>

                 </servlet-mapping>

                

3)  向服務器請求得到xml文件(對象)

      本例中,獲得從服務器返回的xml對象,而後將數據填充到表格

      <title>Online super store</title>

      <script type="text/javascript" src="js/utils.js"></script>

      <script type="text/javascript">

           var xhr = null;

           function initStore(){

                 xhr = createXhr();

                 xhr.open("GET", "xmlListProduct.jsp");

                 xhr.onreadystatechange = display;

                 xhr.send(null);

           }

          

           function display(){

                 if(xhr.readyState == 4){

                      if(xhr.status == 200){

                            fillStoreTable(xhr.responseXML);

                      }else{

                            errorHandler(xhr.status, xhr.statusText);

                      }}}

           function fillStoreTable(productsRoot){

                 // 將xml數據,填充表格,具體過程略

                 ...

           }

      </script>

      </head>

      <body onload="initStore();">

      <table id="storeTable">

           <tbody id="storeBody">

           </tbody>

      </table>

      </html>

     

      xmlListProduct.jsp文件內容以下 :

           <!-- 注意,客戶端須要的是xml文件,故這裏是"text/xml" -->

           <%@page language="java" contentType="text/xml; charset=ISO-8859-1"

               pageEncoding="ISO-8859-1"%>

           <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

           <jsp:useBean id="store" class="com.kettas.ajax.xhr.day1.SuperStore" scope="application"/>

           <products>

               <c:forEach var="product" items="${store.products}">

                 <product>

                      <id>${product.id }</id>

                      <name>${product.name }</name>

                      <price>${product.price}</price>

                 </product>

               </c:forEach>

           </products>

                     

7 封裝ajax的調用步驟 :

   得到XMLHttpRequest對象,而後向服務器發送請求,最後對服務器返回的數據進行處理。這個過程

   千篇一概,每次按照相同的步驟書寫,故將它們封裝起來是當務之急。這樣的話,調用起來會方便

   得多。

   封裝的具體實現以下所示(十分經典的javascript代碼,掌握並牢記) :

           function Request(l){

                 var xhr = createXhr();// 私有屬性 XMLHttpRequest對象

                 var listener = l; // 私有屬性 此對象負責對服務端響應做反應

                 // 保險起見 若初始化時沒有賦予對象 則賦予一個新建立的對象

                 if(!listener) listener = new ResponseListener();

                 // 公有屬性 請求體內容的類型 默認的表示發送的是表單數據

                 // 若發送的是xml類型數據 則this.contentType = "text/xml";

                 // 實際上 這個是無關痛癢的 都用默認的類型便可

                 this.contentType = "application/x-www-form-urlencoded";

                 // 公有方法 以GET方式發送請求

                 this.doGet = function(url,async){

                      sendRequest("GET", url, null, async);

                 }

                 // 公有方法 以POST方式發送請求

                 this.doPost = function(url, requestBody, async){

                      sendRequest("POST", url, requestBody, async);

                 }

                 // 私有方法 向服務器發送請求

                 function sendRequest(method, url, requestBody, async){

                      if(async == undefined) async = true; // 若是沒有說明是否採用異步回調 則採用異步回調

                             // 若是async有值 而且async != ( false || 0 || null ) 則採用異步回調

                           else if(async) async = true;

                            else async = false; // 其餘狀況( async = false || 0 || null ) 則不採用異步回調

                            // 指定發送的方式、接受請求的頁面(或servlet)、是否採用異步回調

                            xhr.open(method, url, async);

                            if(async) xhr.onreadystatechange = callback; // 指定異步回調函數

                           // 設置請求體的內容類contentType =application/x-www-form-urlencoded」

xhr.setRequestHeader("Content-Type", contentType);

                            xhr.send(requestBody); // 發送請求

                            // 若沒有采用異步回調 則執行此函數

                            if(!async) listener.complete(

                                  xhr.status, xhr.statusText, xhr.responseText, xhr.responseXML

                            );

                 }

                 // 私有函數 異步回調函數的實現

                 function callback(){

                      switch(xhr.readyState){

                            case 0: listener.uninitialized(); break;

                            case 1: listener.loading(); break;

                            case 2: listener.loaded(); break;

                            case 3: listener.interactive(); break;

                            case 4: listener.complete(

                                  xhr.status, xhr.statusText, xhr.responseText, xhr.responseXML

                            ); break;

                      }}

                 // 私有函數

                 function createXhr(){

                      if(window.ActiveXObject){

                            return new ActiveXObject("Microsoft.XMLHTTP");

                      }else if(window.XMLHttpRequest){

                            return new XMLHttpRequest();

                      }else{

                            throw new Error("Does not ajax programming");

                      }}}

           // 此對象處理服務端響應

           function ResponseListener(){

                 this.uninitialized = function(){}

                 this.loading = function(){}

                 this.loaded = function(){}

                 this.interactive = function(){}

                 // 最後一個響應狀態 響應完畢

                 this.complete = function(status, statusText, responseText, responseXML){}

           /* 繼承上面的對象

            * 對於其它四個狀態 通常是不須要處理響應的 故這裏不予理會

            * 只是覆蓋響應完畢後的處理方法

            */

           function ResponseAdapter(){

                 this.handleText = function(text){}

                 this.handleXml = function(xml){}

                 this.handleError = function(status, statusText){

                      alert("Error: " + status + " " + statusText);

                 }

                 // 覆蓋父類的方法

                 this.complete = function(status, statusText, responseText, responseXML){

                      if(status == 200){

                            this.handleText(responseText);

                            this.handleXml(responseXML);

                      }else{

                            this.handleError(status, statusText);

                      }

                 }

           }

           // 注意 javascript的繼承機制

           ResponseAdapter.prototype = new ResponseListener();

           ResponseAdapter.prototype.constructor = ResponseAdapter;

           // 對以上部分實現功能的組織調用類

           if(!kettasAjax) var kettasAjax = {};

           // 採用GET方式發送請求 對返回的文本數據進行處理

           if(!kettasAjax.getText){

                 kettasAjax.getText = function(url, handleText, async){

                      var l = new ResponseAdapter();

                      l.handleText = handleText;

                      var req = new Request(l);

                      req.doGet(url, async);

                 }}

           // 採用GET方式發送請求 對返回的XML數據進行處理

           if(!kettasAjax.getXml){

                 kettasAjax.getXml = function(url, handleXml, async){

                      var l = new ResponseAdapter();

                      l.handleXml = handleXml;

                      var req = new Request(l);

                      req.doGet(url, async);

                 }

           }

           // 採用POST方式發送請求 對返回的文本數據進行處理

           if(!kettasAjax.postText){

                 kettasAjax.postText = function(url, requestBody,handleText, async){

                      var l = new ResponseAdapter();

                      l.handleText = handleText;

                      var req = new Request(l);

                      req.doPost(url,requestBody, async);

                 }

           }

           // 採用POST方式發送請求 對返回的XML數據進行處理

           if(!kettasAjax.postXml){

                 kettasAjax.postXml = function(url, requestBody, handleXml, async){

                      var l = new ResponseAdapter();

                      l.handleText = handleXml;

                      var req = new Request(l);

                      req.doPost(url, requestBody, async);

                 }

           }  

           注 : 之後就使用這個kettasAjax對象,會方便異常

          

採用kettasAjax對象,採用不一樣的方式向服務器發送不一樣類型的數據

      (1) html文件以下 :

           <title>Send Request Parameters</title>

           <script type="text/javascript" src="js/utils.js"></script>

           <script type="text/javascript" src="js/kettasAjax.js"></script>

           <script type="text/javascript">

                 function handleForm(httpMethod){

                      if(httpMethod == "GET"){

                            // 採用GET方式向服務器發送表單數據

                            kettasAjax.getText("echo.jsp?" + getQueryString(), display);

                      }else{

                            // 採用POST方式向服務器發送表單數據

                            kettasAjax.postText("echo.jsp", getQueryString(), display);

                      }}

                 // 顯示服務器返回的數據

                 function display(txt){

                       $("response").innerHTML = txt;

                 }

                 // 得到表單數據的字符串組織形式

                 function getQueryString(){

                      var name = escape(getEavById("name"));

                      var age = escape(getEavById("age"));

                      var password = escape(getEavById("password"));

                      var queryStr = "name=" + name +"&age=" + age + "&password=" + password;

                      return queryStr;

                 }

                 // 採用POST方式向服務器發送xml數據

                 // 因爲發送的是xml形式字符串 故服務端不能以getParameter的方式讀取 要以readLine方式讀取

                 function handleXmlForm(){

                      kettasAjax.postText("handleXml", getXmlFromForm(), display);

                 }

                 // 得到表單數據的xml字符串表現形式

                 function getXmlFromForm(){

                      var name = getEavById("name");

                      var age = getEavById("age");

                      var password = getEavById("password");

                      var xmlStr = "<params>"

                      + "<name>" + name + "</name>"

                      + "<age>" + age + "</age>"

                      + "<password>" + password + "</password>"

                      + "</params>"

                      return xmlStr;

                 }

           </script>

           </head>

           <body>

                 <form action="#">

                  Name: <input type="text" id="name"/><br/>

                  Age: <input type="text" id="age"/><br/>

                  Password: <input type="password" id="password"/><br/>

                 </form>

                 <button onclick="handleForm('GET')">Get</button>

                 <button onclick="handleForm('POST')">Post</button>

                 <button onclick="handleXmlForm()">Send Parameters as XML</button><br/>

                 <div id="response"></div>

           </body>

           </html>

      (2) echo.jsp內容以下 :

           Http method: ${pageContext.request.method}, and parameters

           are name: ${param.name}, age: ${param.age}, password: ${param.password}

      (3) Servlet文件HandleXmlServlet片斷以下 :

                 protected void doPost(HttpServletRequest request,

                            HttpServletResponse response) throws ServletException, IOException {

                      response.setContentType("text/plain");

                      StringBuilder sb = new StringBuilder();

                      // 因爲客戶端發送的是xml形式的字符串 故要得到BufferedReader對象用於讀取

                      BufferedReader reader = request.getReader();

                      PrintWriter out = response.getWriter();

                      String line = null;

                      // 可能客戶端是採用多行發送的 故不能只讀取一行了事

                      while ((line = reader.readLine()) != null)

                            sb.append(line);

                      // 解析xml數據

                      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

                      try {

                            DocumentBuilder db = dbf.newDocumentBuilder();

                            // 因爲不存在.xml文件 故只能之內存字節流的方式初始化

                            Document doc = db.parse(

                                  new ByteArrayInputStream(sb.toString().getBytes())

                            );

                            String name = getElementData(doc, "name");

                            String age = getElementData(doc, "age");

                            String password = getElementData(doc, "password");

                            out.print("Parameters are name: " + name

                             + " age: " + age

                             + " password: " + password

                            );

                      } catch (Exception e) {

                            e.printStackTrace();

                            out.print("error");

                      }

                      out.close();

                 }

 

 

頁面部分更新,只更新表格部分

      (1) html文件的實現 :

           <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

           <html>

           <head>

           <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

           <title>Online super store</title>

           <script type="text/javascript" src="js/utils.js"></script>

           <script type="text/javascript" src="js/kettasAjax.js"></script>

           <script type="text/javascript">

                 function initStore(){

                      kettasAjax.getText("listProduct.jsp", display);

                 }               

                 function display(txt){

                      $("store").innerHTML = txt;

                 }

           </script>

           </head>

           <body onload="initStore();">

                 <div id="store"></div>     

           </body>

           </html>

      (2) listProduct.jsp內容以下 :

           <%@ page language="java" contentType="text/html; charset=GBK"

                 pageEncoding="GBK"%>

           <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

           <jsp:useBean id="store" class="com.kettas.ajax.xhr.day1.SuperStore" scope="application"/>

           <table border="1">

             <tbody>

               <c:forEach var="product" items="${store.products}">

                 <tr>

                      <td>${product.id }</td>

                      <td>${product.name }</td>

                      <td>${product.price}</td>

                 </tr>

               </c:forEach>

             </tbody>

           </table>

10  於Ajax中的Json

Json 是一種線上協議,輕量級的xml 一種文體格式

      Json的功能,簡單的說,就是實現字符串和對象之間的轉換。要使用其功能,在客戶端,要引入

      json.js文件,在服務器端,則要引入json.jar這個包。

      Json對象和數組  {}大括號表明一個對象,,【】表明數組

      (1) Json在客戶端的應用實例 :

           <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

           <html>

           <head>

           <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

           <title>JSON test</title>

           <script type="text/javascript" src="js/json.js"></script>

           <script type="text/javascript" src="js/utils.js"></script>

           <script type="text/javascript">

                 // 建立一個對象,注意格式  {}

                 var product = {

                      id: 1,  name: "core java",  price: 100       };

                 // 建立一個對象字符串,注意格式

                 var s = '{"id": 1, "name": "George", "age":30}';

                 // 實現對象和字符串之間的互換 只須stringify和parse這兩個方法便可

                 function display(){

                      // 將對象轉換爲字符串,發送給服務器處理

                      byId("json").innerHTML = JSON.stringify(product);

                      // 將字符串轉換爲對象,把服務端的字符串組裝成對象

                      var student = JSON.parse(s);

                      alert(student.id + "\t" + student.name + "\t" + student.age); }

           </script>

           </head>

           <body onload="display()"><h2>

                 <div id="json"></div>

                 </h2>

           </body>

           </html>

      (2) Json在客戶端和服務器端同時應用 :

           1 客戶端html文件 :

                 <html><head>

                 <title>Query Price</title>

                 <script type="text/javascript" src="js/json.js"></script>

                 <script type="text/javascript" src="js/kettasAjax.js"></script>

                 <script type="text/javascript" src="js/utils.js"></script>

                 <script type="text/javascript">

                      function query(){

                            // obj4form是一個工具函數 根據表單id 將用戶輸入表單的數據封裝爲一個對象

                            var car = obj4form("carInfo");

                            // 直接向服務器發送對象字符串

                 //"queryPrice"是訪問servlet地址,JSON.stringify(car)發送對象字符串,display爲服務器返回內容

                            kettasAjax.postText("queryPrice", JSON.stringify(car), display);

                      }

                      function display(txt){

                            // 將從服務器返回的對象字符串轉換爲對象

                            var ret = JSON.parse(txt);

                            var model = ret.model;

                            var price = ret.price;

                            $("result").innerHTML = model + " " + price

                      }

                 </script>

                 </head>

                 <body>

                      <h2>Please enter car information</h2>

                      <!-- 利用輸入的汽車id和生產廠商信息 得以查詢汽車的價格 -->

                      <form action=#" id="carInfo">

                            Id: <input type="text" id="id"/><br/>

                            Make: <input type="text" id="make"/><br/>

                      </form>

                      <button onclick="query()">Query Price</button>

                      <div id="result"></div>

                 </body>

                 </html>

           2 Servlet文件QueryPriceServlet的片斷 :

                      protected void doPost(HttpServletRequest request, HttpServletResponse response)

                            throws ServletException, IOException {

                            response.setContentType("text/plain");

                            BufferedReader reader = request.getReader();//獲得客戶端的字符串

                            PrintWriter out = response.getWriter();

                            StringBuilder sb = new StringBuilder();

                            String str = null;

                            while((str = reader.readLine()) != null)

                                  sb.append(str);

                            try { // 將客戶端發送的對象字符串轉化爲JSONObject對象

                                  JSONObject jsonObj = new JSONObject(sb.toString());

                                  // 得到對象中的數據 注意格式

                                  int id = jsonObj.getInt("id");

                            String make = jsonObj.getString("make");

                                  // 不用make.equals("Audi") 避免了make == null的狀況下拋異常 小技巧

                                  if(id == 1 && "Audi".equals(make)){

                                       // 給客戶端迴應一個對象字符串 注意格式// 首先建立一個新的JSONObject對象

                                       jsonObj = new JSONObject();

                                       // 向這個對象中填充數據

                                       jsonObj.put("model", "A8");

                                 jsonObj.put("price", 860000);

                                       // 將對象轉化爲對象字符串 回發給客戶端

                                       // 這個對象字符串的格式爲 : '{"model" : "A8" , "price" : 860000}'

                                       out.print(jsonObj.toString());

                                  }

                            } catch (Exception e) {

                                  e.printStackTrace();  throw new ServletException(e);

                            }finally{  out.close();

                            }}  

      (3) 在服務器端將java中的實體bean、collections、array以及map對象轉換爲對象字符串 :

           要實現這個功能,能夠藉助內部工具類JsonUtil.java,其中的幾個方法是頗有用的,如 :

                 public static JSONObject bean2Json(Object bean),

                 public static JSONObject map2Json(Map map),

                 public static JSONArray array2Jarr(Object value),

                 public static JSONArray collection2Json(Object value)

           測試類片斷以下 :                 

                 public class TestJsonUtil {           

                      public static void main(String[] args) {

                            SuperStore ss = new SuperStore();

                            // ss.getProducts()方法返回一個商品對象的集合

                            JSONArray jarr = JsonUtil.collection2Json(ss.getProducts());

                            System.out.println(jarr.toString());

                      }               

                 }    

 

 

11 關於Ajax中的dwr框架 :

      有了dwr框架,操做html頁面感受就是在直接操做java代碼。實際上,仍是經過服務器端執行的。

      要使用此框架提供的功能,必須引入dwr.jar這個包。

      思想:在web上的servlet動態生成javascript代碼

      (1) 最簡單的實例

           java類文件 :

                 package com.kettas.ajax.dwr.day4;

                 public class Hello {                  

                      public String sayHello(String user){

                            try{

                                  Thread.sleep(2000);

                            }catch(Exception e){

                            }

                            return "Hello, " + user;

                      }

                 }

           配置文件dwr.xml(與web.xml處於同一個位置) :

                 <dwr>

                      <allow>

                            <!-- javascript="hello"指定客戶端對象名稱爲hello

                                   creator="new"指定java對象的建立方式

                                   scope="application"指定java對象的放置位置 -->

                            <create javascript="hello" creator="new" scope="application">

                                  <param name="class" value="com.kettas.ajax.dwr.day4.Hello"></param>

                            </create>

                      </allow>

                 </dwr>

           客戶端html文件的內容 :

                 <!-- 服務器動態生成的js文件 內有hello對象 -->

                 <script type="text/javascript" src="dwr/interface/hello.js"></script>

                 <!-- dwr引擎包 -->

                 <script type="text/javascript" src="dwr/engine.js"></script>

                 <!-- 引入dwr提供的工具包 -->

                 <script type="text/javascript" src="dwr/util.js"></script>

                 <script type="text/javascript">

                      // element.style.visibility = "hidden";

                      // element.style.visibility = "";

                      // CSS內容 對象的隱藏屬性  

                      /*

                      // 這樣寫的話 僅此函數就能夠了

                      function sayHello(){

                            // 直接給參數賦內部函數

                            hello.sayHello($("user").value, function(txt){

                                  dwr.util.setValue("helloStr", txt);

                            });

                      }*/

                      /*

                      // 也能夠這麼寫 最簡便

                      function sayHello(){

                       // hello是在dwr.xml配置的,hello.sayHello至關調用服務端的方法,($("user").value 參數,display回調方法,返回值就是display(text)中的text值

                      hello.sayHello($("user").value, display);

                      }

                      */

                      // 這麼寫 是最完整的

                      function sayHello(){                        

                            //dwr.util.useLoadingMessage("Wait a minute...");

                            // 給參數賦一個對象

                            var cb = {

                                  callback: display, // 指定回調函數

                                  timeout: 500, // 指定等待時間 若是超出這個時間 則出錯

                                  errorHandler: display, // 指定處理錯誤的回調函數

                                  // ???

                                  name: "George"

                            };

                            // 在客戶端調用方法 始終比服務端對應方法要多一個參數

                            // 這個參數最終的實現是一個回調函數

                       // 這個回調函數的參數就是服務端方法返回的對象(在客戶端是javascript對象)

                            hello.sayHello($("user").value, cb);

                      }

                      function display(txt){

                            // 調用工具包中的工具函數 爲容器添加文本

                            dwr.util.setValue("helloStr", txt);

                      }

                 </script>

                 </head>

                 <body>

                      <h2 id="h2">Please enter a user who you want to say hello to:</h2>

                      User: <input type="text" id="user"/><button onclick="sayHello()">Say Hello</button><br/>

                      <div id="helloStr"></div>

                 </body>

                 </html>

           在web.xml文件中不妨加上以下內容做爲測試用 :

                      <servlet>

                            <servlet-name>dwr</servlet-name>

                            <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

                            <init-param>

                                  <param-name>debug</param-name>

                                  <param-value>true</param-value>

                            </init-param>

                      </servlet>

                      <servlet-mapping>

                       <servlet-name>dwr</servlet-name>

                       <url-pattern>/dwr/*</url-pattern>

                   </servlet-mapping>

      (2) 實例 : 人員管理

           Person實體類 : Integer id; String name;     String address;  float salary;

           人員管理類PersonMgmt :

                 package com.kettas.ajax.dwr.day5;

                 import java.util.Collection;

                 import java.util.HashMap;

                 import java.util.Map;

                 public class PersonMgmt {

                      private Map<Integer, Person> people = new HashMap<Integer, Person>();

                      private static int count = 10;

                      public PersonMgmt() {

                            Person fred = new Person("Fred", "1 Red Street", 2, 100000.0f);

                            Person jim = new Person("Jim", "42 Brown Lane", 3, 20000.0f);

                            Person shiela = new Person("Shiela", "12 Yellow Road", 4, 3000000.0f);

                            people.put(new Integer(fred.getId()), fred);

                            people.put(new Integer(jim.getId()), jim);

                            people.put(new Integer(shiela.getId()), shiela);

                      }

                      public Collection<Person> getPeople() {

                            return people.values();

                      }

                      public Person getPerson(Integer id) {

                            return people.get(id);

                      }

                      public void add(Person p) {

                      //若是p中沒有值時執行

                            if (p.getId() == -1)

                                  p.setId(count++);

                                  people.put(p.getId(), p);

                            }

                      public void remove(Person p) {

                            people.remove(p.getId());

                      }

                 }

           配置文件dwr.xml :

                 <dwr>

                      <allow>

                            <create javascript="personMgmt" creator="new" scope="session">

                                  <param name="class" value="com.kettas.ajax.dwr.day5.PersonMgmt"></param>

                            </create>

                            <!-- 因爲客戶端傳入的是javascript的Person對象

                                   故這裏要聲明對應的服務器端java的Person對象

                                   不然服務端將沒法將對象從客戶端類型轉換爲服務端類型

<convert》轉換器,對象到字符串之間的轉換 -->

                            <convert match="com.kettas.ajax.dwr.day5.Person" converter="bean"></convert>

                      </allow>

                 </dwr>

           客戶端html文件內容 :

                 <title>Person Management</title>

                 <script type="text/javascript" src="dwr/engine.js"></script>

                 <script type="text/javascript" src="dwr/util.js"></script>

                 <script type="text/javascript" src="dwr/interface/personMgmt.js"></script>

                 <script type="text/javascript">

                      // 初始化顯示人員信息

                      function init(){

                            personMgmt.getPeople(fillTable);

                      }

                      // 函數數組

                      var peoplebodyCellFuncs = [

                            // 函數參數爲人員對象 返回值即咱們要在單元格中顯示的內容

                            // 此數組的長度即表主體顯示內容的列數

                            function(person) { return person.name;},

                            function(person) { return person.address;},

                            function(person) { return person.salary;},

                            // 在第四列添加兩個操做按鈕

                            function(person) {

                                 var div = document.createElement("div");

                                  div.appendChild(createBtn("personId", person.id, prepareEdit, "Edit"));

                                  div.appendChild(createBtn("personId", person.id, removePerson, "Remove"));

                                  return div;

                            }

                      ];

                      // 編輯人員信息

                      function prepareEdit(){

                            var personId = this.personId; // 得到此人id 注意這裏this的使用

                            personMgmt.getPerson(personId, fillFields) // 調用服務端方法 得到此人對象

                      }

                      // 填充人員信息編輯表

                      function fillFields(person){

                            // person對象以下 : {id : 1, name : "yinkui", address : "xf", salary : 50000}

                            // 至關於執行 : document.getElementById("id").value = 1

                            //              document.getElementById("name").value = "yinkui" ...

                            dwr.util.setValues(person);

                      }

                      // 刪除一我的

                      function removePerson(){

                            var personId = this.personId; // 得到此人id 注意這裏this的使用

                            // 因爲對應服務端java方法中 刪除一我的只須要此人id

                            // 故 建立person對象時只須要賦予id

                            // 這樣傳到服務端 建立的java的Person對象頂可能是其餘屬性爲null

                            var person = {

                                  id: personId

                            };

                            personMgmt.remove(person, init); // 調用服務端方法刪除此人 而後刷新人員信息表的顯示

                      }

                      // 建立按鈕的函數

                      function createBtn(attrName, attrValue, onclick, label){

                            var btn = document.createElement("button");

                            btn[attrName] = attrValue; // 按鈕對象中存放對應人員id值

                            btn.onclick = onclick; // 爲按鈕添加事件

                            btn.appendChild(document.createTextNode(label)); // 爲按鈕添加顯示內容

                            return btn;

                      }

                      // 填充人員信息表

                      // 其中people對象是從服務端返回的人員對象數組

                      // 其格式爲[{id : 1, name : "yinkui", address : "xf", salary : 50000}, {...}, ...]

                      function fillTable(people){

                            dwr.util.removeAllRows("peoplebody");// 調用工具函數 清空表主體中的全部行

                            // 調用工具函數 經過人員對象數組 爲表主體添加行

                            // 其中peoplebodyCellFuncs是一個函數數組

                            dwr.util.addRows("peoplebody", people, peoplebodyCellFuncs);

                            clearPerson();// 初始化人員信息編輯表的內容

                      }

                      // 添加新人員

                      function writePerson(){

                            var person = {

                                  id: -1,

                                  name: null,

                                  address: null,

                                  salary: null

                            };

                            // 注意此工具函數的使用

                            // 其做用與dwr.util.setValues({...})偏偏相反

                            // 至關於執行 : person.id = document.getElementById("id").value

                            //    person.name = document.getElementById("name").value

                            dwr.util.getValues(person);

                            personMgmt.add(person, init); // 調用服務端方法 而後刷新人員信息表的顯示

                      }

                      // 初始化顯示人員信息編輯表

                      function clearPerson(){

                            // 注意此工具函數的使用 參數爲對象

                            // 至關於執行 : document.getElementById("id").value = -1

                            //              document.getElementById("name").value = null ...

                            dwr.util.setValues(

                                  {     id: -1,         name: null,

                                       salary: null,         address: null

                                  }

                            );

 }

                 </script>

                 </head>

                 <body onload="init()">

                 <h1>Dynamically Editing a Table</h1>

                 <h2>People Management</h2>

                 <!-- 人員信息列表 -->

                 <table border="1">

                      <!-- 表頭 -->

                      <thead>

                            <tr> th>Name</th>

                                  <th>Address</th>

                                  <th>Salary</th>

                                  <th colspan="2">Actions</th></tr>

                      </thead>

                      <!-- 表的主體 -->

                      <tbody id="peoplebody"></tbody>

                 </table>

                 <h4>Edit Person</h4>

                 <!-- 對人員信息進行編輯 或是添加新人員 -->

                 <table>

                      <tr><td>ID:</td>

                            <td><span id="id">-1</span></td></tr>

                      <tr><td>Name:</td>

                            <td><input id="name" type="text" /></td></tr>

                      <tr><td>Salary:</td>

                            <td><input id="salary" type="text" /></td></tr>

                      <tr><td>Address:</td>

                            <td><input type="text" id="address" /></td></tr>

                      <tr><td colspan="2" align="right">

                            <input type="button" value="Save" onclick="writePerson()" />

                            <input type="button" value="Clear" onclick="clearPerson()" /></td></tr>

                 </table></body></html>

12,關於DOJO的框架:

    含義:Dojo是一個很是強大的面向對象的JavaScript的工具箱, 建議讀者可以去補充一下JavaScript下如何使用OO進行編程的, 這對於你之後閱讀Dojo Source有很大的用處

做用:①處理瀏覽器的不兼容問題,能夠方便創建互動的互動用戶見面。②更容易統一頁面風格。③封裝與服務端的通訊,動態從服務器下載javascript

開發流程:①把dojo工具包考到js文件下

②引用 dojo 的啓動代碼

                   <script type="text/javascript" src="/yourpath/dojo.js" />

③聲明你所要用到的包

<script type="text/javascript">
  dojo.require("dojo.math");引入數學方法
  dojo.require("dojo.io.*"); 引入io

dojo.require("dojo.event.*");  引入事件
  dojo.require("dojo.widget.*");引入頁面

  function init(){  初始化

       var btn = dojo.widget.byId("helloBtn");

       dojo.event.connect(btn, "onClick", "sayHello");事件源,產生關聯,時間方法

  }

  function sayHello(){

       dojo.io.bind(

         { url: "sayHello.jsp",處理事件的url

             handler: callback,  回調函數

             formNode: "myForm" 表單內容

         });}

  function callback(type, data, evt){

       document.getElementById("result").innerHTML

         = data;

  }

 

  dojo.addOnLoad(init);加入事件

</script>

</head>

<body>

  <h2>DOJO Test</h2>

  <form action="#" id="myForm">

       User: <input type="text" name="user" />

  </form>

  <button dojoType="Button" widgetId="helloBtn">DOJO Say Hello</button>

  <div id="result"></div>

</body>

</html>

13,關於Ext框架         

   參考項目文檔

 

     

14補充:Dom部分 建立標籤 var td=document.createElement(「td」); td.apperdchild(childName)

 

 

javascript的高級部分

            1,javascript的對象和繼承  因爲javascript是採起prototype機制的僞繼承」,prototype必須顯示引用「基類」對象,因此註定了javascript只能實現「弱繼承」,或者叫作「對象繼承」
注意這裏的次序關係須要很明確,prototype的賦值必須在對象構造以外。

function classA()
{  classA.prototype.name=」xxx」;屬性

 classA.prototype.methodA = function() {...}這是一個對象方法

classA.methodA = function(){...} //這是一個類方法至關於java的static方法

}
 function classB()
{  classB.prototype.methodA = function(){...}
 }

classB.prototype = new classA();
                      
//注意這裏聲明B繼承自A出如今function classB()函數體以外,而且先於
//classB對象的構造被執行。

 

私有成員的設置

 Var name=「zhang」;

 this.getName=function(){return name;}

 this.setName=function(myname){name=myname; }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Spring

一:Ioc

1含義:爲解決企業應用開發的複雜性而建立的開源框架,用基本的javaBean來完成EJB的事情 從大小和開銷方向spring都是輕量級的

2,用途

①   Ioc容器能夠將對象之間的依賴關係交由spring管理,進行控制

②   AOP:方便進行面向切面的編程,是oop的擴展,想加什麼功能直接加

③   可以集成各類優秀的框架,struts hibernate等

3,spring 組成內容

 

 

 

 

 

 

 

 

 

 

4準備配置工做

①下載SpringFramework的最新版本,並解壓縮到指定目錄。

在IDE中新建一個項目,並將Spring.jar將其相關類庫加入項目

② 配置文件 bean.xml

③在classpath建立日誌輸出文件。log4j.properties

④org.springframework.beans及org.springframework.context包是Spring IoC容器的基礎

5 Spring 基礎語義

     1)IoC (Inversion of Control)=DI (Dependency Injection)控制反轉和依賴注入

     它是一種基於接口的編程,bean由容器建立在須要的時候拿來用便可,主要是採用反射來實現,其核心組建就是BeanFactory 但實際開發經常使用XmlBeanFactory

2)依賴注入的幾種實現類型

  Type1設值注入:經過類的setter方法完成依賴關係的設置,就是給bean類中屬性加set方法

Type3 構造子注入:即經過構造函數完成依賴關係的設

public class DIByConstructor {

private final DataSource dataSource;

private final String message;

public DIByConstructor(DataSource ds, String msg) {

this.dataSource = ds;

this.message = msg;

}}

   

3)幾種依賴注入模式的對比總結


Type2 設值注入的優點

1. 對於習慣了傳統JavaBean開發的程序員而言,經過setter方法設定依賴關係顯得更加直

觀,更加天然。

2. 若是依賴關係(或繼承關係)較爲複雜,那麼Type3模式的構造函數也會至關龐大(咱們需

要在構造函數中設定全部依賴關係),此時Type2模式每每更爲簡潔。

3. 對於某些第三方類庫而言,可能要求咱們的組件必須提供一個默認的構造函數(如Struts

中的Action),此時Type3類型的依賴注入機制就體現出其侷限性,難以完成咱們指望的功

能。

 

Type3 構造子注入的優點:

1. 「在構造期即建立一個完整、合法的對象」,對於這條Java設計原則,Type3無疑是最好的

響應者。

2. 避免了繁瑣的setter方法的編寫,全部依賴關係均在構造函數中設定,依賴關係集中呈現,

更加易讀。

3. 因爲沒有setter方法,依賴關係在構造時由容器一次性設定,所以組件在被建立以後即處於

相對「不變」的穩定狀態,無需擔憂上層代碼在調用過程當中執行setter方法對組件依賴關係

產生破壞,特別是對於Singleton模式的組件而言,這可能對整個系統產生重大的影響。

4. 一樣,因爲關聯關係僅在構造函數中表達,只有組件建立者須要關心組件內部的依賴關係。

對調用者而言,組件中的依賴關係處於黑盒之中。對上層屏蔽沒必要要的信息,也爲系統的

層次清晰性提供了保證。

5. 經過構造子注入,意味着咱們能夠在構造函數中決定依賴關係的注入順序,對於一個大量

依賴外部服務的組件而言,依賴關係的得到順序可能很是重要,好比某個依賴關係注入的

先決條件是組件的DataSource及相關資源已經被設定。

 

 

 

理論上,以Type3類型爲主,輔之以Type2

類型機制做爲補充,能夠達到最好的依賴注入效果,不過對於基於Spring Framework開發的應用而言,

Type2使用更加普遍。

 

 

 

5)bean.xml配置文件

Bean Factory,顧名思義,負責建立並維護Bean實例。

Bean Factory負責根據配置文件建立Bean實例,能夠配置的項目有:

1. Bean屬性值及依賴關係(對其餘Bean的引用)

2. Bean建立模式(是否Singleton模式,便是否只針對指定類維持全局惟一的實例)

3. Bean初始化和銷燬方法

4. Bean的依賴關係

6)XmlBeanFactory兩中注入方式的配置

①property-------àset方法的注入配置

<p:bean id=」hello」 class=」com.kettas.HelloIFImp」>

   <p:property name=」user」 value=」xxx」></p:property>
</p:bean>

②constructor---------à構造方法的注入配置

<p:bean id="hello2" class="com.kettas.spring.ioc.day1.HelloIFImpl">

   <p:constructor-arg index=」0」 value="world"></p:constructor-arg>

   <p:constructor-arg type="java.lang.String"」ref="calendar"></p:constructor-arg>

</p:bean>

說明: index=」0」構造方法第一個參數,用index能夠稍微減小冗餘,可是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

7) 依賴的目標類型分紅三種形式           

 

1) 基本類型+String 
   <value>data</value>類型自動轉化
 2) 對其餘bean 的引用 
       <ref bean="target"/>

 3) 集合類型       list props set map
   list set properties配置相似

  <p:property name="intList">

      <p:list>

                    <p:value>1</p:value>

                    <p:value>2</p:value>

       </p:list>

</p:property>

   <p:property name="objMap">

        <p:map>

     <p:entry>

        <p:key>

              <p:value>1</p:value>

</p:key>

    <p:ref local="hello2"/>

     </p:entry>

   </p:map>

</p:property>

<p:property name="pros">

        <p:props>

              <p:prop key="1">red</p:prop>

              <p:prop key="2">green</p:prop>

        </p:props>

</p:property>

 


               

 Xml配置文件屬性的說明

<bean id="TheAction" ⑴ class="net.xiaxin.spring.qs.UpperAction" ⑵ singleton="true" ⑶

init-method="init" ⑷destroy-method="cleanup" ⑸depends-on="ActionManager" ⑹ >

<property…>

</bean>

⑴ id

Java Bean在BeanFactory中的惟一標識,代碼中經過BeanFactory獲取

JavaBean實例時需以此做爲索引名稱。

⑵ class Java Bean 類名 即真正接口的實現類

⑶ singleton bean的做用域(建立模式(prototype仍是singleton))

單例(Singleton)模式,若是設爲「true」,只維護此Java Bean的一個實例,反之,若是設爲「false」, BeanFactory每次都將建立一個新的實例返回。默認爲true

實現方式是第一次getBean時放入Map中保存,第二次再用時直接在Map中拿,類名爲key,實例爲value。Bean的其餘做用域還有prototype:原型模式:在獲取prototype定義的bean時都產生新的實例,其生命週期由客戶端維護。Session對每次HTTPsession中都回產生一個新的實例。Global session 僅在使用portletcontext的時候纔有效,經常使用的是singleton和prototype

⑷ init-method

初始化方法,此方法將在BeanFactory建立JavaBean實例以後,在嚮應用層返回引

用以前執行。通常用於一些資源的初始化工做。在javaBean中建立init方法,再添加屬性init-method=「init」就行

⑸ destroy-method

銷燬方法。此方法將在BeanFactory銷燬的時候執行,通常用於資源釋放。與init用法相似

⑹ depends-on

Bean依賴關係。通常狀況下無需設定。Spring會根據狀況組織各個依賴關係的構建工做(這裏

示例中的depends-on屬性非必須)。

只有某些特殊狀況下,如JavaBean中的某些靜態變量須要進行初始化(這是一種Bad

Smell,應該在設計上應該避免)。經過depends-on指定其依賴關係可保證在此Bean加

載以前,首先對depends-on所指定的資源進行加載。

⑺ <value>

經過<value/>節點可指定屬性值。BeanFactory將自動根據Java Bean對應的屬性

類型加以匹配。

下面的」desc」屬性提供了一個null值的設定示例。注意<value></value>表明一

個空字符串,若是須要將屬性值設定爲null,必須使用<null/>節點。

⑻ <ref>指定了屬性對BeanFactory中其餘Bean的引用關係。

 

8)使用抽象bean  定義抽象類Abstract=「true」抽象bean不能實例化,一個類能夠建立多個bean

                抽象bean的配置和通常bean的配置基本同樣只是在增長了Abstract=「true」抽象bean是一個bean的模板,容器會忽略抽象bean的定義,不會實例化抽象bean,故不能經過getBean()顯示的得到抽象bean的實例也不能將抽象bean注入其餘bean的依賴屬性。

抽象bean的配置和繼承

   經過Abstract屬性配置抽象bean

   <bean id=」fatherTemple」 class=」abstractClass」 abstract=」true」>

<!—注入屬性à

<property name=」name」 ref=」xxx」/>

</bean>

<!—經過parent屬性定義子beanà

<bean id=」childTemple」 parent=」fatherTemple」>

 <property name=」name2」 ref=」yyyy」/>  -定義本身的屬性

</bean>

說明:子bean配置能夠增長新的配置信息,並能夠定義新的配置覆蓋父類的定義

       子類和父類中至少有一個class屬性不然不知道實現類,父類的class能夠不寫

 

9)bean在容器上的生命週期

初始化兩種方法 1使用init-method屬性指定那個方法在bean依賴關係設置好後自動執行

          2實現initializingBean接口 實現該接口必須實現void afterPropertiesSet()throws Exception那麼就不用設置init-method方法了,注意:最好使用init-method方法,減小代碼的侵入性,若是兩種方法都實現則先實現接口再init方法(通常寫入日誌文件)

 銷燬兩種方法和初始化同樣也有兩種方法:1,destroy-method和1實現DisposableBean接口

 

 

 

 

 

 

 

 

 

6,Spring容器,最基本的接口就是BeanFactory 負責建立,配置,管理bean 它有一個子接口ApplicationContext並將功能擴展。

理論上bean裝配能夠從任何資源得到,包括屬性文件,關係數據庫等,但xml是最經常使用的XmlBeanFactory , ClassPathXmlApplicationContext , FileSystemXmlApplicationContext ,

XmlWebApplicationContext應用系統配置源。Spring中的幾種容器都支持使用xml裝配bean,包括:

XmlBeanFactory , ClassPathXmlApplicationContext ,FileSystemXmlApplicationContext ,
XmlWebApplicationContext

 

BeanFactory接口包含以下的基本方法:
Boolean containsBean(String name): 判斷Spring容器是否包含id爲name的bean定義。
Object getBean(String name): 返回容器id爲name的bean.
Object getBean(String name, Class requiredType): 返回容器中id爲name,而且類型爲requiredType的bean.
Class getType(String name): 返回容器中id爲name的bean的類型.

ApplicationContext有三個實現類實現資源訪問

FileSystemXmlApplicationContext:基於文件系統的xml配置文件建立ApplicationContext,

ClassPathXmlApplicationContext :以類加載路徑下的xml的配置文件建立ApplicationContext(更爲經常使用)

XmlWebApplicationContext:對使用servletContextResource進行資源訪問

得到容器的應用的方式

①InputStream is = new FileInputStream("bean.xml");

XmlBeanFactory factory = new XmlBeanFactory(is);

或者BeanFactory factory = new XmlBeanFactory(

new ClassPathResource("classpath:bean.xml"))

Action action = (Action) factory.getBean("TheAction");

ApplicationContext bf=new ClassPathXmlApplicationContext("classpath:bean.xml")

Action action = (Action) factory.getBean("TheAction");

ApplicationContext bf=new FileSystemXmlApplicationContext(「classpath:bean.xml」)

第一種BeanFactory啓動快(啓動是不建立實體,到用時才建立實體),

第二種ApplicationContext運行快(在加載時就建立好實體)更爲經常使用,繼承BeanFactory

 

        5)工廠bean和bean工廠

FactoryBean(工廠bean)是bean的加工工廠,是對已知Bean的加工,是一個接口,要實現三個方法:

①   Object getObject()能夠對bean進行加工添加功能

②Class getObjectType()③Boolean isSingleton()

              Bf.getBean(「ab」)只是獲得MyFactory.getObject()的object對象 因此最後要強轉。

 

Beanfactory bean工廠 就是生產bean的工廠,注入:

因爲Spring IoC容器以框架的方式提供了工廠方法的功能,並以透明的方式給開發者,不過在一些遺留系統或第三方類庫中,咱們還會碰到工廠方法,這時用戶能夠使用Sping使用工廠方法注入的方式進行配置。

 

靜態工廠方法:
不少工廠類方法都是靜態的,這意味着用戶在無須建立工廠類實例的狀況就能夠調用工廠類方法。所以靜態工廠方法比非靜態工廠方法的調用

更加方便。咱們將carFactory類的getCar()方法調整爲靜態的而後再Spring配置以下:
<bean id=」car」 class =」carFactory」 factory-method=」getCar」/>
用戶直接經過class屬性指定工廠類, 而後在經過factory-method指定對應的靜態工廠方法建立bean。

若是靜態工廠方法須要參數則用<p:constructor-arg index=」1」value="calendar"></p:constructor-arg>傳入

 

實例工廠方法
有些工廠是非靜態的,即必須是實例化工廠類才能調用工廠方法。
下面咱們實例化一個工廠類CarFactory類來爲Car類提供實例。
package com.car;
public class CarFactory
{ public Car getCar(){return new Car();}}
工廠類負責建立一個或多個目標類實例,工廠類方法通常以接口或抽象類變量的形式返回目標類。工廠類對外屏蔽了目標類的實例化步驟。調

用甚至不知道如何具體的目標類是什麼。
下面咱們在Spring 配置文件中進行配置
<!--工廠Bean生成目標Bean-->
<bean id=」carFactory」 class=」com.CarFactory」/>
<!--工廠Bean目標Bean-->
<bean id=」car」 factory-bean=」carFactory」 factory-method=」getCar」/>
factory-bean=」carFactory」指定了工廠類Bean,factory-method=」getCar」指定了工廠類Bean建立該Bean的工廠方法。

和靜態工廠相似若是工廠方法須要參數則用

<p:constructor-arg index=」0」value="calendar"></p:constructor-arg>傳入

 

7,使用ApplicationContext  ApplicationContext覆蓋了BeanFactory的全部功能,並提供了更多的特,容器建立時就建立了singleton Bean

相對BeanFactory而言,ApplicationContext提供瞭如下擴展功能:

1. 國際化支持:繼承MessageSource接口,提供國際化支持

2. 資源訪問:支持對文件和URL的訪問。

3. 事件傳播:事件傳播特性爲系統中狀態改變時的檢測提供了良好支持。

4. 多實例加載:能夠在同一個應用中加載多個Context實例,即加多個配置文件

 1,國際化處理的步驟

1)  寫相應的國家資源文件如:ApplicationResources_zh.properties  

注意字符的轉化相似struts的國際化

2)  bean.xml 的配置

<p:bean id="messageSource[U25] " class="org.springframework.context.support.ResourceBundleMessageSource">

  <p:property name="basename" value="com.kettas.spring.ioc.day3.ApplicationResource" />

  </p:bean>

  <p:bean id="msc" class="com.kettas.spring.ioc.day3.MessageSourceConsumer" />

  </p:beans>

 

3)實現類MessageSourceConsumer

具體的實現類implements MessageSourceAware。注入messageSource ms

獲得字符:String name = ms.getMessage("name", null, Locale.CHINA);name是資源文件的key值

 Locale.CHINA是中文,Locale.ENGLISH英文

 

2. 資源訪問:即外部資源文件的獲取;資源文件

兩種引入外部資源的方式

①<!-- <p:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

           <p:property name="location" value="com/kettas/spring/ioc/day3/jdbc.properties"></p:property>

     </p:bean> -->

 

②,引入解析:xmlns:context="http://www.springframework.org/schema/context"

<context:property-placeholder location="com/kettas/spring/ioc/day3/jdbc.properties"/>

使用<p:property name="driverClassName" value="${jdbc.driver}"></p:property>

jdbc.driver是資源的key值

其它:ApplicationContext.getResource方法提供了對資源文件訪問支持,如:

Resource rs = ctx.getResource("classpath:config.properties");

File file = rs.getFile();

3. 事件傳播:事件機制是觀察者模式的實現

    事件框架兩個重要的成員:

1)  ApplicationEvent:容器事件,必須由ApplicationContext發佈

2)  ApplicationListener:監聽器:可有其餘任何監聽器bean擔任

3)  ApplicationContext是事件源必須由java程序顯示的觸發

1)事件流程:

 

 

 

 

 

 

 

 

 

 

 

 

 

2)代碼實例


1,  事件源.

public class LogEventSource implements ApplicationEventPublisherAware

{

  private ApplicationEventPublisher publisher;   public void setApplicationEventPublisher(

ApplicationEventPublisher publisher){ 

this.publisher = publisher;

  }

 public void fireEvent(){

     LogEvent evt = new LogEvent(this, "Test message");

     publisher.publishEvent(evt);

}

}

 

 

2,  事件監聽

public class Logger implements ApplicationListener {

private Log logger = LogFactory.getLog(Logger.class);

 public void onApplicationEvent(

ApplicationEvent evt) {

         logger.info("Event type: " + evt.getClass().getName());

 if(evt instanceof LogEvent){                logger.info(((LogEvent)evt).getMessage());

   }}

}


3)配置文件

<p:bean id="les"  class="com.kettas.spring.ioc.day3.LogEventSource">   有相應的事件方法

</p:bean>

<p:bean class="com.kettas.spring.ioc.day3.Logger"></p:bean> 處理事件的後臺

</p:beans>

說明:LogEventSourc有相應的事件方法publisher.publishEvent(evt)主動觸發容器事件; Logge處理事件的後臺

 

4. 多實例加載

 BeanPostProcessor bean後處理器 實現BeanPostProcessor接口 對bean實例進一步增長功能,實現兩個方法processBeforeInitialization(Object bean,String name)方法(該方法的第一個參數是將進行後處理的實例bean,name是該bean的名字)和ProcessaAfterInitialization(Object bean,String name).在init()或destory以前作一些處理.Spring的工具類就是經過bean的後處理器完成的。

BeanFactoryPostProcessor 容器後處理器:實現接口BeanFactoryPostProcessor只負責處理容器自己 ,實現的方法是 postProcessBeanFactory(ConfigurableListableBeanFactory  beanFactory)參加資源的引入和獲取,能夠修改bean工廠bean的定義至關一個再配置的過程。相似BeanPostProcessor,ApplicationContext能夠自動檢測到容器中的容器後處理器,可是BeanFacory必須手動調用。
         

5,web中如何使用spring

1),加入相應的jar包

2)Web.xml的配置

<listener>

<listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

或者

(  <servlet><servlet-name>context</servlet-name>

<servlet-class> org.springframework.web.context.ContextLoaderServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>   )

經過以上配置,Web容器會默認自動加載/WEB-INF/applicationContext.xml初始化

ApplicationContext實例,若是須要指定配置文件位置,可經過context-param加以指定

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/myApplicationContext.xml</param-value>

</context-param>

3) Servlet中應用

WebApplicationContext wac= WebApplicationUtils.getRequiredWebApplication(Context(getServletContext()));

HelloIf h=( HelloIf)wac.getBean(「hello」);

 

 

6,BeanFactoryLocator工廠的工廠,主要的兩個實現類ContextSingletonBeanFactoryLocator和SingletonBeanFactoryLocator

BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();

BeanFactoryReference bfr = facLoc.useBeanFactory("il8b");

// BeanFactory fac = bfr.getFactory();

MessageSourceConsumer msc=(MessageSourceConsumer)bfr.getFactory().getBean(「xxxx」);

配置文件只能是beanRefFactory.xml且放在根目錄下

<p:bean id=」il8n」 class=」org.springframework.context.support.ClassPathXmlApplicationContext」>

 <p:constructor-arg><p:value>spring/il8n.xml</p:value></p:constuctor-arg>

</p:bean> 應用另一個配置文件即另一個beanFactory

7, .spring完成自動裝配Autowiring 解決<ref>標籤爲javaBean注入時難以維護而實現的

下面是幾種autowire type的說明:

  ● byname : 試圖在容器中尋找和須要自動裝配的屬性名相同的bean或id,若是沒有找到相應的bean,則這個屬性未被裝配上。配置文件中的id/name中查找

  ● byType : 試圖在容器中尋找一個與須要自動裝配的屬性類型相同的bean或id,若是沒有找到,則該屬性未被裝配上。

                 至關set方法注入

  ● constructor : 試圖在容器中尋找與須要自動裝配的bean的構造函數參數一致的一個或多個bean,若是沒找到則拋出異常。構造方法注入

  ● autodetect : 首先嚐試使用constructor來自動裝配,而後再使用byType方式。

  Dependeney_cheching 依賴檢查 通常和自動裝配配套使用 四種類型:name,simple,object ,all

缺點:spring不必定能很準確的找到javaBean的依賴對象,大型應用通常不用,且配置文件可讀性差

 

 

8,BeanFactoryAware和BeanNameAware

實現 BeanFactoryAware 接口的 bean 能夠直接訪問 Spring 容器,被容器建立之後,它會擁有一個指向 Spring 容器的引用。

BeanFactoryAware 接口只有一個方法void setBeanFactory(BeanFactorybeanFactory)。配置和通常的bean同樣

 

若是某個 bean 須要訪問配置文件中自己的 id 屬性,則能夠使用 BeanNameAware 接口,該接口提供了回調自己的能力。實現

該接口的 bean,能訪問到自己的 id 屬性。該接口提供一個方法:void setBeanName(String name)。

 

9,spring2.5標籤的使用(新特性)對屬性,方法的注入 減小配置文件是工做量

 1)屬性,方法,構造函數的標籤注入

  1)@Autowired  @Autowired按byType自動注入 是對屬性的注入,按照類型匹配原則(set和constructors)

2)@Resource(name="target"):@Resource默認按 byName自動注入罷了。@Resource有兩個屬性是比較重要的,分別是name和type,Spring將@Resource註解的name屬性解析爲bean的名字,而type屬性則解析爲bean的類型。因此若是使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。若是既不指定name也不指定type屬性,這時將經過反射機制使用byName自動注入策略。--à經常使用

3)bean lifecycle  :@PostConstruct--àinit注入  @PreDestroy ----àdestory方法注入

4)ClassPath 類路徑掃描,就是注入bean

2)Bean的標籤注入spring2.5爲咱們引入了組件自動掃描機制,他能夠在類路徑底下尋找標註了@Component、@Service、@Controller、@Repository註解的類,並把這些類歸入進spring容器中管理。它的做用和在xml文件中使用bean節點配置組件是同樣的。要使用自動掃描機制,咱們須要打開如下配置信息:     

@Service用於標註業務層組件bean、@Service("studentBiz")。 @Controller用於標註控制層組件(如struts中的action)、

@Repository用於標註數據訪問組件,即DAO組件。@Repository("dao")

而@Component泛指組件,當組件很差歸類的時候,咱們能夠使用這個註解進行標註,即就是通常的bean。

 

 

二,AOP相關術語

  1

▲AOP是OOP的延續,是Aspect Oriented Programming的縮寫,意思是面向切面的編程。並非所有的AOP框架都是同樣的。他們鏈接點模型的功能可能有強弱之分,有些能夠字段,方法,構造函數級別的,有些只能是方法的好比spring aop 最主要的三種aop框架:AspectJ     Jboss AOP   Spring Aop  前面兩種均可以對字段方法構造函數的支持。Sping和AspectJ有大量的協做

▲Aop添加的主要功能有:事務管理,安全,日誌,檢查,鎖 等

▲Spring對Aop支持的4種狀況:

  ★經典的基於代理的Aop(各個版本的spring) ★@AspectJ註解驅動的切面(spring 2.0)

★純POJO切面(spring 2.0)                ★注入式AspectJ切面(各個版本的spring)

 

2 名詞解釋:

☆關注點 (Concern):關注點就是咱們要考察或解決的問題。如訂單的處理,用戶的驗證、用戶日誌記錄等都屬於關注點。

關注點中的核心關注點 (Core Concerns) ,是指系統中的核心功能,即真正的商業邏輯。如在一個電子商務系統中,訂單處理、客戶管理、庫存及物流管理都是屬於系統中的核心關注點。

還有一種關注點叫橫切關注點 (Crosscutting Concerns) ,他們分散在每一個各個模塊中解決同同樣的問題,跨越多個模塊。如用戶驗證、日誌管理、事務處理、數據緩存都屬於橫切關注點。

在 AOP 的編程方法中,主要在於對關注點的提起及抽象 。咱們能夠把一個複雜的系統看做是由多個關注點來有機組合來實現,一個典型的系統可能會包括幾個方面的關注點,如核心業務邏輯、性能、數據存儲、日誌、受權、安全、線程及錯誤檢查等,另外還有開發過程當中的關注點,如易維護、易擴展等。

☆切面 (Aspect):切面是通知和切入點的結合,通知和寫入點定義了切面的所有內容—它的功能,在什麼時候何地完成功能。在Spring 2.0 AOP中,切面能夠使用通用類(基於模式的風格XML Schema 的風格) 或者在普通類中以 @Aspect 註解(@AspectJ風格)來實現。

下面的例子是基於 xml schema 風格來定義一個 Aspect( 紅字部分 ) :

<aop:aspect id="aspectDemo" ref="aspectBean">

< aop:pointcut id = "myPointcut" expression = "execution(* package1.Foo.handle*(..)" />

< aop:before pointcut -ref = "myPointcut" method = "doLog" />

</aop:aspect >

這個定義的意思是:每執行到 package1.Foo 類的以 handle 開頭的方法前,就會先執行 aspectBean 的 doLog 方法

 

☆鏈接點 (Join point):鏈接點就是在程序執行過程當中某個特定的點,好比某方法調用的時候或者處理異常的時候。這個點能夠

是一個方法、一個屬性、構造函數、類靜態初始化塊,甚至一條語句。切面代碼能夠經過這些點插入到程序的通常流程之中,從而添加新的行爲。 而對於 SPRING 2.0 AOP 來講他是基於動態代理的,故

只支持方法鏈接點,這個必定要記住~!每個方法均可以當作爲一個鏈接點,(AspectJ和Jboss能夠提供其餘aop的實現如,

字段構造函數等)只有被歸入某個Point Cut的 JointPoint 纔有可能被 Advice 。 經過聲明一個org.aspectj.lang.JoinPoint

類型的參數能夠使通知(Advice)的主體部分得到鏈接點信息。JoinPoint 與CutPoint 之間的關係見下面的CutPoint 的講解

 

☆切入點 (Pointcut):若是說通知定義了切面的「什麼」和「什麼時候」那麼切入點就定義了「何地」。切入點指一個或多個鏈接點,能夠理解成鏈接電點的集合 .咱們一般使用明確的類和方法或是利用正則表達式定義這些切入點。 Advice 是經過 Pointcut 來鏈接和介入進你的 JointPoint 的。

好比在前面的例子中,定義了

< aop:pointcut id = "myPointcut" expression = "execution(* package1.Foo.handle*(..)" />  那個類的那個方法使用

那麼這就是定義了一個PointCut ,該Pointcut 表示「在package1.Foo類全部以handle開頭的方法」

假設package1.Foo類裏相似於:

    Public class Foo {

       public handleUpload(){..}

       public handleReadFile(){..}

    }

那麼handleUpload 是一個JointPoint ,handleReadFile 也是一個Joint,那麼上面定義的id=」myPointcut」 的PointCut 則

是這兩個JointPoint 的集合

☆通知 (Advice):通知定義了切面是什麼,以及什麼時候使用,去了描述切面要完成的工做,通知還要解決什麼時候執行這個工做的問題。它應該在某個方法以前調用仍是以後調用,或者拋出一個異常。故通知有各類類型Advice。定義了切面中的實際邏輯(即實現 ) ,好比日誌的寫入的實際代碼。換一種說法Advice 是指在定義好的切入點處,所要執行的程序代碼 。

通知有如下幾種:

§前置通知( Before advice ) :在切入點匹配的方法執行以前運行使用@Before 註解來聲明。implements MethodBeforeAdvice實現的方法是public void before(Method method, Object[] args, Object target)

§返回後通知( After returning advice ) :在切入點匹配的方法返回的時候執行。使用 @AfterReturning 註解來聲明

§拋出後通知( After throwing advice ) : 在切入點匹配的方法執行時拋出異常的時候運行。使用 @AfterThrowing 註解來聲明

§後通知( After (finally) advice ) :不論切入點匹配的方法是正常結束的,仍是拋出異常結束的,在它結束後(finally)後通知(After (finally) advice)都會運行。使用 @After 註解來聲明。這個通知必須作好處理正常返 回和異常返回兩種狀況。一般用來釋放資源。

§環繞通知( Around Advice ) :環繞通知既在切入點匹配的方法執行以前又在執行以後運行。而且,它能夠決定這個方法在何時執行,如何執行,甚至是否執行。在環繞通知中,除了能夠自由添加須要的橫切功能之外,還須要負責主動調用鏈接點 ( 經過 proceed) 來執行激活鏈接點的程序 。 請儘可能使用最簡單的知足你需求的通知。(好比若是前置通知也能夠適用的狀況下,就不要使用環繞通知)

§環繞通知使用 @Around 註解來聲明。並且該通知對應的方法的第一個參數必須是 ProceedingJoinPoint 類型 。在通知體內(即通知的具體方法內),調用 ProceedingJoinPoint 的 proceed() 方法來執行鏈接點方法 。

 

☆引入 (Introduction):引入是指給一個現有類添加方法或字段屬性,引入還能夠在不改變現有類代碼的狀況下,讓現有的 Java 類實現新的接口 (以及一個對應的實現 )。相對於 Advice 能夠動態改變程序的功能或流程來講,引入 (Introduction) 則用來改變一個類的靜態結構 。好比你能夠使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制。舉例來講,咱們能夠建立一個Audiable通知類,記錄對象在最後一次被修改是時的狀態,這很簡單,只要一個方法,setLastModified(Date),和一個實例變量來保存這個狀態,這個新的方法和實例變量而後就能夠引入到如今的類,從而在不修改他們的狀況下讓他們有新的行爲和狀態。

☆目標對象( Target Object )被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫作 被通知(advised) 對象。 既然Spring AOP是經過運行時代理實現的,這個對象永遠是一個 被代理(proxied )對象。

 

☆AOP 代理( AOP Proxy )「代理」是向目標對象應用通知以後被建立的對象,對客戶端來講目標對象和代理對象是同樣的。AOP框架建立的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)。 在Spring中,AOP生成被代理的類有兩種:若是目標對象實現的是一個接口則是用JDK的  java.lang.reflect.Proxy動態代理;若是不是接口則用CGLIB庫生成目標生成目標類的子類在建立這個子類的時候spring織入通知,而且把這個子類的調用委託給子類,這樣就要注意兩點,1 最好是用接口實現代理,cglib只是實現沒有接口也能夠通知的狀況。2,被標記final的方法和類不能通知由於沒法建立子類。。

 

☆織入( Weaving )把切面(aspect)鏈接到其它的應用程序類型或者對象上,並建立一個被通知(advised)的對象,這樣一個行爲就叫作Weaving。 這些能夠在編譯時(例如使用AspectJ 編譯器),類加載時和運行時完成。 Spring 和其餘純 Java AOP 框架同樣,在運行時完成織入 。

其實織入的方式有3種:

一、編譯器織入: 切面在目標類編譯時植入,這須要特殊的編譯器。AspectJ 主要就是是使用這種織入方式 。

二、類加載器織入: -切面在目標類加載到JVM的時候進行織入,這須要特殊的ClassLoader。它能夠在目標類被加載到程序以前加強類的字節代碼。好比AspectWerkz ( 已併入 AspecJ ) 及 JBoss 就使用這種方式 。

三、運行時織入: -即在 java運行的過程當中,使用Java提供代理來實現織入。根據代理產生方式的不一樣,運行時織入又能夠進一步分爲J2SE動態代理及動態字節碼生成兩種方式。因爲J2SE動態代理只能代理接口,所以,須要藉助於一些動態字節碼生成器來實現對類的動態代理。大多數 AOP 實現都是採用這種運行時織入的方式,包括 Spring 。

 

3:AOP的工做模式

 

   代理主要有靜態代理和動態代理

      靜態代理:在代理中實現接口並建立實現類對象,在對實現類的方法增長功能(不經常使用)

      動態代理:實現implements InvocationHandler接口。實現方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

   System.out.println("=========");

      Object o=method.invoke(this.ins, args);

      System.out.println("---------");

      return o;

}

 

 

流程圖:在配置文件的配置

 

  配置文件代碼:

<!-- pointcut definition -->

                   <p:bean id="cf" class="com.kettas.spring.aop.day4.MyClassFilter">

                      <p:property name="classes">

                            <p:set>

                                  <p:value>com.kettas.spring.ioc.day1.HelloIF</p:value>   ---

                            </p:set>

                      </p:property>

                   </p:bean>

                   <p:bean id="mm" class="com.kettas.spring.aop.day4.MyMethodMatcher">

                      <p:property name="methodNames">

                            <p:set>

                                  <p:value>sayHello</p:value>

                            </p:set>

                      </p:property>

                   </p:bean>

                   <p:bean id="pc" class="com.kettas.spring.aop.day4.MyPointcut">

                      <p:property name="classFilter" ref="cf"></p:property>

                      <p:property name="methodMatcher" ref="mm"></p:property>

                   </p:bean>

                  

                   <!--advice   要繼承implements MethodInterceptor-->

                   <p:bean id="timingAdvice" class="com.kettas.spring.aop.day4.TimingInterceptor"></p:bean>

                  

                   <!-- advisor  把通知和切入點結合在一塊兒- 最好給代理增長功能->

                   <p:bean id="timingAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">

                      <p:property name="advice" ref="timingAdvice"></p:property>

                      <p:property name="pointcut" ref="pc"></p:property>

                   </p:bean>

                  

                   <!—target 目標 -->

                   <p:bean id="helloTarget" class="com.kettas.spring.ioc.day1.HelloIFImpl">

                      <p:property name="cal">

                            <p:bean class="java.util.GregorianCalendar"></p:bean>

                      </p:property>

                      <p:property name="user" value="world"></p:property>

                   </p:bean>

                   <!-- proxy -->

                   <p:bean id="hello" class="org.springframework.aop.framework.ProxyFactoryBean">

                      <p:property name="target" ref="helloTarget"></p:property>

                      <p:property name="interceptorNames">

                            <p:list>

                                  <p:idref bean="timingAdvisor"/>   增長一種服務

<p:idref bean="xxxAdvisor"/>   增長另外一種服務

                            </p:list>

                      </p:property>

                      <p:property name="proxyInterfaces">    要和目標類實現共同的接口

                            <p:value>com.kettas.spring.ioc.day1.HelloIF</p:value>

                      </p:property>

                   </p:bean>

</p:beans>

簡化配置:有可能只是目標類不同,其餘的都是同樣的。解決每個目標類都須要一個複雜的代理過程配置的問題,能夠簡化配置的問題 抽象ProxyFactoyBean的方法  如:

<!--  抽象proxy --定義抽象的類,只是沒有目標類,其餘的通知和接口都同樣>

<p:bean id="helloBase" class="org.springframework.aop.framework.ProxyFactoryBean" abstract=「true」>

                      <p:property name="interceptorNames">

                            <p:list>

                                  <p:idref bean="timingAdvisor"/>   增長一種服務

<p:idref bean="xxxAdvisor"/>   增長另外一種服務

                            </p:list>

                      </p:property>

                      <p:property name="proxyInterfaces">    要和目標類實現共同的接口

                            <p:value>com.kettas.spring.ioc.day1.HelloIF</p:value>

                      </p:property>

                   </p:bean>

</p:beans>

    真正的代理

<!—target 目標 繼承抽象方法  只用寫目標類就能夠了 -->

                  

                   <!-- proxy -->

                   <p:bean id="hello" parent=」 helloBase」>

                      <p:property name="target" ref="helloTarget"></p:property>

                   </p:bean>

4:AOP的自動代理

Spring的aop機制提供兩類方式實現類代理。一種是單個代理,一種是自動代理

   單個代理經過ProxyFactoryBean來實現(就如上面的配置),

自動代理:自動代理可以讓切面定義來決定那個bean須要代理,不須要咱們爲特定的bean明確的建立代理從而提供一個更完整的aop實現 經過BeanNameAutoProxyCreator或者 DefaultAdvisorAutoProxyCreator實現。

 

◆採用單個代理方式 (費時費力,配置複雜臃腫)

下面就採用自動代理

   實現代理bean的兩種方式:

      1,「基於Spring上下文的裏聲明的通知者bean的基本自動代理」:通知者的切點表達式用於決定哪一個bean和那些方法須要被代理

      2,」基於@AspectJ註釋驅動切面的自動代理」:切面裏包含的通知裏指定的切點將用於選擇哪一個bean和哪一個方法要被代理

第一種:<!——自動代理增長此行,容器會自動根據通知要匹配的切入點,爲包含切入點的類建立 代理。注意這個bean沒有id,由於永遠都不會直接引用它——>

     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> feedom.net     

        第二種 自動代理@AspectJ切面

 

  然而aspectJ提供可一種基於jdk1.5註解技術的方式,使得配置文件更少,更方便。可以把POJO類註釋爲切面這一般稱爲

@AspectJ.咱們利用@AspectJ註釋,咱們不須要聲明任何額外的類或Bean就能夠把POJO轉換成一個切面例如: 

@Aspect  定義切面再也不是普通的POJO了 在POJO類中加註釋

public class AspectJMixAspect {    

private Log logger = LogFactory.getLog(AspectJMixAspect.class);

@Pointcut("execution(* *..HelloIF.*(..)) || execution(* *..TestBeanIF.*(..))")定義切入點那些類的那些方法添加

public void allMethods() {     }    

@Pointcut("execution(* *..TestBeanIF.toDate(..)) && args(dateStr)")

public void toDate(String dateStr) {

}                 

@Around("allMethods()")   環繞通知

public Object timing(ProceedingJoinPoint pjp) throws Throwable {

long begin = System.currentTimeMillis();    

Object ret = pjp.proceed();

long end = System.currentTimeMillis();

String methodName = pjp.getSignature().getName();

String targetClass = pjp.getTarget().getClass().getName();   

logger.info("Around advice: It took " + (end - begin) + "ms to call "

                                  + methodName + " on " + targetClass);

                   return ret;

                   }

@Before("allMethods()")

public void logBefore(JoinPoint jp) {

logger.info("Before advice: " + jp.getSignature().toLongString()); 

}                 

@AfterReturning(value="toDate(dateStr)", returning = "date", argNames = "date, dateStr")  

public void afterReturning(Date date, String dateStr) {

logger.info("call method toDate(" + dateStr + ") and return " + date);  

}                 

@AfterThrowing(value="toDate(dateStr)", throwing="ex", argNames="dateStr, ex")  

public void afterThrowing(String dateStr, ParseException ex){方法名任意但參數要和argNames=""中的參數順序同樣,

}

}

配置文件

<?xml version="1.0" encoding="UTF-8"?>

<p:beans xmlns:aop="http://www.springframework.org/schema/aop"

                   xmlns:p="http://www.springframework.org/schema/beans"

                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">

                   <!-- target -->

                   <p:bean id="hello" class="com.kettas.spring.ioc.day1.HelloIFImpl">

                      <p:property name="cal">

                            <p:bean class="java.util.GregorianCalendar"></p:bean>

                      </p:property>

                      <p:property name="user" value="world"></p:property>

                   </p:bean>

                   <p:bean id="testBean" class="com.kettas.spring.aop.day5.TestBean">

                      <p:property name="pattern" value="yyyy-MM-dd"></p:property>

                   </p:bean>

                   <!-- apsect bean -->

                   <p:bean id="aspectJAspect" class="com.kettas.spring.aop.day5.AspectJMixAspect"></p:bean>

<aop:aspectj-autoproxy></aop:aspectj-autoproxy> 聲明自動代理bean須要命名空間:aop="http://www.springframework.org/schema/aop"

</p:beans>

 

5,定義純粹的POJO切面 不在普通的bean中加註釋,而是在配置文件中配置

   <!-- target -->

<bean xxx ></bean>

ß-Pojo bean-->

<bean id =」 aspectJAspect」class=」 com.kettas.spring.aop.day5.AspectJMixAspect」/>

<aop:config>

  <aop:aspect ref=」 aspectJAspect」> 將aspectJAspect定義爲切面   下面定義加方法的類和方法

<aop:pointcut id="allMethods" expression="execution(* *..HelloIF.*(..)) or execution(* *..TestBeanIF.*(..))"/>  

  <aop:advisor pointcut-ref="allMethods" advice-ref="timingAdvice" />

  <aop:advisor pointcut-ref="allMethods" before-method=「logBefore」 />

  <aop:advisor pointcut-ref="allMethods" advice-ref="logAfterAdvice" /> 引入外部的通知

  <aop:advisor pointcut="execution(* *..TestBeanIF.toDate(..))" advice-ref="logThrowingAdvice" />

  </aop:config>

 

  14,注入AspectJ切面 

    爲何要用AspectJ:AspectJ提供了Spring AOP不少不能實現的多種切點類型(好比屬性,構造方法切入,因爲不能實現構造方法的切入spring aop就不能實現對象建立過程的通知)

   AspectJ是一個代碼生成工具(Code Generator)。AspectJ有本身的語法編譯工具,編譯的結果是Java Class文件,運行的時候,classpath須要包含AspectJ的一個jar文件。AspectJ是AOP最先成熟的Java實現,它稍微擴展了一下Java語言,增長了一些Keyword等

public aspect TestAspectJ { 

    public TestAspectJ();

  public pointcut writeOperations():

    execution(public boolean Worker.createData()) ||

    execution(public boolean Worker.updateData()) ||

    execution(public boolean AnotherWorker.updateData()) ;

  before() : writeOperations() {

    XXXXXX; advice body

  }

  after() : writeOperations() {

    XXXX;// advice body

  }

}

配置文件

<bean class=」xxx/TeatAspectJ」 factory-method=」aspectof」>

  <property name=」」 ref=」」/></bean>

說明機制:這個<bean>和其餘的bean並無太多區別,只是多了 factory-nmthod屬性 要想得到切面的實例,就必須使用factory-method來調用 aspectof()方法,而不是調用TestAspectJ的構造方法,簡單來講Spring不使用《bean》聲明來建立TestAspectJ實例,它已經被AspectJ運行時建立了,Spring經過aspectof()工廠方法得到切面的引用,而後利用<bean>元素對她執行屬性注入

 

上述代碼關鍵點是pointcut,意味切入點或觸發點,那麼在那些條件下該點會觸發呢?是後面紅字標識的一些狀況,在執行

Worker的createData()方法,Worker的update方法等時觸發

Pointcut相似觸發器,是事件Event發生源,一旦pointcut被觸發,將會產生相應的動做Action,這部分Action稱爲Advice。

  Advice在AspectJ有三種:before、 after、Around之分,上述aspect Lock代碼中使用了Advice的兩種before和after。

  因此AOP有兩個基本的術語:Pointcut和Advice。你能夠用事件機制的Event和Action來類比理解它們

其中advice部分又有:

Interceptor - 解釋器並無在AspectJ出現,在使用JDK動態代理API實現的AOP框架中使用,解釋有方法調用或對象構造或者字段訪問等事件,是調用者和被調用者之間的紐帶,綜合了Decorator/代理模式甚至職責鏈等模式。

Introduction - 修改一個類,以增長字段、方法或構造或者執行新的接口,包括Mixin實現。

 

 

Spring2.5 aop新特性

在配置文件中的配置:就和POJO中的配置同樣

在java類中的配置:就和自動代理類配置同樣 ,只是在配置的時候注意加上<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

注意 execution(* *..HelloIF.*(..)))的含義  任意權限(*),任意返回值(*),任意包下(。。),類名(HelloIF),任意方法(*),任意參數(。。)。   星號(*)表明之間沒有逗號和點號,(。。)表明能夠有逗號和點號

 

5,  切入點指示符:前面的execution就是一個切入點指示符。Spring AOP還支持的切入點指示符有

Within:配置特定的鏈接點  。  this:Aop代理必須是指定類型的實例 如this(org.crazyit.service.AccountService)匹配實現了AccountService接口的全部鏈接點.  Target:和this的表達相似。實現限定目標對象必須是指定類型的實例。

Bean:匹配實例內方法執行的鏈接點 bean(tradeService)能夠用* 通配符

 

 

 

 

 

 

 三:Data Access 數據庫的模板操做

    1,好處:支持事務的管理 2有統一的異常處理 RuntimeException  3 Support各類數據庫

    2,數據源的配置:在spring中數據源的配置有

★有JDBC驅動程序定義的數據源 :在org.springframework.jdbc.datesource包有兩個實現類

                               DriverManagerDateSouce。每一個請求時都創建一個鏈接

                              或者SingleConnectionDataSource  配置api中的set方法,用戶名,密碼,url driver

★由JNDI查詢的數據源  :在tomcate配置數據源,還有Jbose等均可以 經過jndi引用就能夠了

                        <bean id=」dataSource」 class=」…jndi.jndiObjectFactory」>

                          <property name=」jndi」 value=」/jdbc/rantzDataSource」/>

                            <property name=」resourceRef」 value=」true」/>

★鏈接池的數據源:Spring 沒有提供數據源鏈接池,可是DBCP項目提供了一個,下載相關的jar到lib中

                 配置相似第一種JDBC驅動的配置

 

    3 JDBC 咱們知道,Spring JDBC的主要目標是爲了簡化JDBC的編程,方便咱們構建健壯的應用程序。這裏,它的一個基

本設計理念,就是將JDBC編程中變化的和不變化的分開。  在JDBC中,什麼是變化的?毫無疑問,SQL語句是變

化的。那什麼是不變化的?正確的使用JDBC的方式是不變化的。使用JDBC模板

提供了三個模板:JdbcTemplate 最基本的jdbc模板  使用索引參數查詢數據庫

NamedParameterJdbcTemplate ,查詢時把值綁定到SQL裏的命名參數而不是使用索引參數

SimpleJdbcTemplate利用java5的特性,好比自動裝箱,通用,可變參數列表來簡化JDBC模板的使用

         以JdbcTemplate爲例子說明:在已經配置datasource的狀況下就能使用 JdbcTemplate有相關的查詢,插入,等方法

            在xml中配置模板JdbcTemplate  bean

            <bean id=」jdbcTemplate」 class=」org.springframework.jdbc.core.JdbcTemplate」>

                 < property name=」dataSource」 ref=」dataSource」>

              </bean>

           在dao層的bean中加入JdbcTemplate引用就能夠了,這樣就能夠使用它來訪問數據庫

              如:class JdbcDao{

                       Private JdbcTemplate jdbcTemplate

                        //setJdbcTemplate 方法注入

                       Public User getUserById(long id){

                         List users=jdbcTemple.query(sql,new Object[]{Long.valueOf(id)}),new RowMapper(){

 Public Object mapRow(ResultSet rs,int rowNum) throws SQLException

      User user=new User();

       user.setId(rs.getInt(1)); ….;

        return user;  

}

                        Return users.size()>0?(user)users.get(0):null;

}

}

說明:一個字符串,包含用於從數據庫裏選擇數據的 SQL 語句。

      一個 Object 數組,包含與查詢裏索引參數綁定的值。Sql幾個問號就綁定幾個值

一個 RowMapper 對象,它從ResultSet 裏提取數值並構造一個域對象。封裝對象返回結果

而後像下面的設置同樣注入模板JdbcTemplate屬性就能夠了

 <bean id=」jdbcDao」class=」…/JdbcTemplate」>

                     <property name=」 JdbcTemplate」 ref=」 jdbcTemplate」></bean>

 

            JdbcDaoSupport

               注意:能夠使用Spring 對JDBC 的DAO 支持類 JdbcDaoSupport

     思想: 所有 DAO 對象建立一個通用父類,在其中設置JdbcTemplate 屬性,而後讓所有DAO 繼承這個

類,使用父類的JdbcTemplate 進行數據訪問,這樣能夠減小配置量。Spring 的JdbcDaoSupport 就是用於編寫基於JDBC 的DAO 類的基類,咱們只需讓本身的DAO 類繼承它便可 例如上面的

                 class JdbcDao extends JdbcDaoSupport{                   

                       Public User getUserById(long id){

                         List users=getJdbcTemple().query(sql,new Object[]{Long.valueOf(id)}),new RowMapper(){

 Public Object mapRow(ResultSet rs,int rowNum) throws SQLException

      User user=new User();

       user.setId(rs.getInt(1)); ….;

        return user;  

}

                        Return users.size()>0?(user)users.get(0):null;

}

}

在配置文件與配置不繼承JdbcDaoSupport 的DAO 沒有什麼區別

<bean id=」jdbcDao」class=」…/JdbcTemplate」>

                     <property name=」 JdbcTemplate」 ref=」 jdbcTemplate」></bean>

 

4 在Spring 裏集成Hibernate

    1下載相關的Hibernante的jar包到lib文件 注意最好是3.0版本以上

    2使用Hibernate 模板  HibernateTemplate 有各類增刪改查的方法

▲與 Hibernate 進行交互的主要接口是org.hibernate.Session。這個Session 接口提供了基本的數據訪問功

能,好比從數據庫保存、更新、刪除和加載對象。得到 Hibernate Session 對象引用的標準方式是實現。Hibernate 的SessionFactory 接口。SessionFactory負責打開、關閉和管理Hibernate Session,以及其餘一些功能。

3)爲了讓事情簡單一些,Spring 提供了HibernateDaoSupport,用法相似JdbcDaoSupport,它可以讓咱們把會話工廠Bean 直接裝配到DAO 類

   兩種得到session的配置 bean.xml

<!-- 本身加載 hibernate -->

  <bean id="dataSource"[U26]   class="org.apache.commons.dbcp.BasicDataSource">

    <property name="driverClassName">

       <value>oracle.jdbc.driver.OracleDriver</value>

    </property>

    <property name="url">

       <value>jdbc:oracle:thin:@localhost:1521:XE</value>

    </property>

    <property name="password">

       <value>kettas</value>

    </property>

    <property name="username">

        <value>kettas</value>

     </property>

  </bean>

  <bean id="factory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

      <property name="dataSource">

          <ref  bean="dataSource"/>

      </property>

      <property name="mappingResources">

         <list>

            <value>com/kettas/entity/shoppingcart.hbm.xml</value>[U27] 

         </list>

      </property>

      <property name="hibernateProperties[U28] ">

         <props>

             <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>

             <prop key="hibernate.show_sql">true</prop>

             <prop key="hibernate.format_sql">true</prop>

         </props>     

      </property>

  </bean>

  <!-- use 外面的 hibernate.cfg.xml

  <bean id="factory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

           <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>

      </bean>-->

 

<bean  id="DaoSupport" class="com.kettas.dao.impl.Hibernate2DaoSupportImpl">  

     <property name="sessionFactory[U29] ">                                        

       <ref bean="factory"/>

     </property>

  </bean>

 

  <bean id="template"

class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory">  模板注入sessionFactory

<ref bean="factory" />

</property>

</bean>

 

HibernateTemplate中經常使用的方法:getHibernateTemplate().delete(o); update() 。。。。;

super.getHibernateTemplate().executeFind(

                                  new HibernateCallback() {  回調使用hibenate的方法

                                       public Object doInHibernate(Session session)

                                                  throws HibernateException, SQLException { 。。。。}

 

3,  使用Hibernate 3 上下文會話

   若是使用 Hibernate 2,那麼就只能使用HibernateTemplate。

􀂄 Hibernate 上下文會話的主要好處在於把DAO 實現與Spring 解耦。

􀂄 Hibernate 上下文的主要缺點是它們拋出Hibernate 特有的異常。雖然HibernateException 是運行

時異常,但這個異常體系是Hibernate 特有的,並且不像Spring 存留異常體系那樣與ORM 無關,

這可能會在程序向不一樣ORM 遷移時產生問題。

   HibernateTemplate 的缺點是具備必定的侵入性,HibernateDaoSupport),HibernateRantDao 類都被耦合到Spring API。

咱們還有另一種辦法。Hibernate 3 引入的上下文會話能夠管理每事務一個會話,也就不須要讓HibernateTemplate 來確

保這種狀況了。因此,咱們能夠在DAO 裏裝配一個Hibernate SessionFactory 來取代HibernateTemplate

 

public class HibernateRantDao implements RantDao {

private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {

this.sessionFactory = sessionFactory; }

public void saveRant(Rant rant) {

sessionFactory.getCurrentSession().saveOrUpdate(rant);

}}

 

<bean id="rantDao" class="com.roadrantz.dao.hibernate.HibernateRantDao">

<property name="sessionFactory" ref="sessionFactory" />

</bean>

 

 

4,  JPA 是個基於POJO 的存留機制,不只從Hibernate 和Java 數據對象(JDO)吸收了觀念,還適當地混合了Java 5 的註解功能。用法相似Hibernate。基於JPA 的程序使用EntityManagerFactory 的一個實現來獲取EntityManager 的實例,他用entityManagerFactory進行管理,至關sessionFactory。能夠在persistence.xml,相似hibernate的hibernate.cfg.xml配置打他source等資源,也能夠直接在spring的配置文件配置(使用見EJB)

在spring中的配置

<bean id="entityManagerFactory"

class="org.springframework.orm.jpa.

➥   LocalEntityManagerFactoryBean">

<property name="persistenceUnitName" value="rantzPU"[U30]  />

</bean>

<bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">

<property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>

  得到jpa的模板,用法相似Hibernate,就很少說,Ejb中再討論

 

 

 

四:事務管理

    1,事務 (見hibernate的ACID): Spring和EJB同樣,不只提供對程序控制事務管理的支持(手動事務),也對提供聲明式事務管理的支持(容器管理事務),可是Spring對程序控制事務管理的支持與EJB很不同。EJB的事務管理和Java Transaction API(JPA)密不可分。和Ejb不一樣的是Spring採用的是一種回調機制,把真實的事務從事務代碼中抽象出來,那麼Spring就不須要JPA的實現。選擇手動事務仍是容器管理,就是在細微控制和簡便操做之間作出選擇。想精確控制事務就能夠選擇手動事務,不用那麼精確就能夠容器管理事務。

 

事務管理器:無論你是在bean中代碼編寫事務仍是用切面(aspect aop)那樣聲明事務,都須要Spring的事務管理器鏈接特定平臺的事務實現,每一種訪問形式都有一個事務管理器。好比:

    

jdbc.datasource.DataSourceTransactionManager:jdbc鏈接的事務管理,iBATIS也支持

orm.hibernate3. HibernateTransactionManager  :hibernate3的事務支持

orm.jpa.JpaTransactionManager :jpa的事務支持

orm.jdo.JdoTransactionManager   :Jdo事務管理支持

 

這些事務管理器分別充當了某個特定的事務實現門面,這樣你就只要和Spring的事務打交道,而不用關心實際上的事務是怎麼實現的(門面模式)

 

各類事務管理器的配置,以Hibernate 3爲例:

<bean id="transactionManager" class="org.springframework.

➥ orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory[U31] "/>

</bean>

 

JDBC事務管理

<bean id="transactionManager" class="org.springframework.jdbc.

➥ datasource.DataSourceTransactionManager">  ---à DataSourceTransactionManager調用Connection來管理事務

<property name="dataSource" ref="dataSource"/> 

</bean>

 

4,在spring中手動編寫事務

    利用事務模板TransactionTemplate來手動添加事務

 

public void addRant(Rant rant) {

transactionTemplate.execute(-àtransactionTemplate是注入transactionManager獲得的

new TransactionCallback() {-à TransactionCallback()只有一個方法實現doInTransaction,用一個匿名內部類實現

public Object doInTransaction(TransactionStatus ts) {  ------à在事務內執行

try {

rantDao.saveRant(rant);

} catch (Exception e) {

ts.setRollbackOnly();------------------à出現異常就回滾

}return null;

}

}

配置文件

<bean id="rantService"

class="com.roadrantz.service.RantServiceImpl">

<property name="transactionTemplate[U32]  ">

<bean class="org.springframework.transaction.support.

➥ TransactionTemplate">

<property name="transactionManager"

ref="transactionManager" />

</bean>

</property>

</bean>

 

 

5,聲明式事務

   能夠把事務想成一個切面,那麼就能夠用事務性邊界包裹Biz層的方法,而後注入事務

   Spring提供了三種在配置文件聲明事務性邊界的方式:★經常使用的Spring aop代理 bean來支持事務。★但在Spring 2中增長了兩種新的方式:簡單的XML聲明(xml-declared)事務和★註釋驅動事務

 

   1)代理事務:聲明式事務管理經過使用Spring的TransactionProxyFactoryBean代理POJO來完成。TransactionProxyFactoryBean是ProxyFactoryBean的一個特化,他知道如何經過事務性邊界包裹一個POJO的方法來代理他們。

 

<bean id="rantService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="target" ref="rantServiceTarget" />      --à裝配事務目標,至關給biz層的方法加事務

<property name="proxyInterfaces" value="com.roadrantz.service.RantService" />

<property name="transactionManager" ref="transactionManager" />   --à提供適當的事務管理器

<property name="transactionAttributes[U33] ">

<props>

<prop key="add*">PROPAGATION_REQUIRED</prop>

<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>

</props>

</property>

</bean>

事務傳播行爲:

 PROPAGATION_REQUIRED 當前方法必須有一個事務,有事務則運行該事務,沒有則開始新的事務。---à最經常使用

 PROPAGATION_MANDATORY:該方法必須有事務,沒有事務則拋出異常

PROPAGATION_NESTED :該方法運行在嵌套事務中。若是封裝事務不存在則就像第一種PROPAGATION_REQUIRED

PROPAGATION_NEVER  :該方法不能有事務,有事務則拋出異常。

PROPAGATION_NOT_SUPPORTED:該方法不能有事務,若是有事務,則將該方法在運行期間掛起。

PROPAGATION_REQUIRES_NEW:方法必須運行在事務裏,

PROPAGATION_SUPPORTS:表示當前方法不須要事務性上下文,可是若是有一個事務已經在運行的話,他能夠在這個事務裏運行。

 

PROPAGATION,   ISOLATION,     readOnly,     -Exception, +Exception

     (傳播行爲)    (隔離級別 可選)  (事務只讀 可選)  (回滾規則  可選)

 

  能夠建立事務模板簡化配置  :創建事務的抽象聲明

 <bean id="TXServiceTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

 abstract=「true」>[U34] 

<property name="transactionManager" ref="transactionManager" />   --à提供適當的事務管理器

<property name="transactionAttributes[U35] ">

<props>

<prop key="add*">PROPAGATION_REQUIRED</prop>

<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>

</props>

</property>

</bean>

<bean id=」ranBiz」 parent=」 TXServiceTemplate[U36] 」>

  <property name="proxyInterfaces" value="com.roadrantz.service.RantService" />

<property name="transactionManager" ref="transactionManager" />   --à提供適當的事務管理器

</bean>

 

2)在Spring2.0聲明事務 <tx>上面的方法會致使配置很臃腫,下面就是更簡單的配置

   在Spring2.0中專門爲聲明事務提供了一些新的標籤 tx名稱空間下

xmlns:tx=http://www.springframework.org/schema/tx

xmlns:aop[U37] ="http://www.springframework.org/schema/aop"

     http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

<tx:advice[U38]  id="txAdvice" transaction-manager="txManager">

<tx:attributes>

<tx:method name="get*" read-only="true"/>

<tx:method name="create*" />

<tx:method name="join*"/>

</tx:attributes>

</tx:advice>

                  

<aop:config>

      <aop:advisor[U39]  pointcut="execution(* *..Roster.*(..))" advice-ref="txAdvice"/>

</aop:config>

 

3)定義註釋驅動的事務,@Transactional能夠在源代碼中註釋來進一步簡化配置

@Transactional[U40] (propagation=Propagation.SUPPORTS, readOnly=true)

@Service("roster")

public class RosterImpl implements Rosterpublic

@Transactional                  --------------- --------à方法層面的事務

Public  Player createPlayer(Player p) {

      playerDao.save(p);

      return p;

}

 

<context:component-scan

base-package="com.kettas.spring.dao.day5.roster.dao,com.kettas.spring.dao.day5.roster.biz">

</context:component-scan>

<tx:annotation-driven/>  自動搜索@Transactional的bean 而後把事務通知告訴它。

 

 

五:Spring的MVC

          目前比較好的MVC,老牌的有Struts、Webwork。新興的MVC 框架有Spring MVC、

Tapestry、JSF等。這些大可能是著名團隊的做品,另外還有一些邊緣團隊的做品,也至關出色,

如Dinamica、VRaptor等。

 

六:Spring的安全機制 Spring Security:它提供全面的安全性解決方案,同時在Web請求和方法調用處理身份確認和受權,利用依賴注入和aop技術。主要名詞:

1安全攔截器:至關應用的一把鎖,可以阻止對應用程序中保護資源的訪問(一般是用戶名和密碼 正確才能打開鎖)

          2 認證管理器:經過用戶名和密碼來作到這點的,負責肯定用戶的身份。是由

          3:訪問決策管理器:根據你的身份來肯定你是否擁有對資源的訪問,即受權管理

          4:運行身份管理器:運行身份管理器能夠用來使用另外一個身份替換你的身份,從而容許你訪問應用程

序內部更深處的受保護對象。

 5:調用後管理器:訪問結束後還能夠返回取得相關資源,其餘安全管理器組件在受保護資源

被訪問以前實施某種形式的安全措施強制執行,而調用後管理器則是在受保護資源被訪問以後執行安全措

施。

 

         認證管理器是由org.acegisecurity. AuthenticationManager 接口定義的

ProviderManager 是認證管理器的一個實現,它將驗證身份的責任委託給一個或多個認證提供者

DaoAuthenticationProvider 是一個簡單的認證提供者,它使用數據存取對象(DAO)來從關係數據庫

中檢索用戶Spring Security 支持經過LdapAuthenticationProvider 根據LDAP 進行身份驗證,

LdapAuthenticationProvider 是一個知道如何根據LDAP 倉庫查看用戶憑證的認證提供信息(包括用戶的密碼)

身份驗證只是Spring Security 安全保護機制中的第一步。一旦Spring Security 弄清用戶的身份後,它必須

決定是否容許用戶訪問由它保護的資源

Spring Security 對Web 安全性的支持大量地依賴於Servlet 過濾器。這些過濾器攔截進入請求,而且

在你的應用程序處理該請求以前進行某些安全處理。Spring Security 提供有若干個過濾器,它們可以攔截

Servlet 請求,並將這些請求轉給認證和訪問決策管理器處理,從而加強安全性。

 

七:Spring的遠程調用:Spring遠程支持是由普通(Spring)POJO實現的,這使得開發具備遠程訪問功能的服務變得至關容易

       四種遠程調用技術:

       ◆ 遠程方法調用(RMI)       ◆ Caucho的Hessian和Burlap 

 ◆Spring本身的Http invoker    ◆使用SOAP和JAX-RPC的web Services

Spring對上面的遠程服務調用都有支持

       Spring遠程調用支持6種不一樣的RPC模式:遠程方法調用(RMI)、Caucho的Hessian和Burlap、Spring本身的HTTP invoker、

EJB和使用JAX-RPC 的Web Services。表6.1歸納地論述了每一個模式,並簡略討論它們在不一樣狀況下的用處。

表6.1                                  Spring遠程調用所支持的RPC模式

RPC模式

在何種狀況下有用

遠程方法調用(RMI)

不考慮網絡限制(如防火牆)時,訪問/公開基於Java的服務

Hessian或 Burlap

考慮網絡限制時,經過HTTP訪問/公開基於Java的服務

HTTP invoker

考慮網絡限制時,訪問/公開基於Spring的服務

EJB

訪問用EJB實現的遺留的J2EE系統

JAX-RPC

訪問Web Services

 

 

遠程方法調用(RMI)。經過使用 RmiProxyFactoryBean 和 RmiServiceExporter,Spring同時支持傳統的RMI(使用java.rmi.Remote接口和java.rmi.RemoteException)和經過RMI調用器實現的透明遠程調用(支持任何Java接口)。

Spring的HTTP調用器。Spring提供了一種特殊的容許經過HTTP進行Java串行化的遠程調用策略,支持任意Java接口(就像RMI調用器)。相對應的支持類是 HttpInvokerProxyFactoryBean 和 HttpInvokerServiceExporter。

Hessian。經過 HessianProxyFactoryBean 和 HessianServiceExporter,能夠使用Caucho提供的基於HTTP的輕量級二進制協議來透明地暴露服務。

Burlap。 Burlap是Caucho的另一個子項目,能夠做爲Hessian基於XML的替代方案。Spring提供了諸如 BurlapProxyFactoryBean 和 BurlapServiceExporter 的支持類。

JAX RPC。Spring經過JAX-RPC爲遠程Web服務提供支持。

 

客戶端發起對代理的調用,好像是代理提供了這些服務的功能同樣。代理表明客戶端和遠程服務交流。它處理鏈接的具體狀況,

並向遠程服務發起遠程調用。在Spring裏,遠程服務是被代理的,因此他們能像通常的Bean那樣置入到客戶端的代碼裏

 [U41] 

八:Spring的Web服務

Spring支持:使用JAX-RPC暴露服務   訪問Web服務

除了上面所說的支持方法,你還能夠用XFire xfire.codehaus.org 來暴露你的服務。XFire是一個輕量級的SOAP庫,目前在Codehaus開發。

使用JAXI-RPC暴露服務

Spring對JAX-RPC Servlet的端點實現有個方便的基類 - ServletEndpointSupport。爲暴露咱們的Account服務,咱們繼承了Spring的ServletEndpointSupport類來實現業務邏輯,這裏一般把調用委託給業務層。

訪問服務:

Spring有兩個工廠bean用來建立Web服務代理,LocalJaxRpcServiceFactoryBean 和 JaxRpcPortProxyFactoryBean。前者只返回一個JAX-RPT服務類供咱們使用。後者是一個全功能的版本,能夠返回一個實現咱們業務服務接口的代理。本例中,咱們使用後者來爲前面段落中暴露的AccountService端點建立一個代理。你將看到Spring對Web服務提供了極好的支持,只須要不多的代碼 - 大多數都是經過相似下面的Spring配置文件:

     <bean id="accountWebService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">

        <property name="serviceInterface" value="example.RemoteAccountService"/>

        <property name="wsdlDocumentUrl" value="http://localhost:8080/account/services/accountService?WSDL"/>

        <property name="namespaceUri" value="http://localhost:8080/account/services/accountService"/>

        <property name="serviceName" value="AccountService"/>

        <property name="portName" value="AccountPort"/>

     </bean>

XFire一個Codehaus提供的輕量級SOAP庫。在寫做這個文檔時(2005年3月)XFire還處於開發階段。雖然Spring提供了穩定的支持,可是在將來應該會加入更多特性。暴露XFire是經過XFire自身帶的context,這個context將和RemoteExporter風格的bean相結合,後者須要被加入到在你的WebApplicationContext中。

 

 

九:Spring的消息 Java Message Service (JMS)

   前面的RMI,Hesian ,Burlap,HTTP invoker web服務的間通訊,都是程序之同步,即當客戶端調用遠程方法時必須在方法完成以後才能繼續執行。

   JMS是一種異步消息傳遞的標準API,客戶端不須要等待服務端處理消息,客戶端發送消息,會繼續執行,這是由於客戶端假設服務端最終可以收到並處理這條消息。相似Ajax

 

   發送消息 使用JMS的模板JsmTemplate  接收消息

 

 

十:Spring和EJB的整合:

        Spring有兩種方法提供對EJB的支持:

Spring能讓你在Spring的配置文件裏,把EJB做爲Bean來聲明。這樣,把EJB引用置入到其餘Bean的屬性裏就成爲可能了,好像EJB就是另外一個POJO。

  Spring能讓你寫EJB,讓EJB成爲Spring配置的Bean的代理的工做。

Spring提供了兩個代理工廠Bean,來代理EJB的訪問:

   LocalStatelessSessionProxyFactoryBean——用來訪問本地EJB(EJB和它的客戶端在同一個容器中)。

   SimpleRemoteStatelessSessionProxyFactoryBean——用來訪問遠程EJB(EJB和它的客戶端在獨立的容器中)。

 

 

 

 

十一:訪問企業服務:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                               SSH和Ajax的整合

 

一:準備工做

    把Hibernate的jar包 ,spring的jar 包  ,Struts的jar包 ajax中的jar包好比dwr。

 

二:配置文件說明

   Web.xml

<listener[U42] >

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/classes/com/kettas/config/springBean.xml</param-value>

</context-param>

<servlet>

<servlet-name>action[U43] </servlet-name>

<servlet-class> org.apache.struts.action.ActionServlet</servlet-class>

<init-param>

<param-name>config</param-name>

        <param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

<init-param>

<param-name>debug</param-name>

<param-value>3</param-value>

</init-param>

<init-param>

<param-name>detail</param-name>

<param-value>3</param-value>

</init-param>

<load-on-startup>0</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

 

  <servlet>

    <servlet-name>dwr[U44] </servlet-name>

    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

    <init-param>

       <param-name>debug</param-name>

       <param-value>true</param-value>

    </init-param>

  </servlet>

  <servlet-mapping>

    <servlet-name>dwr</servlet-name>

    <url-pattern>/dwr/*</url-pattern>

  </servlet-mapping>

 

struts-config.xml

 <form-beans>

<form-bean name="dynaActionForm"

              type="org.apache.struts.action.DynaActionForm">

<!-- admin formBean -->

<form-property name="loginName" type="java.lang.String" />

</form-bean>

</form-beans>

<global-exceptions />

<global-forwards />

<action-mappings>

<action path="/adminLogin" name="dynaActionForm" parameter="adminLogin"

type="org.springframework.web.struts.DelegatingActionProxy[U45] ">

<forward name="ok" path="/admin/admin.html" redirect="true" />

<forward name="error" path="/error.jsp" />

</action>

</action-mappings>

<!--message-resources

parameter="com.yourcompany.struts.ApplicationResources" /-->

<plug-in

className="org.springframework.web.struts.ContextLoaderPlugIn[U46] ">

<set-property property="contextConfigLocation"

value="/WEB-INF/classes/beans.xml" />

</plug-in>

 

Spring.xml

 

<bean id="sessionFactory"[U47]  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>

</bean>

<bean id="template" class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory"><ref local="sessionFactory" /></property>

相關文章
相關標籤/搜索