JSP數(shù)據(jù)庫操作詳解_第1頁
JSP數(shù)據(jù)庫操作詳解_第2頁
JSP數(shù)據(jù)庫操作詳解_第3頁
JSP數(shù)據(jù)庫操作詳解_第4頁
JSP數(shù)據(jù)庫操作詳解_第5頁
已閱讀5頁,還剩92頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

七JSP數(shù)據(jù)庫操作7.1數(shù)據(jù)庫技術(shù)概論什么是數(shù)據(jù)庫?通俗地說,數(shù)據(jù)庫就是用于集中存放大量信息的一種軟件,這種軟件提供了非常強大的功能來管理數(shù)據(jù),如信息的查詢、修改、增加、刪除等。數(shù)據(jù)庫是非常復(fù)雜的軟件系統(tǒng),其復(fù)雜程度甚至可比操作系統(tǒng)。將實現(xiàn)數(shù)據(jù)庫功能的軟件稱為DBMS(DatabaseManagementSystem,數(shù)據(jù)庫管理系統(tǒng))。3數(shù)據(jù)庫的組織結(jié)構(gòu)數(shù)據(jù)庫表記錄字段4數(shù)據(jù)庫表間的關(guān)聯(lián)關(guān)系表之間的關(guān)聯(lián)是現(xiàn)實生活中事物之間關(guān)聯(lián)關(guān)系的模擬。主鍵外鍵5在實際的數(shù)據(jù)庫設(shè)計中,經(jīng)常使用“自增字段”來作為表的主鍵。7.2結(jié)構(gòu)化查詢語言SQL什么是SQLSQL(StructuredQueryLanguage,結(jié)構(gòu)化查詢語言),使用它來從數(shù)據(jù)庫中提取并操作各種數(shù)據(jù)。7SQL命令的分類SQL命令可以分成以下三類:DML(DataManipulationLanguage,數(shù)據(jù)操作語言):用于檢索或修改數(shù)據(jù)。DDL(DataDefinitionLanguage,數(shù)據(jù)定義語言):用于定義數(shù)據(jù)的結(jié)構(gòu),例如,創(chuàng)建、修改或刪除數(shù)據(jù)庫對象。DCL(DataControlLanguage,數(shù)據(jù)控制語言):用于定義數(shù)據(jù)庫用戶的權(quán)限。8常用的SQL命令Select:選擇數(shù)據(jù)Insert:插入數(shù)據(jù)Update:更新數(shù)據(jù)Delete:刪除數(shù)據(jù)9例:使用SSME執(zhí)行SQL命令使用“新建查詢”命令,在“查詢”面板中書寫SQL命令。10書寫完SQL命令之后,可以先檢查語法,然后再執(zhí)行。檢查語法執(zhí)行SQL命令I(lǐng)nsert:插入數(shù)據(jù)命令格式:

insertinto表名(列名列表)values(值列表)實例:11useClients--指明數(shù)據(jù)庫 insertintoOrderClient(

ClientName,AddressStr,PostCode,Telephone,Email) Values('張三','某省某市某街道某某號', '100081','12345678','SomeOne@');Update:更新數(shù)據(jù)基本格式

update表名set字段名=“字段新值”where滿足條件實例12updateOrderClient setAddressStr='無有國烏有省沒有市虛空街' WhereClientName='張三';Delete:刪除數(shù)據(jù)格式:

deletefrom表名where滿足條件實例:deletefromOrderClientwhereClientName='張三';13Select:選擇數(shù)據(jù)這是最靈活的SQL命令,有許多用法,最基本的格式為:

select表名.列名from表名列表where滿足條件上述基本格式還有許多變化,例如可以使用select命令進行排序和分組等。14三種基本關(guān)系數(shù)據(jù)操作選擇:用于選中滿足某種條件的數(shù)據(jù)

select*fromOrderClientwhereClientNameLike'張%'投影:只顯示記錄中的部分字段selectClientName,AddressStrfromOrderClient連接:從兩個以上的表中提取記錄注意:三種操作可以自由組合15useHappyBookShopselectBook.BookName,BookRemark.RemarkContentfromBook,BookRemarkwhereBook.BookID=BookRemark.BookIDAndBook.BookName='編程之美:微軟技術(shù)面試心得'視圖視圖是一個虛擬表,可以與真實的表一樣使用。其不同之處在于:它的數(shù)據(jù)是在使用時臨時通過執(zhí)行SQL命令獲取的。基本格式:createview視圖名稱asseletct語句實例:16CreateviewBookNameAndBookRemarkasselectBook.BookName,BookRemark.RemarkContentfromBook,BookRemarkwhereBook.BookID=BookRemark.BookID

使用視圖視圖可以當(dāng)成一個表一樣用。實例:17usehappybookshopselect*fromBookNameAndBookRemark存儲過程存儲過程類似于傳統(tǒng)編程語言中的“函數(shù)”。它是一組SQL命令的集合?;靖袷剑篶reateprocedure存儲過程名(參數(shù)列表)asbegin --各種SQL語句end;18創(chuàng)建存儲過程示例:在Clients數(shù)據(jù)庫中創(chuàng)建存儲過程19createprocedureFindCustomerInfo( @FirstNameVARCHAR(20)=NULL)asbegin select*fromOrderClientwhereClientNamelike'%'+@FirstName+'%';end;執(zhí)行存儲過程使用exec命令執(zhí)行存儲過程實例:

