posts - 5,  comments - 0,  trackbacks - 0
           

          一.JDBC原理概述

          1JDBC是一套協議,是JAVA開發人員和數據庫廠商達成的協議,也就是由Sun定義一組接口,由數據庫廠商來實現,并規定了JAVA開發人員訪問數據庫所使用的方法的調用規范。

                2JDBC的實現是由數據庫廠商提供,以驅動程序形式提供。

                3JDBC在使用前要先加載驅動。

                   JDBC對于使用者要有一致性,對不同的數據庫其使用方法都是相同的。

                   driver開發必須要實現Driver接口。

                四種數據庫驅動的實現方式

                JDBC-ODBC橋接式

                JDBC網絡驅動,這種方式是通過中間服務器的協議轉換來實現的

                JDBC+本地驅動,這種方式的安全性比較差

                JDBC驅動,由數據庫廠商實現。

           

          二.JDBCAPI

                java.sql包和javax.sql

                1.Driver接口 代表驅動程序

          2.DriverManager類(驅動管理器),它可以創建連接,它本身就是一個創建Connection的工廠(Factory)

                3.Connection接口,代表數據庫連接,會根據不同的驅動產生不同的連接

                4.Statement接口,執行sql語句

                5. PreparedStatement接口執行sql語句(預編譯)

                6.CallableStatement接口 發送sql語句

                7.ResultSet接口(結果集),是用來接收select語句返回的查尋結果的。其實質類似

          于集合。

                8.DatabaseMetaData  數據庫元數據

                9.ResultSetMetaData   結果集元數據

          10.Types:特殊的類。只包含靜態的常量,代表JDBC類型。JDBC類型是標準SQL類型的子集

          三、事務

                1).原子性,一致性,隔離性,持久性

          事務是一個數據操作單元,能夠保證在該單元內執行的多個SQL語句,或者一起成

          ,或者一起失敗.

                2).事務的并發控制:

                    (dirty)臟讀:一個事務能讀到另外一個事務沒有提交的數據

                    不可重復讀:在同一個事務的兩次查詢中,發現值不同,叫做不可重復讀.這是因為在

          兩次查詢之間,另外一個事務修改了數據并提交了.

                    (phantom)幻影讀:在同一個事務的兩次查詢中,發現記錄的數目不同,叫做幻影讀.

          這是因為在兩次查詢之間,另外一個事務增加或者刪除了數據并提交了.

                3).隔離級別

                   Connection 類中的五個靜態常量

                   A.不使用事務 TRANSACTION_NONE

                 B.允許臟讀    TRANSACTION_READ_UNCOMMITTED

                   C.不允許臟讀  TRANSACTION_READ_COMMITTED

                   D.防止不可重復讀,臟讀 TRANSACTION_REPEATABLE_READ

                   F.事務串行化  TRANSACTION_SERIALIZABLE

          四、JDBC編程步驟

                1,注冊加載一個driver驅動

                2,創建數據庫連接(Connection

                3,創建一個Statement(發送sql

                4,執行sql語句

                5,處理sql結果ResultSetselect語句)

                6,關閉sql結果ResultSet (如果有)

                7,關閉Statement

                8,關閉連接Connection

                注意:678兩個步驟必須要做的,因為這些資源是不會自動釋放的,必須要自己關閉

           

                1,注冊加載驅動driver,也就是強制類加載

                     一般來說我們使用方法1

                     方法1 Class.forName(Driver包名.Driver類名)

                           eg:加載oracle

                           Class.forName("oracle.jdbc.driver.OracleDriver");

                     方法2Driver d=new oracle.jdbc.driver.OracleDriver();

                           DriverManager.registerDriver(d);

                     方法3java -Djdbc.drivers=驅動全名 類名

           

                     OracleDriver的全名:oracle.jdbc.driver.OracleDriver

                     mysqlDriver的全名:com.mysql.jdbc.Driver org.gjt.mm.mysql.Driver

                     SQLServerDriver的全名:com.microsoft.jdbc.sqlserver.SQLServerDriver

                2,創建連接

                     DriverManager.getConnection(String url,String username,String

          password);

                     Connection連接是通過DriverManager的靜態方法getConnection(.....)來得到

          的,這個方法的實質是把參數傳到實際的Driver中的connect()方法中來獲得數

          據庫連接的。

                OracleURL值是由連接數據庫的協議和數據庫的IP地址及端口號還有要連接的

          庫名(DatebaseName

                     Oracle URL的格式

                     jdbc:oracle:thin:@數據庫IP地址:端口號:數據庫名(sid)

                     如:oracle所在服務器地址為192.168.0.254,而端口號為默認的1521,數據

          庫名為tarena,那么URL就應寫成

                     jdbc:oracle:thin:@192.168.0.254:1521:tarena       

                     MySql URL的格式

                     jdbc:mysql://數據庫IP地址:端口號/數據庫名

                     例: jdbc:mysql://localhost:3306/test

                     訪問本機時IP地址用localhost127.0.0.1都可以         

                     SQLServer URL的寫法

                     例:jdbc:microsoft:sqlserver://localhost:1433

                3、創建Statement

                     使用Connection對象獲得一個Statement

                     Statement中的方法:

          1) executeQuery(String sql) 方法可以使用select語句查詢,并且返回一個結

          果集ResultSet,通過遍歷這個ResultSet,可以獲得select語句的查尋結果。

                     ResultSet rs = stmt.executeQuery(“select * from person”);

                     2executeUpdate(String sql) 方法用于執行DDLDML語句,可以update

          delete操作。

                     此方法返回一個int類型的值,表示此條sql語句影響的記錄條數

                     Int count = stmt.executeUpdate(“delete from person where pid=1”);

                     Int count = stmt.executeUpdate(“update person set name=’jack’,age=’20’

          where pid=1”);

                     3execute(String sql) 這個方法的返回值是boolean類型

                     如果返回true就表示sql是一個select語句,然后通過getResultSet()獲得結果

                     如果返回false sql就是DML語句或者是DDL語句,即沒有結果集,

                     然后通過getUpdateCount()方法 獲得更新的記錄條數。

                     在不能明確傳入sql是何種類型的操作時使用此方法。

                     if (stmt.execute(sql)) {

                           ResultSet rs = stmt.getResultSet();

                     } else {

                           int count = stmt.getUpdateCount();

                     }

                     4getUpdateCount() 返回更新的記錄條數

                4.處理結果集ResultSet(結果集里存儲的是二維的結構,相當于一張表)

                     ResultSet rs = stmt.executeQuery(“select pid, name, age from person”);

                     Person person = null;

                     while(rs.next) {

                           person = new Person();

                           person.setPid(rs.getInt(1));//jdbc下標是從1開始

                           person.setName(rs.getString(“name”));//也可使用列名來得到數據

                           person.setAge(rs.getInt(3));

                     }

                     1) next()方法會操作一個游標從第一條記錄的前邊開始讀取,直到最后一條記錄。

                           由于結果集返回來之后游標的位置在第一條記錄的前面,所以調用next()

          法不會丟失數據。

                     2) getXXX(int index)其中XXX代表數據庫中存儲的數據類型相對應的java數據

          類型,

                           此方法可以根據指定順序獲得字段值,注:順序是從1開始的。

                      eg: int cid = rs.getInt(1);

                           String cname = rs.getString(2);

                     3) getXXX(String columnName):此方法可以根據指定字段的名字獲取字段的值

                           eg: int cid = rs.getInt("cid");

                           String cname = rs.getString("cname");

                     4updateXXX() XXX代表的是相應的類型,無返回值

                     5)  isXXXX() XXXX代表的是游標的位置FirstLast。。。返回布爾值

                5.資源的關閉順序:

                     要按先ResultSet結果集,然后Statement,最后Connection的順序關閉資源。

                     因為StatementResultSet是需要連接是才可以使用的,所以在使用結束之后

          有可能起他的Statement還需要連接,

                     所以不能現關閉Connection

                     //關閉結果集

                     if (rs != null) try {rs.close()} catch (SQLException e) { e.printStackTrace();}

                     //關閉Statement

                     if (stmt != null) try { stmt.close()} catch (SQLException e) {

          e.printStackTrace();}

                     //關閉鏈接

                     if (conn != null) try { conn.close()} catch (SQLException e) {

          e.printStackTrace();}

                6.PreparedStatement(預編譯的Statement)

                     PreparedStatement 用來執行同構的SQL,它的創建方式:

                     PreparedStatement pstmt = con.prepareStatement("insert into clazz values(?,?)");

                     可以使用參數替代sql語句中的某些參數使用"?"代替,他先將帶參數的sql語句發送到數據庫,

                     進行編譯,然后PreparedStatement會將參數發送給數據庫。

                     在使用PreparedStatement時,設置相應參數要指明參數的位置和類型,以及給出參數值

                     根據不同的參數類型使用不同的setXXX(參數的位置,參數值)來設置參數

                     結構跟此方法類似:setInt(int parameterIndex, int x)

                     pstmt.setInt(1,i);

                     pstmt.setString(2,"xxx"+i)

                7.CallableStatement

                     CallableStatement是可以用非sql語句來訪問數據庫,他是通過調用存儲過程(PL/SQL)來訪問數據

          庫的。

                     可以直接使用連接來調用 prepareCall(...)方法,來執行這個存儲過程,"..."是存儲過程的名字。

                8.SQLException是檢查異常必須處理,要么throws ,要么try{}catch(){}

                   getErrorCode()可以獲得錯誤碼,可以對錯誤進行查詢。

          五、元數據

                元數據就是描述數據庫或其組成部分的數據。(區別于存儲在數據庫中的實際數據)

                它用來輔助我們更好的處理數據庫的用戶數據[通俗的講就是指容器的結果的信息]

          JDBC中有兩種元數據,一種是數據庫元數據(DatabaseMetaData,另一種是結果集元數據(ResultSetMetaData

                1.數據庫元數據

                     如果要想了解數據庫的更多信息。可以從數據庫連接中獲取一個DatabaseMetaData

                     DatabaseMetaData  dmd=conn.getMetaData();

                     然后可以調用如下的方法獲得數據庫相關的信息

                     getURL(),獲得連接數據庫的URL

                     getDatabaseProductName() 獲得數據庫產品的名稱

                     getDriverVersion() 獲得JDBC驅動程序的String形式的版本號

                     getTables()獲得數據庫中該用戶的所有表

                     getUserName() 獲得數據庫用戶名。

                2.結果集元數據

                     ResultSet rs=ps.executeQuery();

                     ResultSetMetaData m=rs.getMetaData();

                     getColumnCount(),獲得實際列數

                     getColumnName(int colnum),獲得指定列的列名

                     getColumnType(int colnum),獲得指定列的數據類型

                     getColumnTypeName(int colnum),獲得指定列的數據類型名

                例如:ResultSetMetaData md = rs.getMetaData();

                                // 得到字段個數

                                int cols = md.getColumnCount();

                                // 根據字段個數遍歷和打印結果集

                                StringBuffer sb = new StringBuffer();

                                for (int i = 0; i < cols; i++) {

                                      sb.append(md.getColumnName(i + 1) + " ");

                                }

                     動態獲得表結構

           

          六、JDBC2.0新特性

                默認方式獲得的結果集都是1.0的結果集

                能否使用JDBC2.0 ResultSet的新特性要看數據庫驅動程序是否支持。

                1.可滾動結果集(可雙向滾動),(了解 能說出結果集滾動的方法即可)

                     這種結果集不但可以雙向滾動,相對定位,絕對定位,并且可以修改數據信息。

                     要使用可滾動結果集時,要在Statement創建時指定參數,才可以使用

                     Statement st=null;int,int(可滾動特性,可更新特性)

                     st=con.createStatement(ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_UPDATABLE) 

                     PreparedStatement

          ps=con.createPrepareStatement(sql,ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_

          UPDATABLE);

                     ResultSet rs=ps.executeQuery(sql);

                滾動特性

                     next(),此方法是使游標向下一條記錄移動。

                      previous() ,此方法可以使游標向上一條記錄移動,前提前面還有記錄。

                     absolute(int row),絕對定位函數可以使用此方法跳到指定的記錄位置。定位成功返回true,不成功返

          false,返回值為false,則游標不會移動。

                     afterLast() ,游標跳到最后一條記錄 之后,(結果集一回來時就有的位置)。無返回值。

                     beforeFirst() ,游標跳到第一條記錄 之前,(結果集一回來時就有的位置)。(跳到游標初始位)無返回

                     first(),游標指向第一條記錄。

                     last(),有彪指向最后一條記錄。

                     relative(int rows),相對定位方法,參數值可正可負,參數為正,

                     游標從當前位置向下移動指定值,參數為負,游標從當前位置向上移動指定值。

                ResultSet可滾動性的屬性值:

                     TYPE_FORWARD_ONLY ,單向,該常量指示指針只能向前移動的 ResultSet 對象的類型。不可滾動。

                     TYPE_SCROLL_INSENSITIVE ,雙向,對數據庫的變化不敏感

                     TYPE_SCROLL_SENSITIVE ,雙向,對數據庫的變化敏感

                     ResultSet 對象的類型。該特性某些數據庫不支持。

                ResultSet可更新性的屬性值: 

                     CUNCUR_READ_ONLY,不可更新的結果集

                     CUNCUR_UPDATEABLE,可更新的結果集

                2.可更新的結果集:(不常用,也不推薦使用)(了解)

                     如果你想能夠編輯結果集中的數據,并且將結果集上的數據自動反應到數據庫中,

                     那么就必須使用可更新的結果集,可更新結果集不一定是可滾動的,獲得可更新結果集的方法:

                Statement  

          stat=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATE

          ABLE);

                     這樣,調用executeQuery()方法返回的結果集就是可更新的結果集。

                例如:

                     String  query="SELECT *  FROM  books";

                     ResultSet  rs=stat.executeQuery(query);

                     While(rs.next){

                           If(.......){

                                    Double inscrease=.......;

                                    Double  price=rs.getDouble("Price");

                                     rs.updateDouble("Price",price+inscrease);

                                     rs.updateRow();

                         }

                     }

          所有的對應于SQL類型的數據類型都配有updateXXX方法。與getXXX方法類似。使用updateXXX方法是必須指定列的名稱或序列號。

                然后,可以給 該字段設置新的值。

                updateXXX方法改變的只是結果集中的行值,而非數據庫中的值。當更新完行中的字段值后,必須調用

          updateRow方法,這個方法將當前的行中所有更新信息發送給數據庫。如果沒有調用updateRow方法就將

          游標移動到其他行上。那么所以的更新信息就將被丟棄,而且永遠不會被傳遞給數據庫。還可以調用cancelRowUpates方法來取消對當前行的更新。

                以上是更新數據庫中的一行記錄,如果想在數據庫中添加一條新的記錄,首先需要使用moveToInsertRow

          ()方法將游標移動到特定的位置。然后調用updateXXX()方法在插入行的位置上創建一個新的行。然后調用

          insertRow()方法將新建的行發送給數據庫。完成插入操作后在調用moveToCurrentRow()方法講游標移回到調用moveToInsertRow方法之前的位置:

                例子:

                     rs.moveToInsertRow();

                     rs.updateString("Title",title);

                     rs.updateString("Price",price);

                     ..........

                     rs.insertRow();

                     rs.moveToCurrentRow();

                如果要刪除一行調用rs.deleteRow()即可刪除結果集和數據庫中的一行

                能否使用可更新結果集,要看使用的數據庫驅動是否支持,還有只能用于單表且表中有主鍵字段(可能會是

          聯合主鍵),不能夠有表連接,會取所有非空字段且沒有默認值。結果集用select * from t也不行,不能用

          *,不能排序

                3,批處理更新 (熟記于心)

                     Statement.

                     addBatch(String sql) 方法會在批處理緩存中加入一條sql語句

                     executeBatch() ,執行批處理緩存中的所有sql語句。

                     PreparedStatement.   先準備一組參數

                     addBatch() 將一組參數添加到此 PreparedStatement 對象的批處理命令中。

                     executeBatch() 將一批命令提交給數據庫來執行,如果全部命令執行成功,則返回更新計數組成的數組。

                     PreparedStatement中使用批量更新時,要先設置好參數后使用addBatch()方法加入緩存。

                     注意:批量更新中用更新或插入語句

          面向對象的數據庫設計

           

          Id通常是用來表示記錄的唯一性的,通常會使用業務無關的數字類型

          Object id 對象的idsequence只有Oracle才可用,對象idOID)使用高低位算法先生成高位,在生成低位,通過運算獲得對象id

          類應當對象到表,屬性對應字段,對象對應記錄。

           

          類繼承關系對應表,

          1,每個類建一個表,為父子類每個類都對應的創建表,這種方法類關系清晰,但是如果類比較多就不適合了

          2,只有具體類才建表,也就是把父類中的屬性均勻分配到子類的表中,也就是父類不建表,這種表關系不能使用多態

          3,所有類對應一張表,這種方法是在表中加上一個字段來區分父子類,但是只能用于類屬性較少的情況下,而且數據會有冗余。

           

          類關聯關系對應表

          1,一對一關聯,類關系對應成表時有兩種做法,一是引用主鍵,也就是一方引用另一方的主鍵既作為外鍵又作為自身的主鍵。

                二是外鍵引用,一方引用另一方的主鍵作為自身的外鍵,并且自己擁有主鍵。

          2,一對多關聯,也就是多端引用一端的主鍵當作外鍵,多端自身擁有主鍵。

          3,多對多關系,多對多關系是通過中間表來實現的,中間表引用兩表的主鍵當作聯合主鍵,就可以實現多對多關聯。

           

           

          posted on 2009-03-31 19:41 faye 閱讀(711) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 乳山市| 平顶山市| 赤壁市| 巴青县| 漠河县| 宿州市| 都江堰市| 循化| 宕昌县| 社会| 安西县| 辽阳县| 宁夏| 固阳县| 九江市| 宁河县| 泸溪县| 磐石市| 浏阳市| 元江| 阳山县| 五河县| 府谷县| 磐石市| 阳江市| 台南市| 开原市| 阜宁县| 湖口县| 万载县| 商河县| 海晏县| 屯门区| 平凉市| 星座| 天等县| 郸城县| 平定县| 河津市| 湟源县| 漯河市|