版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、數(shù)據(jù)持久化持久化(persistence):把數(shù)據(jù)保存到可掉電式存儲設(shè)備中以供把數(shù)據(jù)保存到可掉電式存儲設(shè)備中以供之后使用之后使用。大多數(shù)情況下,特別是企業(yè)級應(yīng)用,數(shù)據(jù)持久化數(shù)據(jù)持久化意味著將內(nèi)存中的數(shù)據(jù)保存到硬盤上加以意味著將內(nèi)存中的數(shù)據(jù)保存到硬盤上加以”固化固化”,而持久化的實現(xiàn)過程大多通過各種關(guān)系數(shù)據(jù)庫關(guān)系數(shù)據(jù)庫來完成。持久化的主要應(yīng)用是將內(nèi)存中的數(shù)據(jù)存儲在關(guān)系型數(shù)據(jù)庫中,當(dāng)然也可以存儲在磁盤文件、XML數(shù)據(jù)文件中。 Java 中的數(shù)據(jù)存儲技術(shù) 在Java中,數(shù)據(jù)庫存取技術(shù)可分為如下幾類: JDBC直接訪問數(shù)據(jù)庫直接訪問數(shù)據(jù)庫 JDO技術(shù) 第三方O/R工具,如Hibernate, ibat
2、is 等 JDBC是java訪問數(shù)據(jù)庫的基石,JDO, Hibernate等只是更好的封裝了JDBC。JDBC基礎(chǔ)基礎(chǔ) JDBC(Java Database Connectivity)是一個獨立于特定數(shù)據(jù)獨立于特定數(shù)據(jù)庫管理系統(tǒng)庫管理系統(tǒng)、通用的通用的SQL數(shù)據(jù)庫存取和操作的公共接口數(shù)據(jù)庫存取和操作的公共接口(一組API),定義了用來訪問數(shù)據(jù)庫的標(biāo)準(zhǔn)Java類庫,使用這個類庫可以以一種標(biāo)準(zhǔn)的方法、方便地訪問數(shù)據(jù)庫資源 JDBC為訪問不同的數(shù)據(jù)庫提供了一種統(tǒng)一的途徑統(tǒng)一的途徑,為開發(fā)者屏蔽了一些細(xì)節(jié)問題。 JDBC的目標(biāo)是使Java程序員使用JDBC可以連接任何提供提供了了JDBC驅(qū)動程序驅(qū)動程
3、序的數(shù)據(jù)庫系統(tǒng),這樣就使得程序員無需對特定的數(shù)據(jù)庫系統(tǒng)的特點有過多的了解,從而大大簡化和加快了開發(fā)過程。Java ApplicationMysqlOracleSQLServerDB2JDBCMysqlOracleSQLServerDB2Java Application調(diào)用實現(xiàn)一組規(guī)范:接口JDBCMysqlImplMysqlOracleSQLServerDB2Java Application調(diào)用可行,但不建議,因為這意味著 Java 應(yīng)用程序沒有更好的可移植性一組規(guī)范:接口JDBCJDBCOracleImplJDBCSQLServerImplJDBCDB2mpl調(diào)用JDBC驅(qū)動JDBC體系結(jié)構(gòu)
4、 JDBC接口(API)包括兩個層次: 面向應(yīng)用的面向應(yīng)用的API:Java API,抽象接口,供應(yīng)用程序開發(fā)人員使用(連接數(shù)據(jù)庫,執(zhí)行SQL語句,獲得結(jié)果)。 面向數(shù)據(jù)庫的面向數(shù)據(jù)庫的API:Java Driver API,供開發(fā)商開發(fā)數(shù)據(jù)庫驅(qū)動程序用。JDBC驅(qū)動程序分類 JDBC驅(qū)動程序:各個數(shù)據(jù)庫廠商根據(jù)JDBC的規(guī)范制作的 JDBC 實現(xiàn)類的類庫 JDBC驅(qū)動程序總共有四種類型: 第一類:JDBC-ODBC橋。 第二類:部分本地API部分Java的驅(qū)動程序。 第三類:JDBC網(wǎng)絡(luò)純Java驅(qū)動程序。 第四類:本地協(xié)議的純第四類:本地協(xié)議的純 Java 驅(qū)動程序驅(qū)動程序。 第三、四兩類
5、都是純Java的驅(qū)動程序,因此,對于Java開發(fā)者來說,它們在性能、可移植性、功能等方面都有優(yōu)勢。 ODBC早期對數(shù)據(jù)庫的訪問,都是調(diào)用數(shù)據(jù)庫廠商提供的專有的 API。為了在 Windows Windows 平臺平臺下提供統(tǒng)一的訪問方式,微軟推出了 ODBC(Open Database ConnectivityODBC(Open Database Connectivity,開放式數(shù)據(jù)庫連接),并提供了 ODBC API,使用者在程序中只需要調(diào)用 ODBC API,由 ODBC 驅(qū)動程序?qū)⒄{(diào)用轉(zhuǎn)換成為對特定的數(shù)據(jù)庫的調(diào)用請求一個基于ODBC的應(yīng)用程序?qū)?shù)據(jù)庫的操作不依賴任何DBMS(databa
6、se manager system),不直接與DBMS打交道,所有的數(shù)據(jù)庫操作由對應(yīng)的DBMS的ODBCODBC驅(qū)動程序驅(qū)動程序完成。也就是說,不論是FoxPro、Access , MYSQL還是Oracle數(shù)據(jù)庫,均可用ODBC API進(jìn)行訪問。由此可見,ODBC的最大優(yōu)點是能以統(tǒng)一的方式處理所有的數(shù)據(jù)庫。JDBC-ODBC橋 JDBC-ODBC 橋本身也是一個驅(qū)動,利用這個驅(qū)動,可以使用 JDBC-API 通過ODBC 去訪問數(shù)據(jù)庫。這種機(jī)制實際上是把標(biāo)準(zhǔn)的 JDBC 調(diào)用轉(zhuǎn)換成相應(yīng)的 ODBC 調(diào)用,并通過 ODBC 訪問數(shù)據(jù)庫因為需要通過多層調(diào)用,所以利用 JDBC-ODBC 橋訪問數(shù)
7、據(jù)庫的效率較低在 JDK 中,提供了 JDBC-ODBC 橋的實現(xiàn)類(sun.jdbc.odbc.JdbcOdbcDriver)Java 應(yīng)用程序JDBC APIJDBC-ODBC橋ODBC API數(shù)據(jù)庫ODBC層部分本地API部分Java的驅(qū)動程序 這種類型的 JDBC 驅(qū)動程序使用 Java 編寫,它調(diào)用數(shù)據(jù)庫廠商提供的本地 API 通過這種類型的 JDBC 驅(qū)動程序訪問數(shù)據(jù)庫減少了 ODBC 的調(diào)用環(huán)節(jié),提高了數(shù)據(jù)庫訪問的效率 在這種方式下需要在客戶的機(jī)器上安裝本地 JDBC 驅(qū)動程序和特定廠商的本地 API Java 應(yīng)用程序JDBC APIJDBC驅(qū)動程序廠商提供的本地 API數(shù)據(jù)庫
8、JDBC網(wǎng)絡(luò)純Java驅(qū)動程序 這種驅(qū)動利用中間件的應(yīng)用服務(wù)器來訪問數(shù)據(jù)庫。應(yīng)用服務(wù)器作為一個到多個數(shù)據(jù)庫的網(wǎng)關(guān),客戶端通過它可以連接到不同的數(shù)據(jù)庫服務(wù)器。 應(yīng)用服務(wù)器通常有自己的網(wǎng)絡(luò)協(xié)議,Java 用戶程序通過 JDBC 驅(qū)動程序?qū)?JDBC 調(diào)用發(fā)送給應(yīng)用服務(wù)器,應(yīng)用服務(wù)器使用本地程序驅(qū)動訪問數(shù)據(jù)庫,從而完成請求。Java 應(yīng)用程序JDBC APIJDBC驅(qū)動程序數(shù)據(jù)庫應(yīng)用服務(wù)器廠商提供的本地 API本地協(xié)議的純 Java 驅(qū)動程序 多數(shù)數(shù)據(jù)庫廠商已經(jīng)支持允許客戶程序通過網(wǎng)絡(luò)直接與數(shù)據(jù)庫通信的網(wǎng)絡(luò)協(xié)議網(wǎng)絡(luò)協(xié)議。 這種類型的驅(qū)動程序完全使用 Java 編寫,通過與數(shù)據(jù)庫建立的 Socket
9、連接,采用具體與廠商的網(wǎng)絡(luò)協(xié)議把 JDBC 調(diào)用轉(zhuǎn)換為直接連接的網(wǎng)絡(luò)調(diào)用Java 應(yīng)用程序JDBC APIJDBC驅(qū)動程序數(shù)據(jù)庫JDBC APIJDBC API JDBC API 是一系列的接口,它使得應(yīng)用程序能夠進(jìn)行數(shù)據(jù)庫聯(lián)接,執(zhí)行SQL語句,并且得到返回結(jié)果。Driver 接口 Java.sql.Driver 接口是所有 JDBC 驅(qū)動程序需要實現(xiàn)的接口。這個接口是提供給數(shù)據(jù)庫廠商使用的,不同數(shù)據(jù)庫廠商提供不同的實現(xiàn) 在程序中不需要直接去訪問實現(xiàn)了 Driver 接口的類,而是由驅(qū)動程序管理器類(java.sql.DriverManager)去調(diào)用這些Driver實現(xiàn)加載與注冊 JDBC
10、驅(qū)動 加載 JDBC 驅(qū)動需調(diào)用 Class 類的靜態(tài)方法 forName(),向其傳遞要加載的 JDBC 驅(qū)動的類名 DriverManager 類是驅(qū)動程序管理器類,負(fù)責(zé)管理驅(qū)動程序 通常不用顯式調(diào)用 DriverManager 類的 registerDriver() 方法來注冊驅(qū)動程序類的實例,因為 Driver 接口的驅(qū)動程序類都包含了靜態(tài)代碼塊,在這個靜態(tài)代碼塊中,會調(diào)用 DriverManager.registerDriver() 方法來注冊自身的一個實例建立連接 可以調(diào)用 DriverManager 類的 getConnection() 方法建立到數(shù)據(jù)庫的連接 JDBC URL
11、用于標(biāo)識一個被注冊的驅(qū)動程序,驅(qū)動程序管理器通過這個 URL 選擇正確的驅(qū)動程序,從而建立到數(shù)據(jù)庫的連接。 JDBC URL的標(biāo)準(zhǔn)由三部分組成,各部分間用冒號分隔。 jdbc: 協(xié)議:JDBC URL中的協(xié)議總是jdbc 子協(xié)議:子協(xié)議用于標(biāo)識一個數(shù)據(jù)庫驅(qū)動程序 子名稱:一種標(biāo)識數(shù)據(jù)庫的方法。子名稱可以依不同的子協(xié)議而變化,用子名稱的目的是為了定位數(shù)據(jù)庫提供足夠的信息 幾種常用數(shù)據(jù)庫的JDBC URL 對于 Oracle 數(shù)據(jù)庫連接,采用如下形式: jdbc:oracle:thinjdbc:oracle:thin:localhost:1521:sid:localhost:1521:sid 對于
12、 SQLServer 數(shù)據(jù)庫連接,采用如下形式: jdbc:microsoft:sqlserverjdbc:microsoft:sqlserver/localhost:1433; /localhost:1433; DatabaseNameDatabaseName= =sidsid 對于 MYSQL 數(shù)據(jù)庫連接,采用如下形式: j jdbc:mysqldbc:mysql:/localhost:3306/:/localhost:3306/sidsidjdbc:mysql:/localhost:3306/test 協(xié)議協(xié)議子協(xié)議子協(xié)議子名稱子名稱訪問數(shù)據(jù)庫 數(shù)據(jù)庫連接被用于向數(shù)據(jù)庫服務(wù)器發(fā)送命令和
13、SQL 語句,在連接建立后,需要對數(shù)據(jù)庫進(jìn)行訪問,執(zhí)行 sql 語句 在 java.sql 包中有 3 個接口分別定義了對數(shù)據(jù)庫的調(diào)用的不同方式: Statement PrepatedStatement CallableStatementStatement 通過調(diào)用 Connection 對象的 createStatement 方法創(chuàng)建該對象 該對象用于執(zhí)行靜態(tài)的 SQL 語句,并且返回執(zhí)行結(jié)果 Statement 接口中定義了下列方法用于執(zhí)行 SQL 語句: ResultSet excuteQuery(String sql) int excuteUpdate(String sql)Resul
14、tSet 通過調(diào)用 Statement 對象的 excuteQuery() 方法創(chuàng)建該對象 ResultSet 對象以邏輯表格的形式封裝了執(zhí)行數(shù)據(jù)庫操作的結(jié)果集,ResultSet 接口由數(shù)據(jù)庫廠商實現(xiàn) ResultSet 對象維護(hù)了一個指向當(dāng)前數(shù)據(jù)行的游標(biāo),初始的時候,游標(biāo)在第一行之前,可以通過 ResultSet 對象的 next() 方法移動到下一行 ResultSet 接口的常用方法: boolean next() getString() 初始狀態(tài): 指向第一條記錄的前面 next(): 若返回true, 就向下移動一行g(shù)etInt(1)SELECT id, name, age, bi
15、rth FROM customer_tablegetString(2)getInt(3)getDate(4)1.數(shù)組數(shù)組: new Object4, “Mike”, 26, null2.Customer: 一條記錄對應(yīng)一個對象一條記錄對應(yīng)一個對象1.3.age4.birth數(shù)據(jù)類型轉(zhuǎn)換表javajava類型類型SQLSQL類型類型booleanbooleanBITBITbytebyteTINYINTTINYINTshortshortSMALLINTSMALLINTintintINTEGERINTEGERlonglongBIGINTBIGINTStringStringCHAR,V
16、ARCHAR,LONGVARCHARCHAR,VARCHAR,LONGVARCHARbyte arraybyte arrayBINARY , VAR BINARYBINARY , VAR BINARYjava.sql.Datejava.sql.DateDATEDATEjava.sql.Timejava.sql.TimeTIMETIMEjava.sql.Timestampjava.sql.TimestampTIMESTAMPTIMESTAMPJDBC API JDBC API 小結(jié)小結(jié)1 1 java.sql.DriverManagerDriverManager用來裝載驅(qū)動程序,獲取數(shù)據(jù)庫連接。
17、 java.sql.ConnectionConnection完成對某一指定數(shù)據(jù)庫的聯(lián)接 java.sql.StatementStatement在一個給定的連接中作為SQL執(zhí)行聲明的容器,他包含了兩個重要的子類型。 Java.sql.PreparedSatement 用于執(zhí)行預(yù)編譯的sql聲明 Java.sql.CallableStatement用于執(zhí)行數(shù)據(jù)庫中存儲過程的調(diào)用 java.sql.ResultSetResultSet對于給定聲明取得結(jié)果的途徑練習(xí)練習(xí)1 1字段名字段名說明說明類型類型FlowIDFlowID流水號流水號IntIntTypeType四級六級四級六級intintIDCa
18、rdIDCard身份證號碼身份證號碼Varchar(18)Varchar(18)ExamCardExamCard準(zhǔn)考證號碼準(zhǔn)考證號碼Varchar(15)Varchar(15)StudentNamStudentName e學(xué)生姓名學(xué)生姓名Varchar(20)Varchar(20)LocationLocation區(qū)域區(qū)域Varchar(20)Varchar(20)GradeGrade成績成績IntInt1.創(chuàng)立數(shù)據(jù)庫表創(chuàng)立數(shù)據(jù)庫表 examstudentexamstudent,表結(jié)構(gòu)如下:,表結(jié)構(gòu)如下: 練習(xí)11 14 4412824195263214584412824195263214584
19、200523164754000200523164754000張鋒張鋒鄭州鄭州85852 24 4222224195263214584222224195263214584200523164754001200523164754001孫朋孫朋大連大連56563 36 6342824195263214584342824195263214584200523164754002200523164754002劉明劉明沈陽沈陽72724 46 6100824195263214584100824195263214584200523164754003200523164754003趙虎趙虎哈爾濱哈爾濱95955 54
20、 4454524195263214584454524195263214584200523164754004200523164754004楊麗楊麗北京北京64646 64 4854524195263214584854524195263214584200523164754005200523164754005王小紅王小紅太原太原60602.向數(shù)據(jù)庫中添加如下數(shù)據(jù) 練習(xí)1 插入一個新的 student 信息請輸入考生的詳細(xì)信息Type: IDCard:ExamCard:StudentName:Location:Grade:信息錄入成功!練習(xí)練習(xí)1 13. 在 eclipse 中建立 java 程序:輸
21、入身份證號或準(zhǔn)考證號可以查詢到學(xué)生的基本信息。結(jié)果如下:練習(xí)1完成學(xué)生信息的刪除功能SQL 注入攻擊 SQL 注入是利用某些系統(tǒng)沒有對用戶輸入的數(shù)據(jù)進(jìn)行充分的檢查,而在用戶輸入數(shù)據(jù)中注入非法的 SQL 語句段或命令,從而利用系統(tǒng)的 SQL 引擎完成惡意行為的做法 對于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了PreparedStatement 可以通過調(diào)用 Connection 對象的 preparedStatement() 方法獲取 PreparedStatement 對象 PreparedStatement 接口是
22、 Statement 的子接口,它表示一條預(yù)編譯過的 SQL 語句 PreparedStatement 對象所代表的 SQL 語句中的參數(shù)用問號(?)來表示,調(diào)用 PreparedStatement 對象的 setXXX() 方法來設(shè)置這些參數(shù). setXXX() 方法有兩個參數(shù),第一個參數(shù)是要設(shè)置的 SQL 語句中的參數(shù)的索引(從 1 開始),第二個是設(shè)置的 SQL 語句中的參數(shù)的值PreparedStatement vs Statement 代碼的可讀性和可維護(hù)性. PreparedStatement 能最大可能提高性能: DBServer會對預(yù)編譯語句提供性能優(yōu)化。因為預(yù)編譯語句有可能被
23、重復(fù)調(diào)用,所以語句在被DBServer的編譯器編譯后的執(zhí)行代碼被緩存下來,那么下次調(diào)用時只要是相同的預(yù)編譯語句就不需要編譯,只要將參數(shù)直接傳入編譯過的語句執(zhí)行代碼中就會得到執(zhí)行。 在statement語句中,即使是相同操作但因為數(shù)據(jù)內(nèi)容不一樣,所以整個語句本身不能匹配,沒有緩存語句的意義.事實是沒有數(shù)據(jù)庫會對普通語句編譯后的執(zhí)行代碼緩存.這樣每執(zhí)行一次都要對傳入的語句編譯一次. (語法檢查,語義檢查,翻譯成二進(jìn)制命令,緩存) PreparedStatement 可以防止 SQL 注入 SQL1. 先利用 SQL 進(jìn)行查詢,得到結(jié)果集2. 利用反射創(chuàng)建實體類的對象:創(chuàng)建 Student 對象3.
24、 獲取結(jié)果集的列的別名:獲取結(jié)果集的列的別名:idCard、studentName4. 再獲取結(jié)果集的每一列的值, 結(jié)合 3 得到一個 Map,鍵:列的別名,值:列的值:flowId:5, type:6, idCard: xxx 5. 再利用反射為 2 的對應(yīng)的屬性賦值:屬性即為 Map 的鍵,值即為 Map 的值查詢(要求:列的別名要和 Class 對應(yīng)的類的屬性名相同),得到 ResultSet 對象得到 ResultSetMetaData 對象:可以知道 SQL 語句中查詢了哪些列,以及列的別名都是什么flowIdtypeidCardexamCardClass 對象Class 對應(yīng)的類對
25、象反射:創(chuàng)建對象反射:為對應(yīng)的屬性賦值使用使用 JDBC JDBC 驅(qū)動程序處理元數(shù)據(jù)驅(qū)動程序處理元數(shù)據(jù) Java 通過JDBC獲得連接以后,得到一個Connection 對象,可以從這個對象獲得有關(guān)數(shù)據(jù)庫管理系統(tǒng)的各種信息有關(guān)數(shù)據(jù)庫管理系統(tǒng)的各種信息,包括數(shù)據(jù)庫中的各個表,表中的各個列,數(shù)據(jù)類型,觸發(fā)器,存儲過程等各方面的信息。根據(jù)這些信息,JDBC可以訪問一個實現(xiàn)事先并不了解的數(shù)據(jù)庫。 獲取這些信息的方法都是在DatabaseMetaData類的對象上實現(xiàn)的,而DataBaseMetaData對象是在Connection對象上獲得的。 DatabaseMetaData類類 Database
26、MetaData 類中提供了許多方法用于獲得數(shù)據(jù)源的各種信息,通過這些方法可以非常詳細(xì)的了解數(shù)據(jù)庫的信息: getURL():返回一個String類對象,代表數(shù)據(jù)庫的URL。 getUserName():返回連接當(dāng)前數(shù)據(jù)庫管理系統(tǒng)的用戶名。 isReadOnly():返回一個boolean值,指示數(shù)據(jù)庫是否只允許讀操作。 getDatabaseProductName():返回數(shù)據(jù)庫的產(chǎn)品名稱。 getDatabaseProductVersion():返回數(shù)據(jù)庫的版本號。 getDriverName():返回驅(qū)動驅(qū)動程序的名稱。 getDriverVersion():返回驅(qū)動程序的版本號。Res
27、ultSetMetaDataResultSetMetaData 類類 可用于獲取關(guān)于 ResultSet 對象中列的類型和屬性信息的對象: getColumnName(int column):獲取指定列的名稱 getColumnCount():返回當(dāng)前 ResultSet 對象中的列數(shù)。 getColumnTypeName(int column):檢索指定列的數(shù)據(jù)庫特定的類型名稱。 getColumnDisplaySize(int column):指示指定列的最大標(biāo)準(zhǔn)寬度,以字符為單位。 isNullable(int column):指示指定列中的值是否可以為 null。 isAutoIncr
28、ement(int column):指示是否自動為指定列進(jìn)行編號,這樣這些列仍然是只讀的。 取取得得數(shù)據(jù)庫自動生成的主鍵數(shù)據(jù)庫自動生成的主鍵 示例:Connection conn = JdbcUtil.getConnection();String sql = insert into user(name,password,email,birthday) values(abc,123,1978-08-08);PreparedStatement st = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS );st.executeUpd
29、ate();ResultSet rs = st.getGeneratedKeys(); /得到插入行的主鍵if(rs.next()System.out.println(rs.getObject(1);Oracle LOBLOBLOB,即,即Large ObjectsLarge Objects(大對象)(大對象),是用來存儲大量的二進(jìn)制和文是用來存儲大量的二進(jìn)制和文本數(shù)據(jù)的一種數(shù)據(jù)類型本數(shù)據(jù)的一種數(shù)據(jù)類型(一個LOB字段可存儲可多達(dá)4GB的數(shù)據(jù))。LOB 分為兩種類型:內(nèi)部LOB和外部LOB。內(nèi)部LOB將數(shù)據(jù)以字節(jié)流的形式存儲在數(shù)據(jù)庫的內(nèi)部。因而,內(nèi)部LOB的許多操作都可以參與事務(wù),也可以像處理
30、普通數(shù)據(jù)一樣對其進(jìn)行備份和恢復(fù)操作。Oracle支持三種類型的內(nèi)部LOB: BLOB(二進(jìn)制數(shù)據(jù)) CLOB(單字節(jié)字符數(shù)據(jù)) NCLOB(多字節(jié)字符數(shù)據(jù))。CLOB和NCLOB類型適用于存儲超長的文本數(shù)據(jù),BLOBBLOB字段適用于存儲大量字段適用于存儲大量的二進(jìn)制數(shù)據(jù),如圖像、視頻、音頻,文件等的二進(jìn)制數(shù)據(jù),如圖像、視頻、音頻,文件等。目前只支持一種外部LOB類型,即BFILE類型。在數(shù)據(jù)庫內(nèi),該類型僅存儲數(shù)據(jù)在操作系統(tǒng)中的位置信息,而數(shù)據(jù)的實體以外部文件的形式存在于操作系統(tǒng)的文件系統(tǒng)中。因而,該類型所表示的數(shù)據(jù)是只讀的,不參與事務(wù)。該類型可幫助用戶管理大量的由外部程序訪問的文件。MySQ
31、L BLOB 類型介紹 MySQL中,BLOB是一個二進(jìn)制大型對象,是一個可以存儲大量數(shù)據(jù)的容器,它能容納不同大小的數(shù)據(jù)。MySQL的四種BLOB類型(除了在存儲的最大信息量上不同外,他們是等同的)實際使用中根據(jù)需要存入的數(shù)據(jù)大小定義不同的BLOB類型。需要注意的是:如果存儲的文件過大,數(shù)據(jù)庫的性能會下降。使用JDBC來寫入Blob型數(shù)據(jù)到Oracle中 Oracle的的Blob字段字段比long字段的性能要好,可以用來保存如圖片之類的二進(jìn)制數(shù)據(jù)。 Oracle的的BLOB字段由兩部分組成:數(shù)據(jù)(值)和指向數(shù)據(jù)的指針(定位器)。字段由兩部分組成:數(shù)據(jù)(值)和指向數(shù)據(jù)的指針(定位器)。盡管值與表
32、自身一起存儲,但是一個BLOB列并不包含值,僅有它的定位指針。為了使用大對象,程序必須聲明定位器類型的本地變量。當(dāng)Oracle內(nèi)部LOB被創(chuàng)建時,定位器被存放在列中,值被存放在定位器被存放在列中,值被存放在LOB段中,段中,LOB段是在數(shù)據(jù)庫內(nèi)部表的一部分。段是在數(shù)據(jù)庫內(nèi)部表的一部分。因為Blob自身有一個cursor,當(dāng)寫入Blob字段必須使用指針(定位器)對Blob進(jìn)行操作,因而在寫入因而在寫入Blob之前,必須獲得指針(定位器)才能進(jìn)行寫入之前,必須獲得指針(定位器)才能進(jìn)行寫入如何獲得Blob的指針(定位器) :需要先插入一個empty的blob,這將創(chuàng)建一個blob的指針,然后再把這
33、個empty的blob的指針查詢出來,這樣通過兩步操作,就獲得了blob的指針,可以真正的寫入blob數(shù)據(jù)了。 步驟 1、插入空blob insert into javatest(name,content) values(?,empty_blob(); 2、獲得blob的cursor select content from javatest where name= ? for update; 注意: 須加for update,鎖定該行,直至該行被修改完畢,保證不產(chǎn)生并發(fā)沖突。 3、利用 io,和獲取到的cursor往數(shù)據(jù)庫寫數(shù)據(jù)流 數(shù)據(jù)庫事務(wù) 在數(shù)據(jù)庫中,所謂事務(wù)是指一組邏輯操作單元一組邏輯操
34、作單元,使數(shù)據(jù)從一種使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)狀態(tài)變換到另一種狀態(tài)。 為確保數(shù)據(jù)庫中數(shù)據(jù)的一致性一致性,數(shù)據(jù)的操縱應(yīng)當(dāng)是離散的成組的邏輯單元:當(dāng)它全部完成時,數(shù)據(jù)的一致性可以保持,而當(dāng)這個單元中的一部分操作失敗,整個事務(wù)應(yīng)全部視為錯誤,所有從起始點以后的操作應(yīng)全部回退到開始狀態(tài)。 事務(wù)的操作:先定義開始一個事務(wù),然后對數(shù)據(jù)作修改操作,這時如果提交提交(COMMIT),這些修改就永久地保存下來,如果回退回退(ROLLBACK),數(shù)據(jù)庫管理系統(tǒng)將放棄所作的所有修改而回到開始事務(wù)時的狀態(tài)。數(shù)據(jù)庫事務(wù)事務(wù)的ACID(acid)屬性 1. 原子性(Atomicity)原子性是指事務(wù)是一個不可分割的
35、工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。 2. 一致性(Consistency)事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另外一個一致性狀態(tài)。 3. 隔離性(Isolation)事務(wù)的隔離性是指一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾。 4. 持久性(Durability)持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來的其他操作和數(shù)據(jù)庫故障不應(yīng)該對其有任何影響JDBC 事物處理事務(wù):指構(gòu)成單個邏輯工作單元的操作集合事務(wù)處理:保證所有事務(wù)都作為一個工作單元來執(zhí)行,即使出現(xiàn)了故障,都
36、不能改變這種執(zhí)行方式。當(dāng)在一個事務(wù)中執(zhí)行多個操作時,要么所有的事務(wù)都被提交(commit),要么整個事務(wù)回滾(rollback)到最初狀態(tài)當(dāng)一個連接對象被創(chuàng)建時,默認(rèn)情況下是自動提交事務(wù):每次執(zhí)行一個 SQL 語句時,如果執(zhí)行成功,就會向數(shù)據(jù)庫自動提交,而不能回滾為了讓多個 SQL 語句作為一個事務(wù)執(zhí)行: 調(diào)用 Connection 對象的 setAutoCommit(false); 以取消自動提交事務(wù) 在所有的 SQL 語句都成功執(zhí)行后,調(diào)用 commit(); 方法提交事務(wù) 在出現(xiàn)異常時,調(diào)用 rollback(); 方法回滾事務(wù) 若此時 Connection 沒有被關(guān)閉, 則需要恢復(fù)其自
37、動提交狀態(tài)數(shù)據(jù)庫的隔離級別對于同時運行的多個事務(wù), 當(dāng)這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機(jī)制, 就會導(dǎo)致各種并發(fā)問題: 臟讀臟讀: 對于兩個事物 T1, T2, T1 讀取了已經(jīng)被 T2 更新但還沒有被提交沒有被提交的字段. 之后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的. 不可重復(fù)讀不可重復(fù)讀: 對于兩個事物 T1, T2, T1 讀取了一個字段, 然后 T2 更新更新了該字段. 之后, T1再次讀取同一個字段, 值就不同了. 幻讀幻讀: 對于兩個事物 T1, T2, T1 從一個表中讀取了一個字段, 然后 T2 在該表中插入插入了一些新的行. 之后, 如果
38、 T1 再次讀取同一個表, 就會多出幾行.數(shù)據(jù)庫事務(wù)的隔離性: 數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并發(fā)問題. 一個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別. 數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別, 不同隔離級別對應(yīng)不同的干擾程度, 隔離級別越高, 數(shù)據(jù)一致性就越好, 但并發(fā)性越弱數(shù)據(jù)庫的隔離級別 數(shù)據(jù)庫提供的 4 種事務(wù)隔離級別: Oracle 支持的 2 種事務(wù)隔離級別:READ COMMITEDREAD COMMITED, SERIALIZABLE. Oracle 默認(rèn)的事務(wù)隔離級別為: READ COMMITED Mysql 支持 4 中事務(wù)隔離級別. M
39、ysql 默認(rèn)的事務(wù)隔離級別為: REPEATABLE READ在 MySql 中設(shè)置隔離級別 每啟動一個 mysql 程序, 就會獲得一個單獨的數(shù)據(jù)庫連接. 每個數(shù)據(jù)庫連接都有一個全局變量 tx_isolation, 表示當(dāng)前的事務(wù)隔離級別. MySQL 默認(rèn)的隔離級別為 Repeatable Read 查看當(dāng)前的隔離級別: SELECT tx_isolation; 設(shè)置當(dāng)前 mySQL 連接的隔離級別: set transaction isolation level read committed; 設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別: set globalglobal transaction
40、isolation level read committed;批量處理JDBC語句提高處理速度 當(dāng)需要成批插入或者更新記錄時。可以采用Java的批量更新更新機(jī)制,這一機(jī)制允許多條語句一次性提交給數(shù)據(jù)庫批量處理。通常情況下比單獨提交處理更有效率 JDBC的批量處理語句包括下面兩個方法: addBatch(String):添加需要批量處理的SQL語句或是參數(shù); executeBatch();執(zhí)行批量處理語句; 通常我們會遇到兩種批量執(zhí)行SQL語句的情況: 多條SQL語句的批量處理; 一個SQL語句的批量傳參;多條SQL語句的批量處理一個SQL語句的批量傳參 情景 解決JDBC數(shù)據(jù)庫連接池的必要性
41、在使用開發(fā)基于數(shù)據(jù)庫的web程序時,傳統(tǒng)的模式傳統(tǒng)的模式基本是按以下步驟: 在主程序(如servlet、beans)中建立數(shù)據(jù)庫連接。 進(jìn)行sql操作 斷開數(shù)據(jù)庫連接。這種模式開發(fā),存在的問題: 普通的JDBC數(shù)據(jù)庫連接使用 DriverManager 來獲取,每次向數(shù)據(jù)庫建立連接的時候都要將 Connection 加載到內(nèi)存中,再驗證用戶名和密碼(得花費0.05s1s的時間)。需要數(shù)據(jù)庫連接的時候,就向數(shù)據(jù)庫要求一個,執(zhí)行完成后再斷開連接。這樣的方式將會消耗大量的資源和時間。數(shù)據(jù)庫的連接資數(shù)據(jù)庫的連接資源并沒有得到很好的重復(fù)利用源并沒有得到很好的重復(fù)利用. .若同時有幾百人甚至幾千人在線,頻
42、繁的進(jìn)行數(shù)據(jù)庫連接操作將占用很多的系統(tǒng)資源,嚴(yán)重的甚至?xí)斐煞?wù)器的崩潰。 對于每一次數(shù)據(jù)庫連接,使用完后都得斷開。否則,如果程序出現(xiàn)異常而未能關(guān)閉,將會導(dǎo)致數(shù)據(jù)庫系統(tǒng)中的內(nèi)存泄漏,最終將導(dǎo)致重啟數(shù)據(jù)庫。 這種開發(fā)不能控制被創(chuàng)建的連接對象數(shù),系統(tǒng)資源會被毫無顧及的分配出去,如連接過多,也可能導(dǎo)致內(nèi)存泄漏,服務(wù)器崩潰。 數(shù)據(jù)庫連接池(數(shù)據(jù)庫連接池(connection pool) 為解決傳統(tǒng)開發(fā)中的數(shù)據(jù)庫連接問題,可以采用數(shù)據(jù)庫連接池技術(shù)。數(shù)據(jù)庫連接池的基本思想基本思想就是為數(shù)據(jù)庫連接建立一個“緩沖池”。預(yù)先在緩沖池中放入一定數(shù)量的連接,當(dāng)需要建立數(shù)據(jù)庫連接時,只需從“緩沖池”中取出一個,使用完
43、畢之后再放回去。數(shù)據(jù)庫連接池數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是重新建立一個使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是重新建立一個。數(shù)據(jù)庫連接池在初始化時將創(chuàng)建一定數(shù)量的數(shù)據(jù)庫連接放到連接池中,這些數(shù)據(jù)庫連接的數(shù)量是由最小數(shù)據(jù)庫連接數(shù)來設(shè)定最小數(shù)據(jù)庫連接數(shù)來設(shè)定的。無論這些數(shù)據(jù)庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數(shù)量。連接池的最大數(shù)據(jù)庫連接數(shù)量最大數(shù)據(jù)庫連接數(shù)量限定了這個連接池能占有的最大連接數(shù),當(dāng)應(yīng)用程序向連接池請求的連接數(shù)超過最大連接數(shù)量時,這些請求將被加入到等待隊列中。數(shù)據(jù)庫連接池conn1conn2co
44、nn3conn4Java Applicationfreefreefreefree數(shù)據(jù)庫連接池的工作原理數(shù)據(jù)庫連接池的工作原理數(shù)據(jù)庫連接池技術(shù)的優(yōu)點資源重用: 由于數(shù)據(jù)庫連接得以重用,避免了頻繁創(chuàng)建,釋放連接引起的大量性能開銷。在減少系統(tǒng)消耗的基礎(chǔ)上,另一方面也增加了系統(tǒng)運行環(huán)境的平穩(wěn)性。更快的系統(tǒng)反應(yīng)速度 數(shù)據(jù)庫連接池在初始化過程中,往往已經(jīng)創(chuàng)建了若干數(shù)據(jù)庫連接置于連接池中備用。此時連接的初始化工作均已完成。對于業(yè)務(wù)請求處理而言,直接利用現(xiàn)有可用連接,避免了數(shù)據(jù)庫連接初始化和釋放過程的時間開銷,從而減少了系統(tǒng)的響應(yīng)時間新的資源分配手段 對于多應(yīng)用共享同一數(shù)據(jù)庫的系統(tǒng)而言,可在應(yīng)用層通過數(shù)據(jù)庫連
45、接池的配置,實現(xiàn)某一應(yīng)用最大可用數(shù)據(jù)庫連接數(shù)的限制,避免某一應(yīng)用獨占所有的數(shù)據(jù)庫資源統(tǒng)一的連接管理,避免數(shù)據(jù)庫連接泄露 在較為完善的數(shù)據(jù)庫連接池實現(xiàn)中,可根據(jù)預(yù)先的占用超時設(shè)定,強(qiáng)制回收被占用連接,從而避免了常規(guī)數(shù)據(jù)庫連接操作中可能出現(xiàn)的資源泄露兩種開源的數(shù)據(jù)庫連接池 JDBC 的數(shù)據(jù)庫連接池使用 javax.sql.DataSource 來表示,DataSource 只是一個接口,該接口通常由服務(wù)器(Weblogic, WebSphere, Tomcat)提供實現(xiàn),也有一些開源組織提供實現(xiàn): DBCP 數(shù)據(jù)庫連接池 C3P0 數(shù)據(jù)庫連接池 DataSource 通常被稱為數(shù)據(jù)源,它包含連接池
46、和連接池管理兩個部分,習(xí)慣上也經(jīng)常把 DataSource 稱為連接池DBCP 數(shù)據(jù)源 DBCP 是 Apache 軟件基金組織下的開源連接池實現(xiàn),該連接池依賴該組織下的另一個開源系統(tǒng):Common-pool. 如需使用該連接池實現(xiàn),應(yīng)在系統(tǒng)中增加如下兩個 jar 文件: Commons-dbcp.jar:連接池的實現(xiàn) Commons-pool.jar:連接池實現(xiàn)的依賴庫 Tomcat 的連接池正是采用該連接池來實現(xiàn)的。該數(shù)據(jù)庫連接池既可以與應(yīng)用服務(wù)器整合使用,也可由應(yīng)用程序獨立使用。DBCP 數(shù)據(jù)源使用范例 數(shù)據(jù)源和數(shù)據(jù)庫連接不同,數(shù)據(jù)源無需創(chuàng)建多個,它是產(chǎn)生數(shù)據(jù)庫連接的工廠,因此整個應(yīng)用只
47、需要一個數(shù)據(jù)源即可。 當(dāng)數(shù)據(jù)庫訪問結(jié)束后,程序還是像以前一樣關(guān)閉數(shù)據(jù)庫連接:conn.close(); 但上面的代碼并沒有關(guān)閉數(shù)據(jù)庫的物理連接,它僅僅把數(shù)據(jù)庫連接釋放,歸還給了數(shù)據(jù)庫連接池。C3P0 數(shù)據(jù)源ApacheApacheDBUtilsDBUtils簡介簡介 commons-dbutils 是 Apache 組織提供的一個開源 JDBC工具類庫,它是對JDBC的簡單封裝,學(xué)習(xí)成本極低,并且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程序的性能。 API介紹: mons.dbutils.QueryRunner mons.dbutils.ResultSetHandler
48、 工具類 mons.dbutils.DbUtils、。 QueryRunnerquery(Connection conn, String sql, ResultSetHandler rsh) stmt = this.prepareStatement(conn, sql); this.fillStatement(stmt, params); rs = this.wrap(stmt.executeQuery(); result = rsh.handle(rs); return result; 得到結(jié)果集對象調(diào)用傳入的 ResultSetHandler 對象的 handle 方法, 并且把前面得到的
49、 ResultSet 對象作為參數(shù)傳入把 result 作為結(jié)果返回DbUtils類類 DbUtils :提供如關(guān)閉連接、裝載JDBC驅(qū)動程序等常規(guī)工作的工具類,里面的所有方法都是靜態(tài)的。主要方法如下: public static void close() throws java.sql.SQLException:DbUtils類提供了三個重載的關(guān)閉方法。這些方法檢查所提供的參數(shù)是不是NULL,如果不是的話,它們就關(guān)閉Connection、Statement和ResultSet。 public static void closeQuietly(): 這一類方法不僅能在Connection、St
50、atement和ResultSet為NULL情況下避免關(guān)閉,還能隱藏一些在程序中拋出的SQLEeception。 public static void commitAndCloseQuietly(Connection conn): 用來提交連接,然后關(guān)閉連接,并且在關(guān)閉連接時不拋出SQL異常。 public static boolean loadDriver(java.lang.String driverClassName):這一方裝載并注冊JDBC驅(qū)動程序,如果成功就返回true。使用該方法,你不需要捕捉這個異常ClassNotFoundException。QueryRunner類類 該類簡
51、單化了SQL查詢,它與ResultSetHandler組合在一起使用可以完成大部分的數(shù)據(jù)庫操作,能夠大大減少編碼量。 QueryRunner類提供了兩個構(gòu)造方法: 默認(rèn)的構(gòu)造方法 需要一個 javax.sql.DataSource 來作參數(shù)的構(gòu)造方法。QueryRunner類的主要方法類的主要方法public Object query(Connection conn, String sql, Object params, ResultSetHandler rsh) throws SQLException:執(zhí)行一個查詢操作,在這個查詢中,對象數(shù)組中的每個元素值被用來作為查詢語句的置換參數(shù)。該方法會自行處理 PreparedStatement 和 ResultSet 的創(chuàng)建和關(guān)閉。public Object query(String sql, Object params, ResultSetHandler rsh) throws SQLException:幾乎與第一種方法一樣;唯一的不同在于它不將數(shù)據(jù)庫連接提供給方法,并且它是從提供給構(gòu)造方法的數(shù)據(jù)源(DataSource) 或使用
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年徐州從業(yè)資格證貨運考試答案
- 2025年婁底貨運從業(yè)資格證考試內(nèi)容
- 2025年貨運從業(yè)資格證模擬考試0題
- 2025年吉安運輸從業(yè)資格證考試試題庫
- 第二章運動與能量練習(xí)2023-2024學(xué)年教科版物理八年級上冊
- 軟件公司員工手冊
- 智能控制規(guī)劃服務(wù)承諾書
- 實驗室安全防護(hù)設(shè)施配置與維護(hù)
- 商業(yè)活動臨時化妝師聘用書
- 商標(biāo)使用許可合同范本
- 國際疾病分類手術(shù)碼(ICD-9-CM-3)使用手冊
- 物資部對標(biāo)管理實施方案
- 上海工程技術(shù)大學(xué)《管理信息系統(tǒng)》 ~學(xué)年 第 一 學(xué)期 實驗報告
- 職工醫(yī)?;鶖?shù)調(diào)整對比明細(xì)表Excel模板
- 送你一個字評語2022
- 放射科優(yōu)質(zhì)護(hù)理服務(wù)PPT學(xué)習(xí)教案
- GB_T 22627-2022水處理劑 聚氯化鋁_(高清-最新版)
- 教學(xué)團(tuán)隊建設(shè)總結(jié)報告
- 破產(chǎn)法PPT課件
- 看守所釋放證明書
- 魚骨圖-PPT模板
評論
0/150
提交評論