一, 概括
在實(shí)際的應(yīng)用中,很少只局限于對單表進(jìn)行操作,通常會涉及多表操作。例如銀行的取款操作,它至少需要兩個(gè)步驟——首先進(jìn)行取款操作,取款成功后更改賬戶金額;其次記錄日志,記錄此次取款的時(shí)間及金額等。這兩個(gè)步驟是需要同時(shí)成功才算完成取款交易的。要完成上述的需求就需要借助于JDBC的事務(wù)管理和批量處理。
所謂事務(wù):是指一組原子操作(一組SQL語句執(zhí)行)的工作單元。
這個(gè)工作單元中的所有原子操作在進(jìn)行期間,與其他事務(wù)隔離,免于因數(shù)據(jù)來源的交相更新而發(fā)生混亂,事務(wù)中的所有原子操作要么全部執(zhí)行成功,要么全部失敗。
二, 創(chuàng)建JDBC的事務(wù)主要分以下步驟:
a) 設(shè)置事務(wù)的提交方式為非自動提交:conn.setAutoCommit(false);
b) 將需要添加事務(wù)的代碼放在try、catch塊中:
try {
//需要添加事務(wù)的業(yè)務(wù)代碼
} catch (SQLException e) {
...
}
在try塊內(nèi)添加提交操作,表示操作無異常,提交事務(wù):conn.commit(); //正常流程,提交事務(wù)
在catch塊內(nèi)添加回滾事務(wù),表示操作出現(xiàn)異常,撤消事務(wù):conn.rollback(); //發(fā)生異常,撤消事務(wù)
設(shè)置事務(wù)提交方式為自動提交:conn.setAutoCommit(true); //自動提交事務(wù)
三,JDBC批量處理
· Statement的execute()等方法一次只能執(zhí)行一條SQL語句,如果同時(shí)有多條SQL語句要執(zhí)行的話,可以使用addBatch()方法將要執(zhí)行的SQL語句加入進(jìn)來,然后執(zhí)行executeBatch()方法,這樣就可以在一次方法調(diào)用中執(zhí)行多條SQL語句,以提高執(zhí)行效率。
· 為了保證這一批語句要么全部成功,要么全部失敗,應(yīng)該把批處理放置在事務(wù)中進(jìn)行。
· 使用PreparedStatement也可以進(jìn)行批處理
簡單地說,JDBC可做三件事:與數(shù)據(jù)庫建立連接、發(fā)送 SQL 語句并處理結(jié)果。
· 對獲得Connection對象進(jìn)行封裝
– 將數(shù)據(jù)庫的配置信息寫到一個(gè)屬性文件中,然后用IO流去獲取,當(dāng)需要修改數(shù)據(jù)庫連接的時(shí)候只要改動配置文件即可。
– 在src下新建屬性文件jdbc.properties,添加如下內(nèi)容:
· driver=com.MySQL.jdbc.Driver
· url=jdbc:mysql://localhost:3306/test
· username=root
· password=root
· 對關(guān)閉JDBC資源類的封裝
– 新建DbClose.Java類,添加方法關(guān)閉結(jié)果集對象、語句對象、連接對象。
– 在執(zhí)行增加、刪除、修改的時(shí)候可以使用代碼關(guān)閉連接:DbClose.close(Statement stmt, Connection conn);
– 在執(zhí)行查詢之后使用如下代碼關(guān)閉連接:DbClose.close(ResultSet rs, Statement stmt, Connection conn);
四, 實(shí)例
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
/* 操作插入 */
public boolean insert(Student entity) {
/* 第一步:聲明返回結(jié)果變量 */
boolean flag = false;
try {
/* 第二步:獲取連接對象 */
conn = JdbcUtil.getConnection();
/* 第三步:定義sql語句 */
String sql = "insert into student(name,sex,resume,image) values(?,?,?,?)";
/* 第四步:根據(jù)sql語句創(chuàng)建預(yù)處理對象 */
pstmt = conn.prepareStatement(sql);
/* 第五步:為站位符賦值 */
int index = 1;
pstmt.setObject(index++, entity.getName());
pstmt.setObject(index++, entity.getSex());
pstmt.setObject(index++, entity.getResume());
// pstmt.setBinaryStream(parameterIndex, x)
pstmt.setObject(index++, entity.getImage());
/* 第六步:執(zhí)行更新 */
int i = pstmt.executeUpdate();
/* 第七步:判斷 */
if (i > 0) {
flag = true;
}
/* 第八步:釋放資源 */
JdbcUtil.release(rs, pstmt, conn);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* *****修改返回變量值 */
return flag;
}。