20145212 《Java程序設計》第9周學習總結

20145212 《Java程序設計》第9周學習總結

教材學習內容總結

1、JDBC架構

1.數據庫驅動html

  • 這裏的驅動的概念和平時聽到的那種驅動的概念是同樣的,好比平時購買的聲卡,網卡直接插到計算機上面是不能用的,必需要安裝相應的驅動程序以後纔可以使用聲卡和網卡,一樣道理,咱們安裝好數據庫以後,咱們的應用程序也是不能直接使用數據庫的,必需要經過相應的數據庫驅動程序,經過驅動程序去和數據庫打交道,以下所示:

2.JDBC介紹java

  • SUN公司爲了簡化、統一對數據庫的操做,定義了一套Java操做數據庫的規範(接口),稱之爲JDBC。這套接口由數據庫廠商去實現,這樣,開發人員只須要學習jdbc接口,並經過jdbc加載具體的驅動,就能夠操做數據庫。

以下圖所示:
mysql

  • JDBC全稱爲:Java Data Base Connectivity(java數據庫鏈接),它主要由接口組成。
  • 組成JDBC的2個包:
    java.sql
- 開發JDBC應用須要以上2個包的支持外,還須要導入相應JDBC的數據庫實現(即數據庫驅動)。

3.DriverManager類講解

- Jdbc程序中的DriverManager用於加載驅動,並建立與數據庫的連接,這個API的經常使用方法:

DriverManager.registerDriver(new Driver())
DriverManager.getConnection(url, user, password),程序員

- 注意:在實際開發中並不推薦採用registerDriver方法註冊驅動。緣由有二:

1.查看Driver的源代碼能夠看到,若是採用此種方式,會致使驅動程序註冊兩次,也就是在內存中會有兩個Driver對象。
2.程序依賴mysql的api,脫離mysql的jar包,程序將沒法編譯,未來程序切換底層數據庫將會很是麻煩。sql

推薦方式:```Class.forName("com.mysql.jdbc.Driver");```
採用此種方式不會致使驅動對象在內存中重複出現,而且採用此種方式,程序僅僅只須要一個字符串,不須要依賴具體的驅動,使程序的靈活性更高。

4.Connection類講解
- Jdbc程序中的Connection,它用於表明數據庫的連接,Collection是數據庫編程中最重要的一個對象,客戶端與數據庫全部交互都是經過connection對象完成的,這個對象的經常使用方法:
·createStatement():建立向數據庫發送sql的statement對象。
·prepareStatement(sql) :建立向數據庫發送預編譯sql的PrepareSatement對象。
·prepareCall(sql):建立執行存儲過程的callableStatement對象。
·setAutoCommit(boolean autoCommit):設置事務是否自動提交。
·commit() :在連接上提交事務。
·rollback() :在此連接上回滾事務。

5.ResultSet類捲動、更新數據

- Jdbc程序中的ResultSet用於表明Sql語句的執行結果。Resultset封裝執行結果時,採用的相似於表格的方式。ResultSet 對象維護了一個指向表格數據行的遊標,初始的時候,遊標在第一行以前,調用ResultSet.next() 方法,可使遊標指向具體的數據行,進行調用方法獲取該行的數據。
ResultSet既然用於封裝執行結果的,因此該對象提供的都是用於獲取數據的get方法:
- 獲取任意類型的數據

getObject(int index)
getObject(string columnName)數據庫

- 獲取指定類型的數據,例如:

getString(int index)
getString(String columnName)編程

- ResultSet還提供了對結果集進行滾動的方法:

next():移動到下一行
Previous():移動到前一行
absolute(int row):移動到指定行
beforeFirst():移動resultSet的最前面。
afterLast() :移動到resultSet的最後面。api

### 2、反射與ClassLoader

