JDBC編程學習總結

JDBC:數據庫連接, 通過接口實現不同數據庫之間的切換, 面向接口編程

JDBC驅動程序將JDBC調用映射成特定的數據庫調用
驅動類型:
1.JDBC驅動:JDBC-ODBC橋,最早的實現方式,將JDBC API映射到ODBC API,Java8中已刪除
2.直接將JDBC API映射成數據庫特定的客戶端API,次驅動包含特定數據庫的本地代碼,用於訪問特定數據庫的客戶端
3.支持3層結構的JDBC訪問方式,用於Applet,通過Applet訪問數據庫
4.直接與數據庫實例交互,使用數據庫底層協議

JDBC用法:

DriverManager: 管理JDBC驅動服務類, 用於獲取Connection對象; 包含靜態方法: synchronized Connection getConnection(String url,String user,String pass) throws SQL Exception

Connection(接口):連接數據庫, 以下方法拋出SQLException
常用方法:Statement createStatement()//返回一個Statement對象
PreparedStatement prepareStatement(String sql)//返回預編譯的Statement對象(將sql交給數據庫預編譯)
CallableStatement prepareCall(String sql)//返回CallableStatement對象,用於調用儲存
PrepareStatement,CallableStatement是Statement子類
控制事務的方法:
Savepoint setSavepoint()//創建保存點
Savepoint setSavepoint(Stiring name)//指定名字創建
void setTransactionIsolation(int level)//設置事務隔離級別
void rollback()//回滾事務
void rollback(Savepoint savepoint)//將事務回滾到指定保存點
void setAutoCommit(bollean autoCommit)//關閉自動提交,打開事務
void commit()//提交事務
void setSchema(String schema)//設置數據庫Schema, getSchema()//獲取Schema

Statement:執行SQL語句工具類,可用於執行DDL,DCL,DML
ResultSet executeQuery(String sql)//只執行查詢語句
int executeUpdate(String sql)//執行DML/DDL語句,返回受影響的行數/0
boolean excute(String sql)//執行任何SQL語句,執行第一個結果返回Result,返回true,其餘爲false

PreparedStatement: 預編譯Statement對象,爲Statement的子接口,使用PreparedStatement執行SQL語句無需多次傳SQL語句,只需傳對應參數
相比於Statement多增加了void setXxx(int parameterIndex,Xxx value)//傳入值根據索引位置傳給指定SQL指定位置的參數
具有executeUpdate, executeQuery, execute方法,無需接收SQL字符串,只需傳參數

ResultSet: 結果集對象(包含查詢結果的方法), 通過索引或列名獲取列數據
void close()//釋放ResultSet對象
boolean absolute(int row)//將結果集的記錄指針移動到row行,row爲負,移動到倒數row行, 指向有效記錄時返回true
void beforeFirst()//將記錄指針移動到起始位置的前一行
boolean first()//指針移動到首行,有效記錄返回true
boolean previous()/next()//移動到上/下一行
boolean last()//最後一行
void afterLast()//最後一行之後
當移動到指定行,使用getXxx(int columnIndex)/getXxx(columnLabel)獲取當前行列指定值

JDBC編程步驟:

1.加載驅動使用Class類的靜態方法forName(), 加載MySQL驅動: Class.forName(“com.mysql.jdbc.Driver”);
2.通過DriverManager獲取數據庫連接: DriverManager.getConnection(String url,String user,String pass) 注:url寫法固定,mysql: jdbc:mysql://hostname:port/databasename
3.通過Connection對象創建Statement對象: createStatement()/prepareStatement(String sql)/prepareCall(String sql)
4.使用Statement執行sql語句:execute()/executeUpdate()/executeQuery()
5.操作結果集: executeQuery()返回ResultSet對象,內部保存了SQL語句查詢結果,使用ResultSet中的方法對內部結果進行查看
6.回收數據庫資源: ResultSet, Statement, Connection

使用executeLargeUpdate執行DDL/DML 使用方式與executeUpdate一致
使用execute執行SQL語句: 通常情況不使用; 返回值爲boolean類型(判斷是否執行SQL語句)例: boolean hasResult=st.execute(sql);//使用ResultSet rs=st.getResultSet()獲取返回的Result對象, 使用getUpdateCount(),獲取Statement()執行DML語句影響的記錄行數

管理結果集

ResultSet默認的記錄指針移動方式(next()), 如果需要改變記錄指針的移動方式需要在創建Statement/PreparedStatement對象傳入參數:
resultSetType:
1.ResultSet.TYPE_SCROLL_INSENSITIVE//常量可控制記錄指針自由移動,底層數據改變不影響ResultSet內容
2.ResultSet.TYPE_SCROLL_SENSITIVE//同上,但底層數據改變會影響ResultSet的內容
上述兩者的區別在於數據庫驅動

