jdbc 程式設計(二)
JDBC處理大文字,JDBC處理圖片,JDBC進行批處理 資料庫連線池
參考文獻:https://www.cnblogs.com/shanheyongmu/p/5909539.html
參考文獻:https://www.cnblogs.com/shanheyongmu/p/5909922.html
1. 事務(Transaction,簡寫為tx):
所謂事務是使用者定義的一組操作,使資料從一種狀態變換到另一種狀態,要麼同時成功,要麼同時失敗。
2. 事務的操作:
先定義開始一個事務,然後對資料作修改操作,這時如果提交(commit),這些修改就永久地儲存下來,如果回退(rollback),資料庫管理系統將放棄您所作的所有修改而回到開始事務時的狀態。
3. 事務的ACID屬性:
Atomic原子性、Consistency一致性、Isolation [ˌaɪsəˈleɪʃn] 隔離性和 Durability 永續性。
1、原子性(Atomicity)原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
2、一致性(Consistency):事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。
3、隔離性(Isolation):事務的隔離性是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
4、永續性(Durability):永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來的其他操作和資料庫故障不應該對其有任何影響。)
4. 如何在程式碼中去處理事務:
1.在JDBC中,事務是預設提交的. 必須先設定事務為手動提交.
connection物件.setAutoCommit(false);//設定事務為手動提交.
2.手動的提交事務.
connection物件.commit();
3.若出現異常必須回滾事務:
不回滾事務,總餘額依然是正確的. 若不回滾事務,不會釋放資料庫資源.
connection物件.rollback();
6. 事務示例:
銀行轉帳功能: bank / money
過兒和姑姑: 過兒 : 10000塊錢 姑姑 : 0塊錢
轉賬:過兒要給姑姑轉1000塊錢
分析:轉錢需要提供兩條sql,但是程式設計師也會出錯,比較程式碼寫錯了.
①update bank set money = money +1000 where name = '姑姑'
②程式碼出錯, 會導致過兒賬戶錢少了,而姑姑賬戶沒有收到錢,錢去哪了?
③update bank set money = money -1000 where name= '過兒'
解決辦法 程式碼:
資料庫:
CREATE TABLE `bank` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `money` double DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
com.domain包下的 實體類 Bank
package com.domain; public class Bank { private String name; private double money; public Bank(String name, double money) { super(); this.name = name; this.money = money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public Bank() { // TODO Auto-generated constructor stub } @Override public String toString() { return "Bank [name=" + name + ", money=" + money + "]"; } }
com.dao 包下的 IBankDao 介面
package com.dao; import com.domain.Bank; public interface IBankDao { void transMoney(Bank b1,Bank b2, double money); }
com.dao .impl 包 的 BankDaoImpl 實現類
package com.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.Util.JDBCUtil; import com.dao.IBankDao; import com.domain.Bank; public class BankDaoImpl implements IBankDao { // 單利模式獲取 BankDaoImpl 類物件 private BankDaoImpl (){} private static BankDaoImpl instance = null; public static BankDaoImpl getInstance(){ if(instance == null){ return instance = new BankDaoImpl(); } return null; } @Override public void transMoney(Bank b1, Bank b2, double money) { Connection conn = null; PreparedStatement ps = null; try { conn = JDBCUtil.getInstance().getConnection(); //在JDBC中,事務是預設提交的true. 必須先設定事務為手動提交false conn.setAutoCommit(false); ps = conn.prepareStatement("update bank set money = money - ? where name = ? "); ps.setDouble(1, money); ps.setString(2, b1.getName() ); ps.executeUpdate(); // int a = 1/0; //錯誤程式碼 ps = conn.prepareStatement("update bank set money = money + ? where name = ?"); ps.setDouble(1, money); ps.setString(2, b2.getName()); ps.executeUpdate(); conn.commit(); //手動進行提交 } catch (Exception e) { try { conn.rollback(); //資料回滾 } catch (SQLException e1) { e1.printStackTrace(); } } JDBCUtil.getInstance().closeAll(null,ps,conn); } }
測試類
public class TestBank { @Test public void trans(){ Bank b1 = new Bank("過兒",10000); Bank b2 = new Bank("姑姑",0); BankDaoImpl.getInstance().transMoney(b1, b2, 1000); } }
7. 如何在JDBC中儲存資料的時候獲取自動生成的主鍵呢?
Statement方式:
int executeUpdate(String sql, int autoGeneratedKeys):執行SQL:
引數:autoGeneratedKeys,是否需要返回自動生成的主鍵.常量值:Statement.RETURN_GENERATED_KEYS.
ResultSet getGeneratedKeys():獲取自動生成的主鍵
示列程式碼如下:
@Test public void statementTest() throws Exception { String sql = "insert into student (name, age) values ('zhangsan', 30)"; Connection connection = JdbcUtil.getConn(); Statement statement = connection.createStatement(); // statement.executeUpdate(sql); statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); ResultSet resultSet = statement.getGeneratedKeys(); if (resultSet.next()) { Long id = resultSet.getLong(1); System.out.println(id); } JdbcUtil.close(connection, statement, null); }
PreparedStatement方式:
PreparedStatement prepareStatement(String sql,int autoGeneratedKeys) :
建立PreparedStatement物件,病指定是否需要返回生成的主鍵. 常量值:Statement.RETURN_GENERATED_KEYS
示列程式碼:
public class PreparedStatementTest { @Test public void preparedStatement() throws Exception { String sql = "insert into student (name,age) values (?,?)"; Connection connection = JdbcUtil.getConn(); PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, "張三"); preparedStatement.setInt(2, 24); preparedStatement.executeUpdate(); ResultSet resultSet = preparedStatement.getGeneratedKeys(); if (resultSet.next()) { Long id = resultSet.getLong(1); System.out.println(id); } JdbcUtil.close(connection, preparedStatement, null); } }