- 當咱們使用一個類,若是這個類還未加載到內存中,系統會經過加載、鏈接、初始化對類進行初始化。```
1.類加載:指的是將類的class文件讀入JVM,併爲之建立一個Class對象。
2.類鏈接:指的是把類的二進制數據合併到JRE中,這又分爲3個階段:
·校驗:檢查載入Class文件數據的正確性。
·準備:給類的靜態變量分配存儲空間,並進行默認初始化。
·解析:將類的二進制數據中的符號引用替換成直接引用。
3.初始化:對類的靜態變量、靜態初始化塊進行初始化。

- 注意:

1.一個final類型的靜態屬性,若是在編譯時已經獲得了屬性值,那麼調用該屬性時,不會致使該類初始化,由於這個至關於使用常量;
2.使用ClassLoader()方法,只是加載該類,並未初始化。數組

4.類加載器
![](http://images2015.cnblogs.com/blog/877181/201604/877181-20160426222801939-1570271209.jpg)


- 類加載器就是負責將.class文件加載到內存中,併爲之生成對應的java.lang.Class對象,它負責加載全部的類,而一旦一個類被加載入JVM中,就不會被再次載入了。
- 在Java中,一個類用其全限定類名(即包名+類名)做爲標識。
- 在JVM中,一個類用其全限定類名和其類加載器做爲標識。
- JVM運行時會產生3個ClassLoader,分別爲:```BootstrapClassLoader```(根類加載器)、```ExtClassLoader```(擴展類加載器)和```AppClassLoader```(系統類加載器)。

- UML結構以下:
![](http://images2015.cnblogs.com/blog/877181/201604/877181-20160426220139861-248254556.jpg)

其中,BootstrapClassLoader負責加載JRE的核心類庫,它不是ClassLoader的子類,使用C++編寫,所以咱們在Java中看不到它,經過其子類的getParent()方法獲取時,將返回null。BootstrapClassLoader負責裝載JRE目標下的rt.jar、charsets.jar等Java核心類庫。

### 3、自定義泛型、枚舉與註釋

1.泛型
- 在JDK1.5版本以前,若是在集合中添加了不一樣類型的數據,須要在程序的運行期間對類型之間的轉換進行檢查。
例如:

List arrayList=new arrayList();
- 在arrayList中添加String類型的對象和Integer對象,可是咱們定義以下一個數組String[] values=new String[arrayList.size()];```
若是想要把arrayList轉換成數組的話就會出現錯誤:安全

arrayList.toArray(values);//運行期間錯誤
這是由於List中包含了整型封裝類型的對象。可是該錯誤只能在運行期間才能發現,程序可以正常的經過編譯,並不會報錯。對於程序中出現的錯誤,應該儘早的通知程序員。泛型可以很好地解決這個問題。

  • 泛型在集合中的應用

在JDK1.5版本以後Java提供了對泛型的支持。例如對於一個ArrayList列表來講,若是隻想在列表中放入String類型元素,能夠用下面的方法來實現:
ArrayList<String> list=new ArrayList<String>();

  • 泛型使得編譯器可以在編譯期間對集合中加入的對象進行檢查,若是加入了不一樣類型的對象,就會報錯,而沒必要等到運行期間再進行相關的類型轉換。和原來沒有使用泛型相比,它將原來須要在運行時期才能發現的異常提早到了編譯期間,使得程序的安全性也大大提升,泛型通常用於集合類中。

2.枚舉

  • 枚舉也是JDK1.5以後的版本之後Java新加入的特性。使用枚舉能夠表示一組常量數據。枚舉的本質是一個類,可使用enum關鍵字來聲明一個枚舉類型,其聲明方式以下:
    [訪問控制符] enum 枚舉類型名{value1,value2,......}

  • 使用枚舉類型須要注意如下幾點:

·枚舉類型能夠定義在類的內部也能夠定義在類的外部。若是定義在類的內部,那麼其訪問控制符能夠是public,protected,private或者默認的控制符。若是定義在類的外部,其訪·問控制符只能是public和默認控制符;
·枚舉類型中定義的value值都默認爲public static final的。其值一經定義就不能在被修改了。多個value值之間須要用逗號隔開;
·枚舉類型中除了能夠聲明常量以外還能夠聲明方法。可是方法須要在常量以後,而且常量和方法之間要用分號區分;
·枚舉類型中的值能夠經過枚舉類型名直接對他們進行訪問;
·枚舉類型不能聲明爲abstract或者final類型;

  • 枚舉類型的經常使用方法
public final String name()//返回枚舉常量的名稱;
public final int ordinal()//返回枚舉常量在枚舉類型中的位置,第一個枚舉值序號爲0,依次類推;
public String toString()//返回枚舉常量的名字,能夠重寫此方法;
public static valueOf(enumType,String name)//返回與name名字相對應的枚舉常量;