execFindCustomerInfo'張'20統(tǒng)計數(shù)據(jù):使用聚集函數(shù)所謂“聚集函數(shù)”,其實就是對一組記錄進行統(tǒng)計的一些函數(shù):21常用的聚集函數(shù)MIN返回一個給定列中最小的數(shù)值MAX返回一個給定列中最大的數(shù)值SUM返回一個給定列中所有數(shù)值的總和AVG返回一個給定列中所有數(shù)值的平均值COUNT返回一個給定列中所有數(shù)值的個數(shù)COUNT(*)返回一個表中的行數(shù)22聚集函數(shù)使用示例——統(tǒng)計姓張的客戶數(shù)量selectcount(*)fromorderClientwhereClientNameLike'張'+'%';7.3JDBC概述23

JDBC是用于執(zhí)行SQL語句的API類包,由一組用Java語言編寫的類和接口組成。JDBC提供了一種標(biāo)準(zhǔn)的應(yīng)用程序設(shè)計接口,通過它可以訪問各類關(guān)系數(shù)據(jù)庫。7.3JDBC概述25JDBC的全稱為JavaDataBaseConnectivity,是一套面向?qū)ο蟮膽?yīng)用程序接口(API),制定了統(tǒng)一的訪問各類關(guān)系數(shù)據(jù)庫的標(biāo)準(zhǔn)接口,為各個數(shù)據(jù)庫廠商提供了標(biāo)準(zhǔn)接口的實現(xiàn)。通過JDBC技術(shù),開發(fā)人員可以用純Java語言和標(biāo)準(zhǔn)的SQL語句編寫完整的數(shù)據(jù)庫應(yīng)用程序,并且真正地實現(xiàn)了軟件的跨平臺性。在JDBC技術(shù)問世之前,各家數(shù)據(jù)庫廠商執(zhí)行各自的一套API,使得開發(fā)人員訪問數(shù)據(jù)庫非常困難,特別是在更換數(shù)據(jù)庫時,需要修改大量代碼,十分不方便。JDBC很快就成為了Java訪問數(shù)據(jù)庫的標(biāo)準(zhǔn)。26JDBC是一種底層API,在訪問數(shù)據(jù)庫時需要在業(yè)務(wù)邏輯中直接嵌入SQL語句。由于SQL語句是面向關(guān)系的,依賴于關(guān)系模型,所以JDBC傳承了簡單直接的優(yōu)點,特別是對于小型應(yīng)用程序十分方便。

需要注意的是,JDBC不能直接訪問數(shù)據(jù)庫,必須依賴于數(shù)據(jù)庫廠商提供的JDBC驅(qū)動程序,通常情況下使用JDBC完成以下操作:(1)同數(shù)據(jù)庫建立連接;(2)向數(shù)據(jù)庫發(fā)送SQL語句;(3)處理從數(shù)據(jù)庫返回的結(jié)果。27數(shù)據(jù)庫數(shù)據(jù)庫數(shù)據(jù)庫OracleDriverJDBC-ODBCBridgeMySQLDriverDriver驅(qū)動程序管理器(DrvierManager)ConnectionPreparedStatementStatementCallableStatement結(jié)果集(ResultSet)結(jié)果集(ResultSet)結(jié)果集(ResultSet)應(yīng)用層驅(qū)動程序?qū)?.4JDBC的常用接口287.4JDBC中的常用接口

驅(qū)動程序接口Driver

驅(qū)動程序管理器DriverManager

數(shù)據(jù)庫連接接口Connection

執(zhí)行SQL語句接口Statement

執(zhí)行動態(tài)SQL語句接口PreparedStatement

執(zhí)行存儲過程接口CallableStatement

訪問結(jié)果集接口ResultSet30

每種數(shù)據(jù)庫的驅(qū)動程序都應(yīng)該提供一個實現(xiàn)java.sql.Driver接口的類,簡稱Driver類,在加載Driver類時,應(yīng)該創(chuàng)建自己的實例并向java.sql.DriverManager類注冊該實例。通常情況下通過java.lang.Class類的靜態(tài)方法forName(StringclassName),加載要連接數(shù)據(jù)庫的Driver類,該方法的入口參數(shù)為要加載Driver類的完整包名。成功加載后,會將Driver類的實例注冊到DriverManager類中,如果加載失敗,將拋出ClassNotFoundException異常,即未找到指定Driver類的異常。7.4.1驅(qū)動程序接口Driver31java.sql.DriverManager類負(fù)責(zé)管理JDBC驅(qū)動程序的基本服務(wù),是JDBC的管理層,作用于用戶和驅(qū)動程序之間,負(fù)責(zé)跟蹤可用的驅(qū)動程序,并在數(shù)據(jù)庫和驅(qū)動程序之間建立連接。另外,DriverManager類也處理諸如驅(qū)動程序登錄時間限制及登錄和跟蹤消息的顯示等工作。成功加載Driver類并在DriverManager類中注冊后,DriverManager類即可用來建立數(shù)據(jù)庫連接。7.4.2驅(qū)動程序管理器DriverManager32

