JDBC編程步驟:
1.Load the Driver
1. Class.forName()|Class.forName().newInstance()|new DriverName()
2. 實例化時自動向DriverManager註冊,不需顯示調用DriverManager.registerDriver方法
2.Connect to the DataBase
1. DriverManager.getConnect()
3.Execute the SQL
1. Connection.CreateStatement()
2. Statement.executeQuery()
3. Statement.executeUpdate()
4.Retrieve the result data
1. 循環取得結果 while(rs.next())
5.Show the result data
1. 將數據庫中的各種類型轉換爲Java中的類型(getXXX)方法
6.Close
1.close the resulteset./ close the statement / close the connection
eclispe 裏面使用需要先把各種數據庫的驅動jar包加進來。
ProjectName右擊---Build Path--Add External Archives...--選本地的jar包。
循環取得數據(rs.next())
程序完美髮展:try-catch-finnaly
可打印出SQL語句,copy出來在Oracle-SQL*Plus裏面執行下試試SQL語句是否正常---Oracle
JDBC 進階:
1.介紹PreparedStatement:---省掉單引號出錯步驟。
Statement的子接口,insert into 插入數據時,對sql語句格式比較好用
PreparedStatement pstmt = conn.prepareStatement("insert into tablename values (?,?,?)");
pstmt.setInt(1,整數型變量);---指定欲插入第一列的值
pstmt.setString(2,字符串型變量);
pstmt.setString(3,字符串型變量);
pstmt.executeUpdate();---執行SQL語句
2.對存儲過程進行調用。
存儲過程示例:
SQL> create or replace procedure p
(v_a in number, v_b number, v_ret out number, v_temp in out number )
is
begin
if(v_a > v_b) then
v_ret := v_a;
else
v_ret := v_b;
else if;
v_temp := v_temp + 1;
end;
/
調用數據庫中的procedure。
CallableStatement 是 PreparedStatement,Statement的子接口。
CallableStatement cstmt = conn.prepareCall("{call p(?,?,?,?)}");
cstmt.registerOutParameter(3, Typer.INTEGER); //在JDBC中註冊輸出參數及輸出類型。
cstmt.registerOutParameter(4,Typer.INTEGER); //同上。Typer類在sql包裏面
cstmt.setInt(1, 3);
cstmt.setInt(2, 4);
cstmt.setInt(4, 5);
cstmt.execute();
3.批處理
一個Statement處理多條SQL語句。
1.Statement執行批處理
Statement stmt = conn.createStatement();
stmt.addBatch("insert into dept2 values (51, '500','haha')");
stmt.addBatch("sql語句");
stmt.addBatch("...");
stmt.executeBatch();
stmt.close();
2.PreparedStatement 執行批處理。
PreparedStatement ps = conn.prepareStatement("insert into dept2 values (?,?,?)");
ps.setInt(1,61);
ps.setString(2,"haha");
ps.setString(3,"bj");
ps.addBatch();
ps.setInt(1,62);
ps.setString(2,"haha");
ps.setString(3,"bj");
ps.addBatch();
...
ps.executeBatch();
ps.close();
4.運用事務處理
Transaction問題-(轉賬的問題)兩條或多條SQL語句必須同時執行成功或者同時不成功。保持數據的一致性
默認SQL語句是自動提交的。
try {
...
...
conn.setAutoCommit(false);
stmt = conn.createStatement();
stmt.addBatch("insert into dept2 values(51, '500', 'haha')");
stmt.addBatch(sql 語句);
stmt.addBatch(...);
stmt.executeBatch();
conn.commit();
conn.setAutoCommit(true);
} catch(ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
try {
if(conn != null) {
conn.rollback(); //sql失敗,連接不爲空,程序回滾。
conn.setAutoCommit(true);
}
} catch(SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if(stmt != null)
stmt.close();
if(conn !=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
5.Moveable ResultSet(可前後移動的結果集)
Rs.last()
Rs.getRow()返回值可以確定一共有多少條記錄。
此處不同數據庫廠商有點不同,有些不支持。Oracle支持。//現在幾乎都支持。
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,//對滾動不敏感,可以任意滾動。
ResultSet.CONCUR_READ_ONLY);//併發只讀。
ResultSet rs = stmt.executeQruery("select * from emp order by sal");
rs.next();
System.out.println(rs.getString(1));//字段順序也可用字段名來定位
rs.last();//定位到最後一條記錄。
rs.isLast();//是否是最後一條記錄
rs.isAfterLast();//是否是最後一條的下一條記錄。
rs.previous();//前一條記錄
rs.getRow();//第幾條記錄
rs.absoulute(6);//直接定位到第幾條(六)
rs.close();
6.Updatable ResultSet(*)---掌握與否,都OK
很多數據庫廠商不支持。oracle不支持,mySQL支持。
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,//對滾動不敏感,可以任意滾動。
ResultSet.CONCUR_UPDATABLE);//併發可修改。
ResultSet rs = stmt.executeQruery("select * from emp2");
rs.next();
//更新一行數據。
rs.updateString("ename","AAAA");
rs.updateRow();
//插入新行
rs.moveToIsertRow();
rs.updateInt(1,9999);
rs.updateString("ename","AAAA");
rs.updateInt("mgr",7839);
...
rs.insertRow();
//將光標移動到新建的行
rs.moveToCurrentRow();
//刪除行
rs.absolute(5);
rs.deleteRow();
另外:
JDBC新增兩個接口:j2ee標準 //javax.sql包裏
1.DataSource
DriverManager的替代
連接池實現
分佈式實現---DataSource的屬性可以動態改變
2.RowSet
新的ResultSet,從ResultSet繼承。
支持斷開的結果集
支持JavaBean標準