做用:建立一個Statement對象將SQL語句發送到數據庫。
在使用缺省參數設置的時候,ResultSet是一種只能訪問一次、只能向前訪問和只讀的對象。也就是說只能訪問該數據一次,若要再次訪問,則必須從新查詢數據庫。java
createStatement(int resultSetType,int resultSetConcurrency)mysql
做用:建立一個Statement對象,該對象生成具備給定類型和併發性的ResultSet對象。
參數resultSetType指定ResultSet的類型。其選項有:程序員
參數resultSetConcurrency設置ResultSet的併發性,該參數設定是否能夠更新ResultSet。sql
CONCUR_UPDATABLE:指定能夠更新ResultSet。數據庫
JDBC是一種用於執行SQL語句的JAVA API,它由一組用JAVA語言編寫的類和接口組成。經過這些類和接口,JDBC把SQL語句發送給不一樣類型的數據庫進行處理並接收處理結果。編程
JDBC產品包括三個組件:緩存
(1)JDBC驅動程序管理器:是JDBC體系結構的支柱,主要做用是把JAVA應用程序鏈接到JDBC驅動程序上,而後退出。安全
(2)JDBC驅動程序測試工具包:用於測試JDBC驅動程序,只有經過測試的驅動程序才被認爲是「符合JDBC標準」的。服務器
(3)JDBC-ODBC橋:使ODBC驅動程序可被用做JDBC驅動程序,它的實現爲JDBC的快速發展提供了一條途徑。網絡
主要的類和接口:
支持JDBC API的類和主要接口封裝在Java.sql包和javax.sql包中。
Java.sql.DriverManager是惟一的一個服務類,用於管理JDBC驅動程序,提供getConnection方法創建應用程序與數據庫鏈接。當JDBC驅動程序加載到內存時,會自動向JDBC驅動程序進行註冊,接着若是有鏈接數據庫的請求,DriverManager類就會用註冊的JDBC驅動程序來建立到數據庫的鏈接。通常經過調用Class.forName(String str)來加載驅動程序。
Java.sql.Connection接口定義到數據庫的鏈接,用於製造Statement對象,提供數據庫的信息。一個應用程序可與單個數據庫有一個或多個鏈接,或者可與許多數據庫有鏈接。
Java.sql.Statement表明SQL語句的接口,經過executeQuery或executeUpdate方法執行一個靜態的SQL語句。
Java.sql.ResultSet接口維護查詢獲得的一張視圖表,它提供了許多維護表記錄的方法對數據庫進行操做。
Java.sql.SQLException類用於檢查並報告用JDBC操做數據庫時的錯誤。JAVA是一種安全性很好的語言,若是在類方法中聲明瞭有例外處理,當在程序中建立對象實例,經過對象實例調用這些方法時都應該提供例外處理。
JSP使用JDBC的過程:
(1) 建立一個JDBC Driver鏈接實例或DataSource鏈接實例。
(2) 使用鏈接實例建立一個鏈接
(3) 使用JDBC鏈接建立聲明語句
(4) 調用聲明語句的executeQuery得到結果集或executeUpdate修改數據庫中的數據
(5) 操做結果集的記錄
(6) 若是還須要這個鏈接建立其它結果集,從第3步開始重複
(7) 釋放結果集
(8) 釋放聲明語句
(9) 斷開與數據庫的鏈接
JDBC驅動程序的類型:
(1) 驅動程序類型一:將JDBC調用映射到其它類型的數據訪問API上,最經常使用的是JDBC-ODBC橋鏈接驅動程序,它利用ODBC驅動程序提供JDBC的訪問。要注意的是,使用這種類型的驅動程序必須在每一個客戶機上加載ODBC驅動程序,所以此類型使用於企業內部或者是用JAVA編寫的三層結構的應用程序服務器代碼。
(2) 驅動程序類型二:是基於本地API,部分用JAVA來編寫的驅動程序。這種類型的驅動程序將客戶機API上的JDBC調用裝換爲Oracle、Sybase、Informix、DB2或其它DBMS的調用。
(3) 驅動程序類型三:是JDBC網絡純JAVA驅動程序,這種驅動程序將JDBC裝換爲於DBMS無關的網絡協議,此後這種協議將被某個服務器裝換爲一種DBMS協議。這種網絡服務器中間件可以將它的純JAVA客戶機鏈接到多種不一樣的數據庫上,由於它們僅僅依賴驅動程序和中間件之間的網絡協議,而中間件提供數據庫到應用程序之間的抽象。
(4) 驅動程序類型四:是本地協議純JAVA驅動程序,這類驅動程序將JDBC調用轉換爲DBMS所使用的網絡協議,這將容許從客戶機直接調用DBMS服務器,得到最大的網絡傳輸速度。
經過Driver接口創建鏈接:
(1)加載驅動程序:
Class.forName(類名),就能夠將相應的核心類加載到驅動程序管理器中。
(A)加載JDBC-ODBC橋驅動程序
Class.forName(「sun.jdbc.odbc.JdbcOdbcDriver」);
(B)加載JDBC驅動程序
Class.forName(「jdbc.driver_class_name」);
(C)加載mysql驅動程序
Class.forName(「org.gjt.mm.mysql.Driver」);
(D)加載Oracle驅動程序
Class.forName(「Oracle.jdbc.driver.OracleDriver」);
(2)創建鏈接
當驅動程序加載成功,就能夠操做DriverManager類的getConnection方法創建同數據庫的鏈接,格式以下:
Connection conn=DriverManger.getConnection(url,login,password);
對於不一樣的數據庫驅動程序,其URL有所不一樣,可是必須聽從下面兩個格式中的一個:
Jdbc:driver-id:database-id
Jdbc:driver-id://host/database-id
例如:JDBC-ODBC橋驅動程序的格式:jdbc:odbc:數據源名
Mysql jdbc驅動程序的格式:jdbc:mysql:///test
Oracle jdbc驅動程序的格式:jdbc:oracle:thin:@myhost:1521:ORCL
使用DataSource接口創建鏈接:使用JAVA命名和目錄接口JNDI做爲數據的存儲和查詢機制。首先使用JNDI的命名類制定一個驅動程序的名稱和位置並裝入該驅動程序。完成這一操做,須要創建一個目錄形式的視圖,建立一個InitialContext類(該類屬於javax.naming包)表示的頂級域名,至關於一個目錄形式的根目錄,例如:
InitialContext ctx=new InitialContext();//構造一個初始上下文
DataSource ds=(DataSource)ctx.lookup(「jdbc/oracle」);
得到了一個數據源後,就能夠經過這個數據源的getConnection方法建立一個鏈接了:
Connection conn=ds.getConnection(「username」,」pwd」);
(3)聲明語句
聲明語句的建立:JDBC提供了三個接口用於向數據庫發送SQL語句,它們分別是: Statement,PreparedStatement,CallableStatement。Connection接口中的三個方法對應於建立上述三個接口實例,分別爲:createStatement,preparedStatement,prepareCall。Statement對象用於發送簡單的 SQL語句。PreparedStatement對象用於發送帶有一個或多個輸入參數的SQL語句,而且它通過預編譯,效率要比使用Statament對象高。CallableStatement對象用於執行SQL存儲程序,SQL存儲程序是一組經過名稱來調用的SQL語句。
普通語句的建立:
String cmd=」select * from BaseInfo」;
Statement stmt=conn.createStatement(cmd);
預編譯語句的建立:
String cmd=」select * from BaseInfo where major=?」;
PreparedStatement stmt=conn.prepreadStatement(cmd);
stmt.setString(1,」cs」);
調用存儲過程語句的建立:
String cmd=「CALL LIST_ON_MAJOR(‘CS’)」;
CallabelStatement stmt=conn.prepareCall(cmd);
聲明語句的執行:使用SQL語句對數據庫執行的操做一般分爲兩類:一是查詢數據庫信息;二是操縱數據庫數據。查詢數據庫信息操做須要返回查詢結果集,操縱數據庫操做須要返回操縱成功的記錄數,因此Statement接口提供兩種不一樣的執行方法完成兩類操做。
查詢數據庫信息:ResultSet rs=stmt.executeQuery(「select * from BaseInfo」);
操縱數據庫數據:ResultSet rs=stmt.executeUpdate(「insert into BaseInfo values(‘02010534’,’xiaoming’,’CS’)」);
聲明語句的釋放:語句使用完畢,釋放語句對象是良好的編程風格:stmt.close();
(4)結果集
數據庫建立結果集類型:
l read-only:只容許讀取查詢結果,讀取順序從頭至尾值只能讀一次。
l scroable:容許反覆隨機讀取查詢結果的任意記錄。
l updateable容許對結果集做插入、修改和刪除操做,並直接反應到後臺數據庫。
結果集類提供了方法getType()檢查結果集的類型,方法getConcurrency()檢查當前記錄的可操做類型。
結果集類型:
TYPE_FORWORD_ONLY:
結果集爲只讀類型,而且讀取順序從頭至尾值讀取記錄,只能讀一次
TYPE_SCROLL_SENSITIVE:
在他人同時對數據庫操做時,會影響結果集中的紀錄。
TYPE_SCROLL_INSENSITIVE:
在他人同時對數據庫操做時,不會影響結果集中的紀錄。
當前記錄操做類型:
CONCUR_READ_ONLY:結果集是隻讀的,不能改變當前記錄。
CONCUR_UPDATEABLE:結果集能夠修改的,能夠修改記錄的值,插入記錄,刪除記錄。
在進行記錄的修改操做時,一般要先檢查可操做類型,: if(rs.getCurrency()!=ResultSet.CONCUR_UPDATEABLE) system.err.println(「Error,cannot change rs」);
• 結果集接口提供了next()方法,使遊標向後移動一條記錄,previous()方法使遊標向前移動一條記錄,組合使用這兩個方法就能夠實現訪問結果集任意記錄。
• 遍歷一個記錄集的方法爲:
• ResultSet rs=...
• while(rs.next()){
• ... ...
• }
訪問字段記錄:
• 結果集接口提供了一系列的getXXX方法訪問字段的值,XXX表示返回值的類型,調用格式爲:
rs.getXXX((index/fieldname)
得到結果集信息:
• 在操做結果集時,常常須要得到一些額外的信息,如記錄數、列名稱等等,ResultSetMetaData接口經過元數據(Metadata)提供一個特定結果集的相關信息。例如:下面代碼顯示數據庫的全部列信息:
• ResultSetMetsData MetaData=rs.getMetaData();
• int num_columnes=MetaData.getColumnCount();
• for (int i=1;i<=numColumns;i++){
• Sytem.out.print(「column」);
• Sytem.out.print(i); /*列位置*/
• Sytem.out.print(「name:」);
• Sytem.out.print(MataData.getColumnName(i));/*列名稱*/
• }
定位記錄:
• 使用absolute()方法能夠定位到肯定的一條記錄上,例如:定位到第10條記錄的語句爲:
rs.absolute(10)
刪除記錄:
• 使用deleteRow()方法能夠刪除到當前的一條記錄上,例如:刪除第5條記錄的語句爲:
rs.absolute(5);
rs.deleteRow()
修改記錄:
rs.updateXXX(Index, value);
例如:修改全部記錄的major字段爲」IT」的語句爲:
ResultSet rs=...
ResultSetMetaData MetaData=rs.getMetaData();
int index_major=rs.findColumn(「major」);//返回字段major的序號
if(rs.getCurrency()!==Result.CONCUR_UPDATEABLE)
{ system.err.println(「Error,can not change rs 」);
return;
}
while(rs.next())
{ rs.updateString(index_major,」IT」);
}
插入記錄:
• 爲插入一條新記錄,ResultSet專門建立了一條特殊的記錄行,插入一條新紀錄的步驟爲:
• (1)調用movetoInsertRow()方法將遊標指向插入行;
• (2)使用UpdateXXX()方法修改插入行字段值;
• (3)調用insertRow()方法將新記錄加入到數據庫;
• (4)調用movetoCurrentRow()返回當前修改行;
例如增長一條學生記錄的語句爲:
ResultSet rs=...
if(rs.getCurrency()!==Result.CONCUR_UPDATEABLE)
{ system.err.println(「Error,can not change rs 」);
return;
}
rs.movetoInsertRow();
rs.UpdateString(1,」02010625」);
rs.UpdateString(2,」yulei」);
rs.UpdateString(3,」IT」);
rs.insertRow();
rs.movetoCurrentRow();
-------------------------------------------------------------------------------
JDBC
一、 JDBC使用
java數據庫鏈接
API分爲兩部分:java程序員java.sql、javax.sql包、jdbc驅動程序開發人員
Driver:驅動程序
DriverManager:驅動程序的管理類,利用鏈接字符串測試已註冊的一個或多個驅動中哪一個可用
Connecton:數據庫鏈接
Statement:數據庫的操做對象,PreparedStatement預編譯、CallableStatement存儲過程等
ResultSet:結果集
DataBaseMetaData(經過Connection得到,isReadOnly),ResultSetMetaData(經過ResultSet得到,rowCount),元數據有關容器自己結構方面的數據
Types:類型
開發步驟:
註冊驅動:三種方式(類加載器Class.forName,直接實例化驅動new ,使用java -Djdbc.drivers屬性)
創建鏈接:DriverManager.getConnection()——Driver.connect (PPT19檢索鏈接示意圖)
建立Statement:createStatement,preparedStatement
執行SQL:無改變的傳至數據庫
處理結果集:while(rs.next()){rs.getInt…… setter/getter}
關閉鏈接:ResultSet、Statement、Connection
二、 高級特性
元數據
事務:事務包含若干條數據庫操做,而且保證這些操做具備原子性,能夠正確的恢復 ACID
默認自動提交,setAutoCommit(false)——執行若干數據庫操做——提交/回滾
併發控制:髒讀、不可重複讀、幻讀
三、2.0核心特性
可滾動、可更新結果集:先後滾動+相對/絕對定位,經過結果集對數據庫進行增刪改
可更新結果集限制(單表、不能join、包含主鍵、不能爲空、不能有默認值)
批量更新:addBatch、executeBatch
新增長數據類型:clob、blob流式讀取(PPT67-69)
四、2.0擴展
數據源和JNDI:封裝了數據庫鏈接的具體細節,制定特定的邏輯名稱將其綁定到JNDI服務器上
鏈接池:利用對可重用數據庫鏈接對象的緩存來提升數據庫鏈接效率(犧牲空間換時間)
行集RowSet(繼承ResultSet):ResultSet(可滾動可更新)+Statement+Connection
Hibernate
JDBC適用於數據量較大、表之間關係較爲簡單
Hibernate適用於數據量較小、表之間關係較爲複雜
一、 概述
對象持久化:序列化、保存在數據庫(CRUD)
對象關係映射:java對象和關係型數據庫之間的映射(類——表,對象——條目,屬性——字段,關係——表間關係或表)
PPT 8 Hibernate應用程序結構
Session:鏈接和事務之間,非線程安全,輕量級,一線程一session
Sessionfactory:獲取Session,線程安全,重量級,多線程共享,緩存
Configuration:配置對象,讀取hbm.cfg.xml,*.hbm.xml,建立SessionFactory
Transaction:jdbc事務/jta事務
Query:執行HQL
二、 實體映射
id生成方式(oid獨立於數據庫,惟一,與業務無關,簡化對象到表的映射):native、hilo、seqhilo、sequence(DB2)、increment、identity(DB2)、assigned(默認)、foreign、uuid-hex等等
映射類型:java類型和SQL字段類型的映射類型
integer、string、class(java.lang.Class——varchar2類全限定名)、clob、blob
三、 持久化對象的管理
對象狀態:暫態(new建立、與session無關、沒有id)、持久態(session管理、有id)、遊離態(session管理過了、有id)
狀態管理 PPT38
get(直接查數據庫,找不到返回null)和load(先查緩存,找不到拋異常)
list(Query接口下)、find(直接查數據庫)和iterate(先經過id查緩存,找不到再去查數據庫)
close、clear、evict、lock、saveOrUpdate、delete
自動髒檢查
批量處理:循環save,超過限量會報錯
Hibernatenate查詢方式:根據id查詢(單個)、HQL(經常使用、跟SQL相似、面向對象、只被Hibernate支持、不限制DB類型)、Criteria(模糊匹配、動態查詢、只被Hibernate支持)、Native SQL(適用於不熟悉Hibernate,有些HQL不能實現的SQL,指定DB類型)
四、 實體映射
關聯關係:單向、雙向one-to-one(惟一外鍵、共享主鍵)one-to-many、many-to-many
inverse(true放棄維護關係,one方寫)、lazy(延遲加載帶來的問題?fetch)
傳播性持久化:cascade:all、save-update、delete、delete-orphon、all-delete-orphon
組件映射:某些對象不要求共享,不必從新分配一張表
集合映射:set(無序不重複)、bag(無序可重複,list實現)、list(有序可重複)、map(鍵值對)
繼承映射:
table-per-class(支持多態、表太多)、table-per-concrete-class(表較少、重複定義屬性、不支持多態)、table-per-class-hierarchy(表最少、表可能很大、支持多態)
五、 事務和併發控制
提交(某些查詢,commit,flush)setFlushMode
beginTransaction——commit
讀未提交(1)——讀提交(2)——重複讀(4)——串行(8)
應用程序事務:悲觀鎖(慎重使用、效率過低)、樂觀鎖(version、timestamp)
六、 高級查詢
分頁setFirstResult、setMaxResult
NamedQuery(查詢語句寫在映射文件按中)
集合過濾session.createFilter()
報表查詢:like、投影、函數lower、分組、distinct、count(*)
join(fetch 解決延遲加載問題)
參數綁定(位置從1開始,名稱:name)