當(dāng)調(diào)用DriverManager類的getConnection()方法請求建立數(shù)據(jù)庫連接時,DriverManager類將試圖定位一個適當(dāng)?shù)腄river類,并檢查定位到的Driver類是否可以建立連接。如果可以,則建立連接并返回,如果不可以,則拋出SQLException異常。getConnection()方法有以下3種不同的函數(shù)重載形式:staticConnectiongetConnection(Stringurl)和一個通過URL指定的數(shù)據(jù)庫建立連接。33staticConnectiongetConnection(Stringurl,Propertiesinfo)和一個通過URL指定的數(shù)據(jù)庫建立連接,info提供了一些屬性,這些屬性里包括了user和password等屬性。staticConnectiongetConnection(Stringurl,Stringuser,Stringpassword)傳入?yún)?shù)用戶名為user,密碼為password,和一個通過URL指定的數(shù)據(jù)庫建立連接。URL的格式為:jdbc:subprotocol:subname34方法名稱功能描述getConnection(Stringurl,Stringuser,Stringpassword)為靜態(tài)方法,用來獲得數(shù)據(jù)庫連接,有3個入口參數(shù),依次為要連接數(shù)據(jù)庫的URL、用戶名和密碼,返回值類型為java.sql.ConnectionsetLoginTimeout(intseconds)為靜態(tài)方法,用來設(shè)置每次等待建立數(shù)據(jù)庫連接的最長時間setLogWriter(java.io.PrintWriterout)為靜態(tài)方法,用來設(shè)置日志的輸出對象println(Stringmessage)為靜態(tài)方法,用來輸出指定消息到當(dāng)前的JDBC日志流Stringurl=“jdbc:mysql://localhost/test?user=root&password=123456”;35java.sql.Connection接口負(fù)責(zé)與特定數(shù)據(jù)庫的連接,在連接的上下文中可以執(zhí)行SQL語句并返回結(jié)果,還可以通過getMetaData()方法獲得由數(shù)據(jù)庫提供的相關(guān)信息,例如數(shù)據(jù)表、存儲過程和連接功能等信息。7.4.3數(shù)據(jù)庫連接接口Connection方法名稱功能描述createStatement()創(chuàng)建并返回一個Statement實例,通常在執(zhí)行無參數(shù)的SQL語句時創(chuàng)建該實例prepareStatement()創(chuàng)建并返回一個PreparedStatement實例,通常在執(zhí)行包含參數(shù)的SQL語句時創(chuàng)建該實例,并對SQL語句進行了預(yù)編譯處理36方法名稱功能描述prepareCall()創(chuàng)建并返回一個CallableStatement實例,通常在調(diào)用數(shù)據(jù)庫存儲過程時創(chuàng)建該實例setAutoCommit()設(shè)置當(dāng)前Connection實例的自動提交模式,默認(rèn)為true,即自動將更改同步到數(shù)據(jù)庫中,如果設(shè)為false,需要通過執(zhí)行commit()或rollback()方法手動將更改同步到數(shù)據(jù)庫中g(shù)etAutoCommit()查看當(dāng)前的Connection實例是否處于自動提交模式,如果是則返回true,否則返回falsesetSavepoint()在當(dāng)前事務(wù)中創(chuàng)建并返回一個Savepoint實例,前提條件是當(dāng)前的Connection實例不能處于自動提交模式,否則將拋出異常releaseSavepoint()從當(dāng)前事務(wù)中移除指定的Savepoint實例37setReadOnly()設(shè)置當(dāng)前Connection實例的讀取模式,默認(rèn)為非只讀模式,不能在事務(wù)當(dāng)中執(zhí)行該操作,否則將拋出異常,有一個boolean型的入口參數(shù),設(shè)為true則表示開啟只讀模式,設(shè)為false則表示關(guān)閉只讀模式isReadOnly()查看當(dāng)前的Connection實例是否為只讀模式,如果是則返回true,否則返回falseisClosed()查看當(dāng)前的Connection實例是否被關(guān)閉,如果被關(guān)閉則返回true,否則返回falsecommit()將從上一次提交或回滾以來進行的所有更改同步到數(shù)據(jù)庫,并釋放Connection實例當(dāng)前擁有的所有數(shù)據(jù)庫鎖定rollback()取消當(dāng)前事務(wù)中的所有更改,并釋放當(dāng)前Connection實例擁有的所有數(shù)據(jù)庫鎖定;該方法只能在非自動提交模式下使用,如果在自動提交模式下執(zhí)行該方法,將拋出異常;有一個入口參數(shù)為Savepoint實例的重載方法,用來取消Savepoint實例之后的所有更改,并釋放對應(yīng)的數(shù)據(jù)庫鎖定close()立即釋放Connection實例占用的數(shù)據(jù)庫和JDBC資源,即關(guān)閉數(shù)據(jù)庫連接38