3.註釋

  • 在原始碼中使用註釋,對編譯程序提供額外編譯提示,或提供應用程序執行時期可讀取的組態信息。註釋能夠僅用於原始碼,編譯後留在.class文檔僅供編譯程序讀取或開放執行時期讀取。

  • 經常使用標準註釋
@Override //就是標準註釋,被註釋的方法必須是父類或接口中已定義的方法,請編譯程序協助是否真的爲從新定義方法。
@Deprecated //若是某個方法原先存在與API中,後來不建議再使用,能夠在該方法上註釋。如有用戶後續想調用或從新定義這個方法,編譯程序會提出警告。對於支持泛型的API,建議明確指定泛型真正類型,若是沒有指定,編譯程序會提出警告。
@SuppressWarnings //指定抑制unchecked的警告產生:
@SuppressWarnings(value={"unchecked"})
@SafeVarargs //代表開發人員肯定避免了heap pollution問題。heap pollution問題就是編譯程序沒法檢查執行時期的類型錯誤,沒法具體確認自變量類型。
@FunctionalInterface //讓編譯程序可協助檢查interface是否可作爲lambda的目標類型
  • 自定義註釋類型
    ·標示註釋:就是註釋名稱自己就是信息,對編譯程序或應用程序來講,主要是檢查是否有註釋出現,並做出對應的動做。
    ·相關規則:
(1)若是註釋名稱自己沒法提供足夠信息,設置單值註釋 
(2)註釋屬性也能夠用數組形式指定。 
(3)在定義註釋屬性時,若是屬性名稱爲value,則能夠省略屬性名稱,直接指定值。 
(4)對成員設定默認值,使用default關鍵字便可。 
(5)要設定數組默認值,能夠在default以後加上{},必要時{}中可放置元素值。
  • 定義註釋時,可以使用java.lang.annotation.Target限定時可指定java.lang.annotation.ElementType的枚舉值。
  • 在製做JavaDoc文件時,默認不會將註釋數據加入文件中,若是想要將註釋數據加入文件,可使用java.lang.annotation.Documented。
  • 默認父類設定的註釋,不會被繼承至子類,在定義註釋時,設定java.lang.annotation.Inherited註釋,就可讓註釋被子類繼承。

  • JDK8標註加強功能
1.ElementType的枚舉成員是用來限定哪一個聲明位置能夠進行標註。在JDK8中,增長了兩個枚舉成員TYPE _PARAMETER、TYPE _USE。
2.ElementType.TYPE _ USE可用於標註在各式類型,一個標註若是被設定爲ElementType.TYPE_USE,只要是類型名稱,均可以進行標註。
3.@Repeatable 可讓你在同一個位置重複相同標註
4.@Filters 做爲收集重複標註信息的容器,而每一個@Filters儲存各自指定的字符串值。
  • 執行時期讀取註釋信息
1.自定義註釋,默認會將註釋信息存儲於.class文檔,可被編譯程序或位碼分析工具讀取,但執行時期沒法讀取註釋信息,在執行時期讀取註釋信息,可使用java.lang.annotation.Retention搭配java.lang.annotation.RetentionPolicy枚舉指定。
2.RetentionPolicy爲RUNTIME的時機,在於讓註釋在執行時期提供應用程序信息,可以使用java.lang.reflect.AnnotatedElement接口操做對象取得註釋信息。
3.JDK 8中新增了getDeclaredAnnotation()、getDeclaredAnnotationsByType()、getAnnotationsByType()三個方法。 
getDeclaredAnnotation()可讓你取回指定的標註,在指定@Repeatable的標註時,會尋找收集重複標註的容器。 
getDeclaredAnnotationsByType()、getAnnotationsByType()就不會處理@Repeatable的標記。

教材學習問題

  • 嘗試用JDBC鏈接數據庫,共有如下7個步驟:
    1.加載JDBC驅動程序:
    在鏈接數據庫以前,首先要加載想要鏈接的數據庫的驅動到JVM(Java虛擬機),這經過java.lang.Class類的靜態方法forName(String className)實現。
try{   
    //加載MySql的驅動類   
    Class.forName("com.mysql.jdbc.Driver") ;   
    }catch(ClassNotFoundException e){   
    System.out.println("找不到驅動程序類 ,加載驅動失敗!");   
    e.printStackTrace() ;   
    }

