用Java程式設計語言和JDBC開發的程式是可以跨平台啟動並執行,並且是不受供應商限制的.
4.1 JDBC的設計
JDBC由兩層組成,上面一層是JDBC API,負責與JDBC管理器驅動程式API進行通訊,將各個不同的SQL語句發送給它;該管理器(對程式員是透明的)再與實際串連到資料庫的各個第三方驅動程式進行通訊,並且返回查詢的資訊,或者執行由查詢規定的操作.
JDBC驅動程式分為以下幾種類型:
類型1驅動程式
負責將JDBC轉換為ODBC,並且使用一個ODBC驅動程式與資料庫進行通訊
類型2驅動程式
部分使用Java程式設計語言編寫的和部分使用機器碼編寫的驅動程式,用於與資料庫的客戶機API進行通訊
類型3驅動程式
純粹的Java客戶程式庫,它使用跨資料庫協議,將資料庫訪問請求傳輸給伺服器組件,然後該伺服器組件將訪問請求轉換成特定的資料庫協議
類型4驅動程式
純粹的Java庫,用於JDBC訪問請求直接轉換成特定資料庫協議
4.2 結構化查詢語言 (SQL)
JDBC是個到SQL(結構化查詢語言 (SQL))的介面,而SQL實際上是與所有最新型的關聯式資料庫之間的介面.
4.3 安裝JDBC
建議最好不要使用Java2 SDK配備的JDBC/ODBC橋接器驅動程式,更加反對將該驅動程式用於Access這樣的案頭資料庫.
4.4 JDBC編程的基本概念
1. 資料庫URL
文法: jdbc:subprotocol name:other stuff
其中subprotocol特定驅動程式, other stuff參數的格式要根據它使用的子協議而定.
2. 建立串連
Class.forName(驅動程式類); 註冊驅動程式
String url = …;
String username = …;
String password = …;
Connetion conn = DriverManager.getConnection(url, username, password);
讀取屬性檔案建立串連
Properties props = new Properties();
FileInputStream in = new FileInputStream(“database.properties”);
props.load(in);
in.close();
String drivers = props.getProperty(“jdbc.drivers”);
String url = props.getProperty(“jdbc.drivers”);
String username = props.getProperty(“jdbc.username”);
String password = props.getProperty(“jdbc.password”);
Connetion conn = DriverManager.getConnection(url, username, password);
3. 執行SQL命令
Statement stat = conn.createStatement();
String sql = …;
ResultSet rs = stat.executeQuery(sql);/stat.executeUpdate(sql);
while(rs.next()){
…
}
4. 進階SQL類型
Blob b=resultSet.getBlob(1);
InputStream bin=b.getBinaryStryeam();
Clob c=resultSet.getClob(2);
Reader cReader=c.getCharacterStream();
寫入:
FileInputStream fis=new FileInputStream(f,Connection conn);
byte[] buffer=new byte[1024];
data=null;
int sept=0;int len=0;
while((sept=fis.read(buffer))!=-1){
if(data==null){
len=sept;
data=buffer;
}else{
byte[] temp;
int tempLength;
tempLength=len+sept;
temp=new byte[tempLength];
data=temp;
len=tempLength;
}
if(len!=data.length()){
byte temp=new byte[len];
data=temp;
}
}
String sql="insert into fileData (filename,blobData) value(?,?)";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,f.getName());
ps.setObject(2,data);
ps.executeUpdate();
讀出:
try {
Clob c=resultSet.getClob(2);
Reader reader=c.getCharacterStream():
if (reader == null) {
return null;
}
StringBuffer sb = new StringBuffer();
char[] charbuf = new char[4096];
for (int i = reader.read(charbuf); i > 0; i = reader.read(charbuf)) {
sb.append(charbuf, 0, i);
}
return sb.toString();
} catch (Exception e) {
return "";
}
4.5 執行查詢操作
採用宿主變數方式:
String userId = 1;
String sql = “select * form user where user_id=?”;
PreparedStatement pStat = conn.prepareStatement(sql);
pStat.setString(1,userId);
ResultSet rs = pStat.executeQuery();
4.6 可滾動的和可更新的結果集
1. 可滾動的結果集
Statement stat = conn.createStatement(type,concurrency);
或
PreparedStatement stat = conn.prepareStatement(command,type, concurrency);
其中
Type包括:
ResultSet.TYPE_FORWARD_ONLY 不能滾動
ResultSet.TYPE_SCROLL_INSENSITIVE 可以滾動,但變化不敏感
ResultSet.TYPE_SCROLL_SENSITIVE 可以滾動,但變化敏感
Concurrency包括:
ResultSet.CONCUR_READ_ONLY 不能更新
ResultSet.CONCUR_UPDATABLE 可以更新
常用方法:
rs.previous() 滾動結果集
rs.relative(n) 將游標向後或向前移動n行
rs.absolute(n) 將游標設定到某個特定的行號上
rs.getRow() 獲得當前的行號
2. 可更新的結果集
常用方法:
rs.getConcurrency() 查看結果集是否可更新
rs.updateXxx() 只能用於修改行的值,不能修改資料庫
rs.updateRow() 將當前行中所有資訊更新發送給資料庫
rs.cancelRowUpdates() 撤銷對當前行的更新
rs.moveToInsertRow() 將游標移到一個特定的位置
rs.insertRow() 將該新行傳遞給資料庫
rs.moveToCurrentRow() 將游標移回之前位置
rs.deleteRow() 刪除游標下的行
例子:
rs. moveToInsertRow();
rs.updateString(“Title”,title);
rs.updateString(“Isbn”,isbn);
rs.insertRow();
rs.moveToCurrentRow();