java.sql.Statement接口用來執(zhí)行靜態(tài)的SQL語句,并返回執(zhí)行結(jié)果。例如,對于insert、update和delete語句,調(diào)用executeUpdate(Stringsql)方法,而select語句則調(diào)用executeQuery(Stringsql)方法,并返回一個永遠(yuǎn)不能為null的ResultSet實例。7.4.4執(zhí)行SQL語句接口Statement39方法名稱功能描述executeQuery(Stringsql)執(zhí)行指定的靜態(tài)SELECT語句,并返回一個永遠(yuǎn)不能為null的ResultSet實例executeUpdate(Stringsql)執(zhí)行指定的靜態(tài)INSERT、UPDATE或DELETE語句,并返回一個int型數(shù)值,為同步更新記錄的條數(shù)clearBatch()清除位于Batch中的所有SQL語句,如果驅(qū)動程序不支持批量處理將拋出異常addBatch(Stringsql)將指定的SQL命令添加到Batch中,String型入口參數(shù)通常為靜態(tài)的INSERT或UPDATE語句,如果驅(qū)動程序不支持批量處理將拋出異常40方法名稱功能描述executeBatch()執(zhí)行Batch中的所有SQL語句,如果全部執(zhí)行成功,則返回由更新計數(shù)組成的數(shù)組,數(shù)組元素的排序與SQL語句的添加順序?qū)?yīng)數(shù)組元素有以下幾種情況:①大于或等于零的數(shù),說明SQL語句執(zhí)行成功,為影響數(shù)據(jù)庫中行數(shù)的更新計數(shù);②2,說明SQL語句執(zhí)行成功,但未得到受影響的行數(shù);③3,說明SQL語句執(zhí)行失敗,僅當(dāng)執(zhí)行失敗后繼續(xù)執(zhí)行后面的SQL語句時出現(xiàn)。如果驅(qū)動程序不支持批量,或者未能成功執(zhí)行Batch中的SQL語句之一,將拋出異常close()立即釋放Statement實例占用的數(shù)據(jù)庫和JDBC資源,即關(guān)閉Statement實例41

java.sql.PreparedStatement接口繼承于Statement接口,是Statement接口的擴展,用來執(zhí)行動態(tài)的sql語句,即包含參數(shù)的SQL語句。通過PreparedStatement實例執(zhí)行的動態(tài)SQL語句,將被預(yù)編譯并保存到PreparedStatement實例中,從而可以反復(fù)并且高效地執(zhí)行該SQL語句。

需要注意的是,在通過setXxx()方法為SQL語句中的參數(shù)賦值時,必須通過與輸入?yún)?shù)的已定義SQL類型兼容的方法,也可以通過setObject()方法設(shè)置各種類型的輸入?yún)?shù)。7.4.5執(zhí)行動態(tài)SQL語句接口PreparedStatement42PreparedStatement的使用方法如下:PreparedStatementps=connection .prepareStatement("select*fromtable_namewhereid>?and(name=?orname=?)");ps.setInt(1,1);ps.setString(2,"wgh");ps.setObject(3,"sk");ResultSetrs=ps.executeQuery();43方法名稱功能描述executeQuery()執(zhí)行前面包含參數(shù)的動態(tài)SELECT語句,并返回一個永遠(yuǎn)不能為null的ResultSet實例executeUpdate()執(zhí)行前面包含參數(shù)的動態(tài)INSERT、UPDATE或DELETE語句,并返回一個int型數(shù)值,為同步更新記錄的條數(shù)clearParameters()清除當(dāng)前所有參數(shù)的值setXxx()為指定參數(shù)設(shè)置Xxx型值close()立即釋放Statement實例占用的數(shù)據(jù)庫和JDBC資源,即關(guān)閉Statement實例44java.sql.CallableStatement接口繼承于PreparedStatement接口,是PreparedStatement接口的擴展,用來執(zhí)行SQL的存儲過程。

JDBCAPI定義了一套存儲過程SQL轉(zhuǎn)義語法,該語法允許對所有RDBMS通過標(biāo)準(zhǔn)方式調(diào)用存儲過程。該語法定義了兩種形式,分別是包含結(jié)果參數(shù)和不包含結(jié)果參數(shù)。如果使用結(jié)果參數(shù),則必須將其注冊為OUT型參數(shù),參數(shù)是根據(jù)定義位置按順序引用的,第一個參數(shù)的索引為1。7.4.6執(zhí)行存儲過程接口CallableStatement45

為參數(shù)賦值的方法使用從PreparedStatement中繼承來的setXxx()方法。在執(zhí)行存儲過程之前,必須注冊所有OUT參數(shù)的類型;它們的值是在執(zhí)行后通過getXxx()方法檢索的。

CallableStatement可以返回一個或多個ResultSet實例。處理多個ResultSet對象的方法是從Statement中繼承來的。46java.sql.ResultSet接口類似于一個數(shù)據(jù)表,通過該接口的實例可以獲得檢索結(jié)果集,以及對應(yīng)數(shù)據(jù)表的相關(guān)信息,例如列名和類型等,ResultSet實例通過執(zhí)行查詢數(shù)據(jù)庫的語句生成。7.4.7訪問結(jié)果集接口ResultSet47

ResultSet實例具有指向其當(dāng)前數(shù)據(jù)行的指針。最初,指針指向第一行記錄的前方,通過next()方法可以將指針移動到下一行,因為該方法在沒有下一行時將返回false,所以可以通過while循環(huán)來迭代ResultSet結(jié)果集。在默認(rèn)情況下ResultSet對象不可以更新,只有一個可以向前移動的指針,因此,只能迭代它一次,并且只能按從第一行到最后一行的順序進行。如果需要,可以生成可滾動和可更新的ResultSet對象。48ResultSet接口提供了從當(dāng)前行檢索不同類型列值的getXxx()方法,均有兩個重載方法,可以通過列的索引編號或列的名稱檢索,通過列的索引編號較為高效,列的索引編號從1開始。對于不同的getXxx()方法,JDBC驅(qū)動程序嘗試將基礎(chǔ)數(shù)據(jù)轉(zhuǎn)換為與getXxx()方法相應(yīng)的Java類型,并返回適當(dāng)?shù)腏ava類型的值。49