成功加載後,會將Driver類的實例註冊到DriverManager類中。
2.提供JDBC鏈接的URL
·鏈接URL定義了鏈接數據庫時的協議、子協議、數據源標識。
·書寫形式:協議:子協議:數據源標識
·協議:在JDBC中老是以jdbc開始
·子協議:是橋鏈接的驅動程序或是數據庫管理系統名稱。
·數據源標識:標記找到數據庫來源的地址與鏈接端口。

//例如:(MySql的鏈接URL)   
jdbc:mysql:   
//localhost:3306/test?useUnicode=true&characterEncoding=gbk ;   
useUnicode=true:表示使用Unicode字符集。若是characterEncoding設置爲   
gb2312或GBK,本參數必須設置爲true 。characterEncoding=gbk:字符編碼方式。

3.建立數據庫的鏈接
·要鏈接數據庫,須要向java.sql.DriverManager請求並得到Connection對象, 該對象就表明一個數據庫的鏈接。
·使用DriverManager的getConnectin(String url , String username ,String password )方法傳入指定的欲鏈接的數據庫的路徑、數據庫的用戶名和 密碼來得到。

//鏈接MySql數據庫,用戶名和密碼都是root   
     String url = "jdbc:mysql://localhost:3306/test" ;    
     String username = "root" ;   
     String password = "root" ;   
     try{   
    Connection con =    
             DriverManager.getConnection(url , username , password ) ;   
     }catch(SQLException se){   
    System.out.println("數據庫鏈接失敗!");   
    se.printStackTrace() ;   
     }

4.建立一個Statement
·要執行SQL語句,必須得到java.sql.Statement實例,Statement實例分爲如下3種類型:

一、執行靜態SQL語句。一般經過Statement實例實現。   
      二、執行動態SQL語句。一般經過PreparedStatement實例實現。   
      三、執行數據庫存儲過程。一般經過CallableStatement實例實現。

·具體的實現方式:

Statement stmt = con.createStatement() ;   
       PreparedStatement pstmt = con.prepareStatement(sql) ;   
       CallableStatement cstmt =    
                            con.prepareCall("{CALL demoSp(? , ?)}") ;

5.執行SQL語句
·Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate和execute

1.ResultSet executeQuery(String sqlString):執行查詢數據庫的SQL語句,返回一個結果集(ResultSet)對象。   
2.int executeUpdate(String sqlString):用於執行INSERT、UPDATE或   DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等   
3.execute(sqlString):用於執行返回多個結果集、多個更新計數或兩者組合的語句。

·具體實現的代碼:

ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;   
    int rows = stmt.executeUpdate("INSERT INTO ...") ;   
    boolean flag = stmt.execute(String sql) ;

6.處理結果
·兩種狀況:
1.執行更新返回的是本次操做影響到的記錄數。 2.執行查詢返回的結果是一個ResultSet對象。
7.關閉JDBC對象
`操做完成之後要把全部使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲明順序相反:

1.關閉記錄集   
     2.關閉聲明   
     3.關閉鏈接對象
if(rs != null){   // 關閉記錄集   
        try{   
            rs.close() ;   
        }catch(SQLException e){   
            e.printStackTrace() ;   
        }   
          }   
          if(stmt != null){   // 關閉聲明   
        try{   
            stmt.close() ;   
        }catch(SQLException e){   
            e.printStackTrace() ;   
        }   
          }   
          if(conn != null){  // 關閉鏈接對象   
         try{   
            conn.close() ;   
         }catch(SQLException e){   
            e.printStackTrace() ;   
         }   
       }

本週代碼託管截圖

其餘

七週的學習,咱們已經基本學完了Java的基礎知識。可是我知道本身並無掌握好每個點,若是如今讓我獨立去編寫一個程序,極可能依舊會出現不少錯誤和漏洞。
在接下來的學習中,我就要多多實踐,多編寫程序,經過經驗的積累讓本身對Java的理解逐漸深刻。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 200/200 2/2 10/10
第二週 300/500 1/3 16/26
第三週 300/800 1/4 18/44
第四周 300/1100 1/5 18/62
第五週 250/1350 1/6 14/76
第六週 400/1750 2/8 14/90
第七週 300/2050 2/10 10/100
第八週 300/2350 2/12 10/110
第九周 300/2650 3/15 10/120

參考資料

相關文章
相關標籤/搜索