resultSetConcurrency:
1.控制ResultSet的併發類型
2.執行完executeQuery後返回的ResultSet對象使用updateXxx(int columnIndex,Xxx value)可用於更新數據庫指定位置的數據(更新結果集必須滿足:所選的數據必須來自同一個表,選出的數據中必須包含主鍵列), 使用updateRow()提交修改
注: Java8提供updateObject(String columnLable/int columnIndex,Object x,SQLtype targetSQLType);來直接修改記錄指針所指向的記錄
1.ResultSet.CONCUR_READ_ONLY:只讀的併發模式(默認)
2.ResultSet.CONCUR_UPDATABLE:可更新的併發模式
例: PrepareStatement pstm=coon.PrepareStatement(sql,Result.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs=pstm.executeQuery();
rs.last();int rowCount=rs.getRow();
for(int i=rowCount;i>0;i–){
rs.absolute(i); rs.updateString(2,“學生名”+i);
rs.updateRow();//提交修改; 從後的行的位置將每行的student的名字做修改
}
執行execute/executeQuery/executeUpdate將會返回ResultSet對象(採用移動記錄指針查看修改後的效果, 條件是在知道表結構,採用rs.next(),rs.getXxx()查看)

PreparedStatement執行SQL(需要反覆執行)
使用佔位符"?“放置到合適的位置, Statement不允許使用佔位符”?", 出現PrepareStatement作爲Statement的子接口
例:PreparedStatement ps=conn.preparedStatement(“insert into myJava_test (test_name)values”+ “(?)”);
PreparedStatement可用於防止SQL注入
舉個例子: 將用戶登錄的賬號或密碼進行拼接作爲去數據庫查找的數據, 一些特定的字符串會導致, 不用賬號密碼也能登陸, 比如:‘or true or’,
PreparedStatement相比於Statemnet可以做到: 預編譯SQL語句,無需SQL拼接(防止SQL注入)

使用CallableStatement調用存儲過程(也就所謂設計一個函數,然後調用完成一系列操作)

例: 格式如下
delimiter//
create procedure add_proName(a int,b int, out sum int)#create procedure爲創建關鍵字,out表示輸入
begin set sum=a+b;
end;
//
#將結束符改爲("//"),使得在創建儲存過程中可以使用分號,在完成存儲函數的定義(使用delimiter)後, 使用call add_proName(1,2,@sum);調用這個函數,@sum表示將函數結果放到形參中; 具體不做闡述
調用儲存過程使用CallableStatement, 通過Connection的prepareCall()方法創建CallableStatement對象,創建對象的過程中傳入SQL語句: 格式如下----{call add_proName(?,?,?)}//使用通配符"?"
例: CallableStatement csmt=conn.prepareCall("{Call add_proName(?,?,?)}");//完成調用操作
csmt.setXxx();//設置傳入參數 csmt.registerOutParameter(3,Types.INTEGER)//註冊參數 上述操作完成後使用csmt.execute();//執行SQL語句

處理Blob類型數據(Blob表示二進制長對象,如圖片/音視頻)

使用PreparedStatement中的對象的方法:將圖片等插入數據庫:psmt.setBinaryStream(int parameterIndex,InputStream is,int length)//傳入二進制輸入流
psmt.executeUpdate();
從ResultSet中提取Blob數據:Blob blob=rs.getBlob(int columnIndex)

使用ResultSetMetaData查看結果集

ResultSet對象包含getMetaData(),用於返回ResultSet的ResultSetMetaData對象
int i=rsmd.getColumnCount()//返回ResultSet的列數量
String s=rsmd.getColunName(int column)//返回指定列名
int i=getColumnType(int column)//返回索引列類型
使用ResultSetMetaData會造成系統開銷

事務處理(多條SQL要麼全部執行,要麼放棄執行;具有原子性,一致性,隔離性,持續性)

事務提交: 顯式提交(commit),自動提交(DDL/DCL DML語句會導致事務立即被處理)
事務提交的過程中會出現某個操作失敗,需要rollback事務(剛纔執行的操作全部失效): 分爲顯式回滾(rollback),自動回滾(系統錯誤自動退出);
MySQL默認關閉事務,在DML語句中需要添加:set autocommit=0 開啓事務(DML語句不會立馬生效,需要使用commit顯式提交或者運行DDL/DCL語句),1表示自動提交
設置事務只會對當前的命令行窗口有效,MySQL使用start transaction或者begin來執行一次臨時的事務
例: begin; insert into studentTable values(null,‘A’,1); insert into studentTable values(null,‘B’,2); select * from studenttable;#插入記錄成功 rollback();上述操作全部失效
savepoint a;#設置事務的中間點讓事務回滾到中間點位置
rollback to a;
注: 回滾到指定位置並不會結束當前事務

JDBC事務支持

conn.setAutoCommit(false);//開啓事務
stm.executeUpdate(…);stm.executeUpdate(…);stm.executeUpdate(…);
conn.commit();//提交事務
conn.rollback();//回滾事務,當SQL語句出現異常,將會自動回滾事務
Savepoint sp=coon.setSavepoint();//設置斷點
conn.rollback(Savepoint sp);//回滾到指定斷點

使用DatabasesMetaDate分析數據庫信息

DatabaseMetaData dmd=conn.getMetaData();
例:ResultSet rs=dmd.getTableTypes();//通常DatabaseMetaData的方法返回ResultSet對象

使用連接池管理連接(創建足夠多的數據庫連接,避免應用程序多次重新打開數據庫連接,提高效率)

DBCP連接池:Apache旗下, Tomcat採用此連接池,需下載到apache網站下載commons-pool.zip,commons-dbcp.zip,可與應用服務器整合使用,也可以應用程序獨立使用
BasicDataSource ds=new BasicDataSource();//創建數據源對象
ds.setDriverClassName(“com.mysql.jdbc.Driver”);//連接驅動
ds.setUrl(“jdbc:mysql://localhost:3306/test”);
ds.setUsername(“root”);ds.setPassword(“12345”);
ds.setInitialSize(5);//設置初始連接數
ds.setMaxActive(20);//最多爲20個活動連接
ds.setMinIdle(2);//最少2個空閒連接
Connection conn=ds.getConnection();//連接數據庫
conn.close();//釋放鏈接
C3P0連接池…; 與DBCP一致自行百度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章