在JDBC2.0API(JDK1.2)之后,為該接口添加了一組更新方法updateXxx(),均有兩個重載方法,可以通過列的索引編號或列的名稱指定列,用來更新當(dāng)前行的指定列,或者初始化要插入行的指定列,但是該方法并未將操作同步到數(shù)據(jù)庫,需要執(zhí)行updateRow()或insertRow()方法完成同步操作。方法名稱功能描述first()移動指針到第一行;如果結(jié)果集為空則返回false,否則返回true;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常last()移動指針到最后一行;如果結(jié)果集為空則返回false,否則返回true;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常50方法名稱功能描述previous()移動指針到上一行;如果存在上一行則返回true,否則返回false;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常next()移動指針到下一行;指針最初位于第一行之前,第一次調(diào)用該方法將移動到第一行;如果存在下一行則返回true,否則返回falsebeforeFirst()移動指針到ResultSet實例的開頭,即第一行之前;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常afterLast()移動指針到ResultSet實例的末尾,即最后一行之后;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常absolute()移動指針到指定行;有一個int型入口參數(shù),正數(shù)表示從前向后編號,負(fù)數(shù)表示從后向前編號,編號均從1開始;如果存在指定行則返回true,否則返回false;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常51方法名稱功能描述relative()移動指針到相對于當(dāng)前行的指定行;有一個int型入口參數(shù),正數(shù)表示向后移動,負(fù)數(shù)表示向前移動,視當(dāng)前行為0;如果存在指定行則返回true,否則返回false;如果結(jié)果集類型為TYPE_FORWARD_ONLY將拋出異常getRow()查看當(dāng)前行的索引編號;索引編號從1開始,如果位于有效記錄行上則返回一個int型索引編號,否則返回0findColumn()查看指定列名的索引編號;該方法有一個String型入口參數(shù),為要查看列的名稱,如果包含指定列,則返回int型索引編號,否則將拋出異常isBeforeFirst()查看指針是否位于ResultSet實例的開頭,即第一行之前,如果是則返回true,否則返回false52方法名稱功能描述isAfterLast()查看指針是否位于ResultSet實例的末尾,即最后一行之后,如果是則返回true,否則返回falseisFirst()查看指針是否位于ResultSet實例的第一行,如果是則返回true,否則返回falseisLast()查看指針是否位于ResultSet實例的最后一行,如果是則返回true,否則返回falseclose()立即釋放ResultSet實例占用的數(shù)據(jù)庫和JDBC資源,當(dāng)關(guān)閉所屬的Statement實例時也將執(zhí)行此操作7.5連接數(shù)據(jù)庫5354

在對數(shù)據(jù)庫進行操作時,首先需要連接數(shù)據(jù)庫,在JSP中連接數(shù)據(jù)庫大致可以分加載JDBC驅(qū)動程序、創(chuàng)建Connection對象的實例、執(zhí)行SQL語句、獲得查詢結(jié)果和關(guān)閉連接等5個步驟。7.5連接數(shù)據(jù)庫

加載JDBC驅(qū)動程序創(chuàng)建數(shù)據(jù)庫連接執(zhí)行SQL語句獲得查詢結(jié)果關(guān)閉連接55try{

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");}catch(ClassNotFoundExceptione){

System.out.println("加載數(shù)據(jù)庫驅(qū)動時拋出異常,內(nèi)容如下:");

e.printStackTrace();}

在連接數(shù)據(jù)庫之前,首先要加載要連接數(shù)據(jù)庫的驅(qū)動到JVM(Java虛擬機),通過java.lang.Class類的靜態(tài)方法forName(StringclassName)實現(xiàn)。例如加載SQLServer2000驅(qū)動程序的代碼為:7.5.1加載JDBC驅(qū)動程序56

成功加載后,會將加載的驅(qū)動類注冊給DriverManager類,如果加載失敗,將拋出ClassNotFoundException異常,即未找到指定的驅(qū)動類,所以需要在加載數(shù)據(jù)庫驅(qū)動類時捕捉可能拋出的異常。技巧:通常將負(fù)責(zé)加載驅(qū)動的代碼放在static塊中,這樣做的好處是只有static塊所在的類第一次被加載時才加載數(shù)據(jù)庫驅(qū)動,避免重復(fù)加載驅(qū)動程序,浪費計算機資源。57Connectionconn=DriverManager.getConnection("jdbc:microsoft:sqlserver://:1433;DatabaseName=db_database08","sa","");

java.sql.DriverManager(驅(qū)動程序管理器)類是JDBC的管理層,負(fù)責(zé)建立和管理數(shù)據(jù)庫連接。通過DriverManager類的靜態(tài)方法getConnection(Stringurl,Stringuser,Stringpassword)可以建立數(shù)據(jù)庫連接,3個入口參數(shù)依次為要連接數(shù)據(jù)庫的路徑、用戶名和密碼,該方法的返回值類型為java.sql.Connection。

典型代碼如下:7.5.2創(chuàng)建數(shù)據(jù)庫連接58

建立數(shù)據(jù)庫連接(Connection)的目的是與數(shù)據(jù)庫進行通信,實現(xiàn)方式為執(zhí)行SQL語句,但是通過Connection實例并不能執(zhí)行SQL語句,還需要通過Connection實例創(chuàng)建Statement實例。

