?? day02.txt
字號:
JDBC_day02 langna 2007-9-7 星期五
wanghg@tarena.com.cn
回顧:
con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
"xjh0704", "xjh0704");
另外一種注冊方法:
Properties p = new Properties();
p.setProperty("user", "xjhsd0704");
p.setProperty("password", "xjhsd0704");
Connection con = d.connect("jdbc:oracle:thin:@192.168.0.20:1521:tarena", p);
另外一種方式:
jdbc:oracle:thin:xjh0704/xjh0704@192.168.0.20:1521:tarena
java類型是靜態類型,編譯器檢查類型;字符串只檢查類型,不檢查內容;
注意:
同一個statement 得到結果集之后沒有去遍歷結果集,
而是做了其他操作(插入或修改)的話,結果集就不能用了,為空了;
先做插入或修改操作,然后再得到結果集去遍歷,不會有什么問題;
一、設計
封裝:避免重復的代碼;
抽象:將具體的細節、量抽出來,把邏輯,形式留下;
依賴倒轉:原來的設計是寫具體的類,依賴倒轉就是將具體的抽取出來;
寫一個工具類:JdbcUtil ,方法都設成靜態方法;
加載驅動放到初始化代碼塊里;只加載一次就行;
public class JdbcUtil {
//靜態代碼塊加載驅動;
static{
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//得到數據庫連接
public static Connection getConnection(){
Connection con =null;
try {
con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
"xjh0704", "xjh0704");
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//釋放數據庫資源
public static void close(ResultSet rs,Statement stmt,Connection con){
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(con!=null){
try{
con.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
//重載一個關閉方法
public static void close(Object o){
try{
if(o instanceof ResultSet){
((ResultSet)o).close();
}else if(o instanceof Statement){
((Statement)o).close();
}else if(o instanceof Connection){
((Connection)o).close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
二、PreparedStatement概述;預編譯的
1、概括:與Statement比較
效率高;
清晰(類型);
結構:1、SQL參數化(Statement中SQL是純字符串的)
2、SQL預編譯
Statement 將 SQL 送到數據庫 ---> 編譯---> 運行---> 再返回給應用程序
有1000條記錄的話就送1000次;編譯1000次,運行1000次;
相當于sqlplus ,一條命令執行一次;
Preparement "insert into t_test values(?,?)" //占位符;
---> 發到數據庫可以編譯但不能運行---> 等參數傳過來再運行;
有1000條記錄,編譯一次,運行1000次;
************************************
Statement stmt=null;
stmt = con.createStatement();
sql="insert into t_test values(1,'tony')"
//直接送sql語句;象一個表達式
stmt.executeUpdate(sql);
***********************************
PreraredStatement ps=null;//象方法一樣
sql="insert into t_test values(?,?)");
//1、準備一條sql語句
ps=con.prepareStatement(sql);
//2、往ps對象設置參數值;檢查類型是否兼容;
ps.setInt(1,8);
ps.setString(2,"Tony");
//3、送到數據庫執行
ps.executeUpdate();
2、SQL:同構;sql語句除了參數不同其他都一樣;
異構:除了參數不同,其他地方有不同的就是異構的;
比如 insert 和 update;或者表不同也是異構的;
不管同構的還是異構的都用 PreparedStatement
同構的更能發揮它的優勢;
select 一般是異構的,但是執行一次返回一個結果集就行了;
update/insert 一般都是同構的,用PreparedStatement;
對客戶端來說并沒有減少工作量,但是對數據庫來說減少了工作量;
三、元數據:
1、 ResultSetMetaData
元數據是用來描述數據的數據,ResultSetMetaData就是來描述結果集的
列的類型和屬性信息,比如可以通過它得到結果集的列數,列名等。
具體可在API中查閱java.sql.ResultSetMetaData。
ResultSetMetaData對象可以通過ResultSet對象的getMetaData()來得到。
ResultSetMetaData對象有以下三個方法比較常用:
getColumnCount():獲得實際列數
getColumnName(int colnum):獲得指定列的列名
getColumnType(int colnum):獲得指定列的數據類型(Types里面的類型,存放的是整數)
getColumnTypeName(); 數據庫的類型
JDBC API :JDBC --- JAVA --- 數據庫類型
類型對照表:String 范圍
//1、獲取結果集元數據
ResultSetMetaData md=rs.getMetaData();
//2、從結果集元數據中讀取字段個數
int column=md.getColumnCount();
//3、利用元數據讀取字段名和字段值
for(int i=1;i<=column;i++) {
System.out.println(md.getColumnName(i)+"\t");
}
2、數據庫元數據:
DatabaseMetaData
getURL(),獲得連接數據庫的URL
getDatabaseProductName() 獲得數據庫產品的名稱
getDriverVersion() 獲得JDBC驅動程序的String形式的版本號
getUserName() 獲得數據庫用戶名。
ResultSet getTables(參數)獲得數據庫中該用戶的所有表
參數:
catalog : null ,
schema : 用戶名;如"OPENLAB"
table_name:表名,可以用通配符"%TEST"
types: 類型;是String[] 格式的;候選類型是:"TABLE"、"VIEW"、"SYSTEM TABLE"
//1獲取數據庫元數據
DatabaseMetaData dbmd=con.getMetaData();
//2讀取特定表信息;獲得結果集
String[] types=new String[1];
types[0]="TABLE";//必須是大寫
rs=dbmd.getTables(null, "OPENLAB","%", types);
//3遍歷結果集,輸出
四、事務Transaction
1、原子操作:不可分割的操作;
atom: 原子操作,代表不可再分操作;
2、事務:
事務就是將一組數據庫操作變為原子操作;事務是達成原子操作的一個途徑;
事務是針對原子操作的,要求原子操作不可再分,要求原子操作必須同時成功同時失敗。
事務是捆綁的原子操作的邊界。
事務由數據庫服務器來實現的,我們只是使用它;
我們寫的代碼,數據庫都將其設為自動提交;插入10條記錄就commit 10次;
使用事務的語法:
1) 關閉自動提交(開始一個用戶的事務);
con.setAutoCommite(false); 打開事務就要關閉自動提交。
如果不關掉,則是數據庫的事務,將每次提交作為一個事務;
不用事務時要把setAutoCommite(true);
2)正常的進行若干"相關"的數據庫操作;
3)如果一切正常,用戶可以選擇提交 con.commit();
也可以選擇回滾 con.rollback();
4)任何一個操作失敗,就回滾;在catch語句塊中con.rollback();
在提交和回滾時舊的事務結束,新的事務開始;
聲明一下:
從我最近對大家的觀察,發現有相當一部分同學上課并沒有好好去記筆記;
這樣對記憶還有學習的影響很不好,所以以后我不再給大家發筆記了,
希望大家自己上課好好聽課,好好記筆記。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -