【JDBC詳解】深入
1.SQL注入攻擊
(1)定義:
SQL 注入是利用某些系統沒有對使用者輸入的資料進行充分的檢查,而在使用者輸入資料中注入非法的 SQL 語句段或命令,從而利用系統的 SQL 引擎完成惡意行為的做法。
(2)解決方法:用 PreparedStatement(預編譯) 取代 Statement 就可以了
原因:使用預編譯SQL語句避免了頻繁sql拼接 (可以使用佔位符),也可以防止sql注入
例:OR 1=1 語句將刪除整個表 ;
2.批處理
(1)需求:批量儲存資訊。
(2)常用方法
- void addBatch(String sql) 新增批處理
- void clearBatch() 清空批處理
- int[] executeBatch() 執行批處理
(3)進行批處理
例:
public void batching(List<Admin> list) {
private Connection con = null;
private PreparedStatement pstmt = null;
String sql = "INSERT INTO admin(userName,pwd) values(?,?)";
try {
// 獲取連線(利用工具類)
con = JdbcUtil.getConnection();
pstmt = con.prepareStatement(sql); //預編譯SQL語句
for (int i=0; i<list.size(); i++) {
Admin admin = list.get(i);
// 設定引數
pstmt.setString(1, admin.getUserName());
pstmt.setString(2, admin.getPwd());
// 新增批處理
pstmt.addBatch(); // 不需要傳入SQL
// 測試:每5條執行一次批處理
if (i % 5 == 0) {
// 批量執行
pstmt.executeBatch();
// 清空批處理
pstmt.clearBatch();
}
}
// 批量執行
pstmt.executeBatch();
// 清空批處理
pstmt.clearBatch();
} catch (Exception e) {
e.printStackTrace();
} finally {
//(利用工具類)
JdbcUtil.closeAll(con, pstmt, null);
}
}
}
3. 事務
(1)概念:
事務使指一組最小邏輯操作單元,裡面有多個操作組成。 組成事務的每一部分必須要同時提交成功,如果有一個操作失敗,整個操作就回滾。
(2)四個特性(ACID)
原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
一致性(Consistency)
事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。
隔離性(Isolation)
事務的隔離性是多個使用者併發訪問資料庫時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作資料所幹擾,多個併發事務之間要相互隔離。
永續性(Durability)
永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來即使資料庫發生故障也不應該對其有任何影響
(3)特性的總結:
* 原子性,是一個最小邏輯操作單元 !
* 一致性,事務過程中,資料處於一致狀態。
* 永續性, 事務一旦提交成功,對資料的更改會反映到資料庫中。
* 隔離性, 事務與事務之間是隔離的。
(4)JDBC事務處理
當一個連線物件被建立時,預設情況下是自動提交事務:每次執行一個 SQL 語句時,如果執行成功,就會向資料庫自動提交,而不能回滾
為了讓多個 SQL 語句作為一個事務執行,呼叫 Connection 物件的 setAutoCommit(false); 以取消自動提交事務
在所有的 SQL 語句都成功執行後,呼叫 commit(); 方法提交事務
若出現異常,呼叫 rollback(); 方法回滾事務
若此時 Connection 沒有被關閉, 則需要恢復其自動提交狀態
例:
public void trans() {
String sql_zs = "UPDATE account SET money=money-1000 WHERE accountName='Lee';";
String sql_ls = "UPDATE1 account SET money=money+1000 WHERE accountName='LinDan';";
try {
con = JdbcUtil.getConnection();
//設定手動提交任務
con.setAutoCommit(false);
pstmt = con.prepareStatement(sql_zs);
pstmt.executeUpdate();
pstmt = con.prepareStatement(sql_ls);
pstmt.executeUpdate();
} catch (Exception e) {
try {
//若出現異常則回滾
con.rollback();
} catch (SQLException e1) {
}
e.printStackTrace();
} finally {
try {
//若無異常則提交事務
con.commit();
//工具類
JdbcUtil.closeAll(con, pstmt, null);
} catch (SQLException e) {
}
}
}
4.大文字型別的處理
(1)MySQL的大文字型別,
- Text 長文字型別
- Blob 二進位制型別
例:
public void testSaveText() {
String sql = "insert into test(img) values(?)";
try {
// 連線
con = JdbcUtil.getConnection();
// pstmt 物件
pstmt = con.prepareStatement(sql);
// 獲取圖片流
InputStream in = App_text.class.getResourceAsStream("background.jpg");
pstmt.setBinaryStream(1, in);
// 執行儲存圖片
pstmt.execute();
// 關閉
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, null);
}
}
本人才疏學淺,若有錯誤,請指出
謝謝!