Statement實例又分為以下3種類型。Statement實例:該類型的實例只能用來執(zhí)行靜態(tài)的SQL語句;

PreparedStatement實例:該類型的實例增加了執(zhí)行動態(tài)SQL語句的功能;

CallableStatement對象:該類型的實例增加了執(zhí)行數(shù)據(jù)庫存儲過程的功能。7.5.3執(zhí)行SQL語句59

通過Statement接口的executeUpdate()或executeQuery()方法,可以執(zhí)行SQL語句,同時將返回執(zhí)行結(jié)果。如果執(zhí)行的是executeUpdate()方法,將返回一個int型數(shù)值,代表影響數(shù)據(jù)庫記錄的條數(shù),即插入、修改或刪除記錄的條數(shù);如果執(zhí)行的是executeQuery()方法,將返回一個ResultSet型的結(jié)果集,其中不僅包含所有滿足查詢條件的記錄,還包含相應(yīng)數(shù)據(jù)表的相關(guān)信息,例如,列的名稱、類型和列的數(shù)量等。7.5.4獲得查詢結(jié)果resultSet.close();statement.close();connection.close();

在建立Connection,Statement和ResultSet實例時,均需占用一定的數(shù)據(jù)庫和JDBC資源,所以每次訪問數(shù)據(jù)庫結(jié)束后,應(yīng)該及時銷毀這些實例,釋放它們占用的所有資源。方法是通過各個實例的close()方法,并且在關(guān)閉時建議按照以下的順序:7.5.5關(guān)閉連接61

采用上面的順序關(guān)閉的原因在于Connection是一個接口,close()方法的實現(xiàn)方式可能多種多樣。如果是通過DriverManager類的getConnection()方法得到的Connection實例,在調(diào)用close()方法關(guān)閉Connection實例時會同時關(guān)閉Statement實例和ResultSet實例。62

但是通常情況下需要采用數(shù)據(jù)庫連接池,在調(diào)用通過連接池得到的Connection實例的close()方法時,Connection實例可能并沒有被釋放,而是被放回到了連接池中,又被其他連接調(diào)用,在這種情況下如果不手動關(guān)閉Statement實例和ResultSet實例,它們在Connection中可能會越來越多,雖然JVM的垃圾回收機制會定時清理緩存,但是如果清理得不及時,當(dāng)數(shù)據(jù)庫連接達到一定數(shù)量時,將嚴(yán)重影響數(shù)據(jù)庫和計算機的運行速度,甚至導(dǎo)致軟件或系統(tǒng)癱瘓。7.6典型JSP數(shù)據(jù)庫連接63647.6典型JSP數(shù)據(jù)庫連接SQLServer2000數(shù)據(jù)庫的連接

Access數(shù)據(jù)庫的連接

MySQL數(shù)據(jù)庫的連接7.6.1SQLServer2000數(shù)據(jù)庫的連接StringdriverClass="com.microsoft.jdbc.sqlserver.SQLServerDriver";SQLServer2000數(shù)據(jù)庫的驅(qū)動為:65

連接SQLServer2000數(shù)據(jù)庫需要用到的包有msbase.jar,mssqlserver.jar和msutil.jar。

連接SQLServer2000數(shù)據(jù)庫的URL為:Stringurl="jdbc:microsoft:sqlserver://:1433;DatabaseName=db_database08";667.6.2Access數(shù)據(jù)庫的連接StringdriverClass="sun.jdbc.odbc.JdbcOdbcDriver";Access數(shù)據(jù)庫的驅(qū)動為:

連接Access數(shù)據(jù)庫需要通過JDBC-ODBC方式,不需要引入任何包。連接Access數(shù)據(jù)庫的URL為:Stringurl="jdbc:odbc:driver={MicrosoftAccessDriver(*.mdb)};DBQ=E:/db_database08.mdb";67

由于在上面的URL中采用的是系統(tǒng)默認(rèn)的連接Access數(shù)據(jù)庫的驅(qū)動MicrosoftAccessDriver(*.mdb),所以不需要手動配置ODBC驅(qū)動;“E:/db_database08.mdb”為Access數(shù)據(jù)庫的絕對存放路徑,在實際程序中,可以通過request對象的相關(guān)方法獲取數(shù)據(jù)庫文件的存放路徑。687.6.3MySQL數(shù)據(jù)庫的連接StringdriverClass="com.mysql.jdbc.Driver";MySQL數(shù)據(jù)庫的驅(qū)動為:

連接MySQL數(shù)據(jù)庫需要用到的包為mysql-connector-java-3.0.16-ga-bin.jar。連接MySQL數(shù)據(jù)庫的URL為:Stringurl="jdbc:mysql://:3306/db_database08";7.7數(shù)據(jù)庫操作技術(shù)6970

在開發(fā)Web應(yīng)用程序時,經(jīng)常需要對數(shù)據(jù)庫進行操作,最常用的數(shù)據(jù)庫操作技術(shù),包括向數(shù)據(jù)庫查詢、添加、修改或刪除數(shù)據(jù)庫中的數(shù)據(jù),這些操作即可以通過靜態(tài)的SQL語句實現(xiàn),也可以通過動態(tài)的SQL語句實現(xiàn),還可以通過存儲過程實現(xiàn),具體采用的實現(xiàn)方式要根據(jù)實際情況而定。7.7數(shù)據(jù)庫操作技術(shù)

