JDBC複習,oracle的blob,clob的讀寫-zhai

luxika發表於2012-04-13
http://hi.baidu.com/annleecn/blog/item/ff2fdb17e7a9e915972b4381.html

JDBC複習

JDBC驅動程式的型別:
JDBC-ODBC橋;部分本地API,部分JAVA驅動程式;JDBC網路純JAVA驅動程式;本地協議純JAVA驅動程式。
最後一種是訪問資料庫效率最高的。目前應用最多的也是這種。

不同資料庫的連線URL如下:
sqlserver:jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs
ORACLE:jdbc:oracle:thin:@localhost:1521:ORCL
mysql:jdbc:mysql://localhost:3306/databasename

CallableStatement物件用於執行SQL儲存過程。
CallableStatement cstmt = conn.prepareCall("call p_changesal(?,?)");
cstmt.registerOutParameter(2, java.sql.Types.INTERGER);//註冊OUT型別的返回引數
cstmt.setInt(1, 98);
cstmt.execute();
int sal = cstmt.getInt(2);

可以呼叫ResultSet.getMetaData()方法來獲取ResultSetMetaData物件,再獲取後設資料。

一個Statement物件在同一時刻只有一個開啟的ResultSet物件,在Statement介面中定義的所有executeXXX()方法都隱含地關閉Statement當前的ResultSet物件。如果你要執行多個查詢語句,並且需要同時對它們的結果集進行操作,那麼你必須使用多個Statement物件。

連線池技術預先建立多個資料庫連線物件,然後將連線物件儲存到連線池中,當客戶請求到時,從池中取出一個連線物件為客戶服務,請求完成後,客戶程式呼叫close()方法,將連線物件放回池中。

常用埠:ftp:21 telnet:23 oracle:1521 mysql:3306 sqlserver:1433

註冊資料庫驅動的3種方式:
1,Class.forName( driverName ) 如:Class.forName("oracle.jdbc.driver.OracleDriver"):
2,Driver drv = new DriverConstructor();
DriverManager.registerDriver(drv);
如:Driver drv = new Oracle.jdbc.driver.OracleDriver();
DriverManager.registerDriver( drv );
3,java -Djdbc.drivers = oracle.jdbc.driver.OracleDriver;這種方式只能註冊一個driver,命令列註冊方式
方法1最好

建立連線3種方式:
getConnection( String url ) //匿名訪問
getConnection( url, Properties info) //要一個properties對
getConnection( url, username, password) //最常用

PreparedStatement繼承自Statement
Statement 1,不適合有多個引數的SQL;2,不適合重複執行同構的SQL

Statement tem = conn.createStatement();

PreparedStatement pstm = conn.prepareStatement("select * from t_user where id = ?");
pstm.setString(1, "21"); //下標從1開始
pstm.executeQuery();

CallableStatement:專用於呼叫伺服器的儲存過程

Statement裡的方法:
executeQuery( sql ) 返回ResultSet
execute( sql ) 返回boolean,是否有ResultSet返回
executeUpdate( sql ) 返回int,影響的記錄行數

字元轉換:
java -------------> oracle:ISO-8859-1
Unicode:gb2312(GBK)
如:String name = "張三";
gb2312---->ISO-8859-1:
String newName = new String(name.getBytes("gb2312"), "ISO-8859-1");
ISO-8859-1------->gb2312:
String newName = new String(name.getBytes("ISO-8859-1"), "gb2312");

從ResultSet裡面取值:
while(rs.next()){
String name = rs.getString("name");
}

關閉:
if(null != rs){
try{
rs.close();
}catch(Exception e){

}
}
statement,connection一樣要先判斷非空,後關閉

SQLWarning:理論上的,不影響程式執行,不用處理;
SQLException裡的方法:getErrorCode:返回錯誤碼;getMessage:返回錯誤資訊

後設資料:DatabaseMetaData,ResultSetMetaData
conn.getMetaData(); rs.getMetaData();
檢視資料庫中表的資訊

事務處理流程:
1,關閉自動提交;2,執行操作;3,處理資料;rollback或commit;4,開啟自動提交
commit不僅是原有事務的結束,也是新事務的開始。

併發控制:
事務級別:transaction_none; transaction_read_uncommitted(預設); transaction_read_committed:解決髒讀dirty read
transaction_repeateable_read:解決不可重複讀的問題:non_repeated read
transaction_serializable:解決幻讀:phantom read

oracle只支援read_commit和serializable
例如:conn.setTransactionIsolation( Connection.TRANSACTION_READ_COMMITTED );

回滾集的問題:
CONCUR_READ_ONLY, CONCUR_UPDATEABLE:
用來指定可不可以修改資料庫:
TYPE_FORWARD_ONLY 預設
TYPE_SCROLL_INSENSITIVE, TYPE_SCROLL_SENITIVE
用來指定Result能不能滾動
可以用refreshRow重新整理當前行。
例:Statement stm = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATEABLE);

定位方法:全部返回boolean,除afterLast(), beforeFirst()復位,返回void
absolute(int row) 傳輸絕對定位
first(), last(), next(), previous()向前一位
relative(int ) 相對定位
isAfterLast(), isBeforeFirst(), isFirst(), isLast();
注意:指標一開始是指在第一行的前面。