查詢操作添加操作修改操作刪除操作71JDBC中提供了兩種實現(xiàn)數(shù)據(jù)查詢的方法,一種是通過Statement對象執(zhí)行靜態(tài)的SQL語句實現(xiàn);另一種是通過PreparedStatement對象執(zhí)行動態(tài)的SQL語句實現(xiàn)。由于PreparedStatement類是Statement類的擴展,一個PreparedStatement對象包含一個預(yù)編譯的SQL語句,該SQL語句可能包含一個或多個參數(shù),這樣應(yīng)用程序可以動態(tài)地為其賦值,所以PreparedStatement對象執(zhí)行的速度比Statement對象快。因此在執(zhí)行較多的SQL語句時,建議使用PreparedStatement對象。7.7.1查詢操作72try{Statementsql=con.createStatement();ResultSetrs=sql.executeQuery(“SELECT*FROM表名”);}catch(SQLExceptione){System.out.println(e);}try{PrepareStatementsql=con.prepareStatement(“SELECT*FROM表名”);ResultSetrs=sql.executeQuery();}catch(SQLExceptione){System.out.println(e);}73

通過Statement對象和PreparedStatement對象實現(xiàn)數(shù)據(jù)添加操作的方法同實現(xiàn)查詢操作的方法基本相同,所不同的就是執(zhí)行的SQL語句及執(zhí)行方法不同,實現(xiàn)數(shù)據(jù)添加操作時采用的是executeUpdate()方法,而實現(xiàn)數(shù)據(jù)查詢時使用的是executeQuery()方法。實現(xiàn)數(shù)據(jù)添加操作使用的SQL語句為INSERT語句,其語法格式如下:Insert[INTO]table_name[(column_list)]values(data_values)JDBC中也提供了兩種實現(xiàn)數(shù)據(jù)添加操作的方法,一種是通過Statement對象執(zhí)行靜態(tài)的SQL語句實現(xiàn);另一種是通過PreparedStatement對象執(zhí)行動態(tài)的SQL語句實現(xiàn)。7.7.2添加操作74參數(shù)描述[INTO]可選項,無特殊含義,可以將它用在INSERT和目標(biāo)表之前table_name要添加記錄的數(shù)據(jù)表名稱column_list是表中的字段列表,表示向表中哪些字段插入數(shù)據(jù);如果是多個字段,字段之間用逗號分隔;不指定column_list,默認(rèn)向數(shù)據(jù)表中所有字段插入數(shù)據(jù)data_values要添加的數(shù)據(jù)列表,各個數(shù)據(jù)之間使用逗號分隔;數(shù)據(jù)列表中的個數(shù)、數(shù)據(jù)類型必須和字段列表中的字段個數(shù)、數(shù)據(jù)類型相一致values引入要插入的數(shù)據(jù)值的列表;對于column_list(如果已指定)中或者表中的每個列,都必須有一個數(shù)據(jù)值;必須用圓括號將值列表括起來;如果VALUES列表中的值與表中的值和表中列的順序不相同,或者未包含表中所有列的值,那么必須使用column_list明確地指定存儲每個傳入值的列75Statementstmt=conn.createStatement();intrtn=stmt.executeUpdate("insertintotb_user(name,pwd)values('hope','111')");

應(yīng)用Statement對象向數(shù)據(jù)表tb_user中添加數(shù)據(jù)的關(guān)鍵代碼如下:

利用PreparedStatement對象向數(shù)據(jù)表tb_user中添加數(shù)據(jù)的關(guān)鍵代碼如下:PreparedStatementpStmt=conn.prepareStatement("insertintotb_user(name,pwd)values(?,?)");pStmt.setString(1,"dream");pStmt.setString(2,"111");intrtn=pStmt.executeUpdate();76JDBC中也提供了兩種實現(xiàn)數(shù)據(jù)修改操作的方法,一種是通過Statement對象執(zhí)行靜態(tài)的SQL語句實現(xiàn);另一種是通過PreparedStatement對象執(zhí)行動態(tài)的SQL語句實現(xiàn)。通過Statement對象和PreparedStatement對象實現(xiàn)數(shù)據(jù)修改操作的方法同實現(xiàn)添加操作的方法基本相同,所不同的就是執(zhí)行的SQL語句不同。7.7.3修改操作77

實現(xiàn)數(shù)據(jù)修改操作使用的SQL語句為UPDATE語句,其語法格式如下:UPDATEtable_nameSET<column_name>=<expression>[….,<lastcolumn_name>=<lastexpression>][WHERE<search_condition>]78參數(shù)描述table_name需要更新的數(shù)據(jù)表名SET指定要更新的列或變量名稱的列表column_name含有要更改數(shù)據(jù)的列的名稱;column_name必須駐留于UPDATE子句中所指定的表或視圖中;標(biāo)識列不能進行更新;如果指定了限定的列名稱,限定符必須同UPDATE子句中的表或視圖的名稱相匹配expression變量、字面值、表達式或加上括號返回單個值的subSELECT語句;expression返回的值將替換column_name中的現(xiàn)有值WHERE指定條件來限定所更新的行<search_condition>為要更新行指定需滿足的條件,搜索條件也可以是連接所基于的條件,對搜索條件中可以包含的謂詞數(shù)量沒有限制79Statementstmt=conn.createStatement();intrtn=stmt.executeUpdate("updatetb_usersetname='hope',pwd='222'wherename='dream'");

應(yīng)用Statement對象修改數(shù)據(jù)表tb_user中name字段值為“dream”的記錄,關(guān)鍵代碼如下:

利用PreparedStatement對象修改數(shù)據(jù)表tb_user中name字段值為“hope”的記錄,關(guān)鍵代碼如下:80說明:在實際應(yīng)用中,經(jīng)常是先將要修改的數(shù)據(jù)查詢出來并顯示到相應(yīng)的表單中,然后將表單提交到相應(yīng)處理頁,在處理頁中獲取要修改的數(shù)據(jù),并執(zhí)行修改操作,完成數(shù)據(jù)修改。PreparedStatementpStmt=conn.prepareStatement("updatetb_usersetname=?,pwd=?wherename=?"); pStmt.setString(1,"dream"); pStmt.setString(2,"111"); pStmt.setString(3,"hope"); intrtn=pStmt.executeUpdate();81

實現(xiàn)數(shù)據(jù)刪除操作也可以通過兩種方法實現(xiàn),一種是通過Statement對象執(zhí)行靜態(tài)的SQL語句實現(xiàn);另一種是通過PreparedStatement對象執(zhí)行動態(tài)的SQL語句實現(xiàn)。通過Statement對象和PreparedStatement對象實現(xiàn)數(shù)據(jù)刪除操作的方法同實現(xiàn)添加操作的方法基本相同,所不同的就是執(zhí)行的SQL語句不同。實現(xiàn)數(shù)據(jù)刪除操作使用的SQL語句為DELETE語句,其語法格式如下:DELETEFROM<table_name>[WHERE<searchcondition>]7.7.4刪除操作82Statementstmt=conn.createStatement();intrtn=stmt.executeUpdate("deletetb_userwherename='hope'");

應(yīng)用Statement對象從數(shù)據(jù)表tb_user中刪除name字段值為“hope”的數(shù)據(jù),關(guān)鍵代碼如下:

利用PreparedStatement對象從數(shù)據(jù)表tb_user中刪除name字段值為“dream”的數(shù)據(jù),關(guān)鍵代碼為:PreparedStatementpStmt=conn.prepareStatement("deletefromtb_userwherename=?");pStmt.setString(1,"dream");intrtn=pStmt.executeUpdate();7.8連接池技術(shù)83847.8連接池技術(shù)

連接池簡介在Tomcat中配置連接池使用連接池技術(shù)訪問數(shù)據(jù)庫7.8.1連接池簡介

所謂連接池,就是預(yù)先建立好一定數(shù)量的數(shù)據(jù)庫連接,模擬存放在一個連接池中,由連接池負(fù)責(zé)對這些數(shù)據(jù)庫連接進行管理。85

這樣,就免去了每次在訪問數(shù)據(jù)庫之前建立數(shù)據(jù)庫連接的開銷。

連接池還解決了數(shù)據(jù)庫連接數(shù)量限制的問題。由于數(shù)據(jù)庫能夠承受的連接數(shù)量是有限的,當(dāng)達到一定程度時,數(shù)據(jù)庫的性能就會下降,甚至崩潰,而池化管理機制,通過有效地使用和調(diào)度這些連接池中的連接,則解決了這個問題。數(shù)據(jù)庫連接池的具體實施辦法是:

預(yù)先創(chuàng)建一定數(shù)量的連接,存放在連接池中;當(dāng)程序請求一個連接時,連接池是為該請求分配一個空閑連接,而不是去重新建立一個連接;當(dāng)程序使用完連接后,該連接將重新回到連接池中,而不是直接將連接釋放;當(dāng)連接池中的空閑連接數(shù)量低于下限時,連接池將根據(jù)管理機制追加創(chuàng)建一定數(shù)量的連接;當(dāng)空閑連接數(shù)量高于上限時,連接池將釋放一定數(shù)量的連接。87

在每次用完Connection后,要及時調(diào)用Connection對象的close()或dispose()方法顯式關(guān)閉連接,以便連接可以及時返回到連接池中,非顯式關(guān)閉的連接可能不會添加或返回到池中。連接池具有下列優(yōu)點:

創(chuàng)建一個新的數(shù)據(jù)庫連接所耗費的時間主要取決于網(wǎng)絡(luò)的速度以及應(yīng)用程序和數(shù)據(jù)庫服務(wù)器的(網(wǎng)絡(luò))距離,而且這個過程通常是一個很耗時的過程,而采用數(shù)據(jù)庫連接池后,數(shù)據(jù)庫連接請求則可以直接通過連接池滿足,而不需要為該請求重新連接、認(rèn)證到數(shù)據(jù)庫服務(wù)器,從而節(jié)省了時間;

提高了數(shù)據(jù)庫連接的重復(fù)使用率;

解決了數(shù)據(jù)庫對連接數(shù)量的限制。

連接池中可能存在多個與數(shù)據(jù)庫保持連接但未被使用的連接,在一定程度上浪費了資源;

要求開發(fā)人員和使用者準(zhǔn)確估算系統(tǒng)需要提供的最大數(shù)據(jù)庫連接的數(shù)量。連接池具有下列缺點:

為了使用連接池技術(shù)訪問數(shù)據(jù)庫,首先要建立數(shù)據(jù)源配置,下面介紹MySQL數(shù)據(jù)源的基本配置。(1)啟動To

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論