可更新結果集:
rs.updateInt(1, 9911); //更新當前行
rs.updateString("name", "tony");
rs.updateRow(); //修改生效,不呼叫則無效
rs.absolute(10);
rs.deleteRow(); //刪除第10條記錄
rs.cancelRowUpdates(); //放棄修改,刪除還是會生效

插入新行
rs.moveToInsertRow(); //建立一個空記錄
rs.updateInt("id", 11);
rs.updateString("name", "rose");
rs.insertRow();
rs.moveToCurrentRow(); //修改生效
rs沒有主鍵則不能插入資料,必須包含所有的無預設值的非空欄位,只能查一個表,不能連線查詢,查詢結果必須包含主鍵

如果是插入的話,必須選擇表中所有不能為空的列。

批量處理:batch
con.setAutoCommit(false); //關閉自動提交
Statement stm = con.createStatement();
stm.addBatch("insert into t_user(id) value(11)");
stm.addBatch(" ... ");
int[] results = stm.executeBatch(); //返回所有成功的操作結果
con.commit();
con.setAutoCommit(true); //恢復自動提交

高階資料型別:
Blob ------ SQL Blob //大二進位制物件 binary large object
Clob ------ SQL Clob //大文字二進位制物件character large object
Array ----- SQL Array
Struct ---- SQL structure Type
Ref ------- SQL REF

方法:getXXX, setXXX, updateXXX
步驟:1,獲得資料庫連線,2,向表中插入一個空的Blog欄位,3,獲得Blob的輸出流,4,通過輸入流將資料寫入資料庫
如:
try{
conn.setAutoCommit(false);
Blob blob = null;
PreparedStatement pstm = conn.prepareStatement("insert into t_blob(id,filename,blobData) value

(?,?,empty_blob())"); //empty_blob()函式由oracle提供,用來建立空物件
pstm.setInt(1,10);
pstm.setString(2,"d:/hello.mp3");
pstm.executeUpdate(); //插入空值
pstm.close();

pstm = conn.prepareStatement("select blobData from u_blob where filename = ? for update"); //for update

同步必須使用,只能在查詢時使用
pstm.setString(1, "d:/hello.mp3");
rs = pstm.executeQuery();
if(rs.next()){
Blob b = rs.getBlob();
oracle.sql.BLOB ob = (oracle.sql.BLOB)b;
OutputStream os = ob.getBinaryOutputStream();
InputStream is = new FileInputStream("d:/hello.mp3");
byte[] buffer = new byte[4096];
int len = 0;
while(true){
len = is.read(buffer);
if(-1 == len) break;
os.write(buffer, 0, len);
}
is.close();
os.close();
conn.commit();
}
}catch(Exception e){
conn.rollback();
}finally{
}

查詢:
conn.setAutoCommit(false);
pstm = conn.prepareStatement("select blobData from u_blob where name = ? for update");
rs = pstm.executeQuery();
if(rs.next()){
blob b = rs.getBlob(1);
InputStream is = b.getBinaryStream();
OutputStream os = new FileOutputStream(path);
byte[] bb = new byte[4096];
int len = 0;
while(true){
len = is.read(bb);
if(len == -1) break;
os.write(bb, 0, len);
}
}

DataSource
WebLogic:services----->JDBC---->connection pool

JNDI:java naming directory interface api

用DataSource建立connection步驟:1,獲得資料庫連線,2,支援連線池,3,通常可以支援JNDI,4,支援分散式事務

OID:object id:物件在資料庫中的ID

OOAD:object orient analyze and design物件導向的分析與設計

ODBC:open database connectivity:開放的資料庫連線

JDBC:java database connectivity:java資料庫連線

JDBC驅動程式可分為4類:
1,JDBC-ODBC橋; 2,部分本地API,部分JAVA驅動程式; 3,JDBC網路純JAVA驅動程式; 4,本地協議純JAVA驅

動程式,這個效率最高

Driver介面:
SQLSERVER:com.microsoft.jdbc.sqlserver.SQLServerDriver
jdbc:microsoft:sqlserver://IP:1433;資料庫名,使用者名稱,密碼

MySQL:com.mysql.jdbc.Driver
jdbc:mysql://IP:3306/資料庫名,使用者名稱,密碼

DB2:com.ibm.db2.jdbc.app.DB2Driver()
jdbc:db2://IP:埠/資料庫名,使用者名稱,密碼

oracle:jdbc:oracle:thin:@IP:PORT,DBname,user,password

pointbase:jdbc:pointbase:server://ip:port,dbname,user,password
com.pointBase.jdbc.jdbcUniverSqlDriver

DriverManager類是驅動程式管理器類,所有方法都是靜態的,一個statement物件在同一時刻只有一個開啟的ResultSet物件,在

statement介面中定義的所有executeXXX()方法都隱含地關閉statement當前的ResultSet物件,如果你要執行多個查詢語句,並且需

要同時對它們的結果集進行操作,那麼你必須使用多個statement物件。

DataSource例子:
javax.naming.context ctx = new javax.naming.InitialContext();
//JNDI名是相對於java:comp/env上下文的,因此在程式中利用JNDI名查詢資料來源物件時,要加上java:comp/env/
javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup("java:comp/env/bookstore");
java.sql.Connection conn = ds.getConnection();

相關文章