[toc]
JDBC是什么 (Java DataBase Connectivity)
jdbc是一種Java編程語言和各種數(shù)據(jù)庫之間
數(shù)據(jù)庫無關(guān)連接的行業(yè)標(biāo)準(zhǔn),
JDBC API為基于SQL的數(shù)據(jù)庫訪問提供了調(diào)用級API
數(shù)據(jù)庫無關(guān)
在沒有JDBC之前,我們需要編寫不同的程序?qū)硬煌瑥S商的數(shù)據(jù)庫系統(tǒng),像下圖所示,需要針對不同的數(shù)據(jù)庫api編程,可想而知,當(dāng)我們需要更換數(shù)據(jù)庫系統(tǒng)而產(chǎn)生的大量重復(fù)工作,增加不必要的開發(fā)成本

而JDBC的出現(xiàn),統(tǒng)一了Java程序訪問不同數(shù)據(jù)庫系統(tǒng)的api,應(yīng)用程序通過調(diào)用JDBC來操作數(shù)據(jù)庫時,實際上是右數(shù)據(jù)庫系統(tǒng)廠商提供的JDBC驅(qū)動程序來完成的。這樣一來,即使要更換數(shù)據(jù)庫系統(tǒng),也僅僅是更換相應(yīng)的驅(qū)動程序就可以了。(本文使用mysql的驅(qū)動程序)

JDBC API主要完成以下三個工作:
- 建立與數(shù)據(jù)庫的連接或訪問任何表格數(shù)據(jù)源
- 發(fā)送SQL語句到數(shù)據(jù)庫
- 處理數(shù)據(jù)返回的結(jié)果
這三個工作中都有其對應(yīng)的jdbc api來完成各自的任務(wù)。應(yīng)用程序可以使用這些api 來操作數(shù)據(jù)庫系統(tǒng)了
JDBC API
DriverManager
管理JDBC驅(qū)動的服務(wù)類,主要功能是獲取Connection對象(示例程序中的第2步)
getConnection方法
Connection getConnection(url,username,password)
- url寫法:jdbc:mysql://localhost:3306/mydb
本地數(shù)據(jù)庫簡寫:jdbc:mysql:///mydb - jdbc:協(xié)議
- mysql:子協(xié)議
- localhost:主機名
- 3306:端口號
- mydb:數(shù)據(jù)庫名稱
Connection
數(shù)據(jù)庫連接對象,每個Connection對象表示一個連接會話。
Connection的常用方法
1. 返回Statement對象
Statement createStatement()-
PreparedStatement PreparedStatement(String sql):Statement的子類,將SQL語句提交到數(shù)據(jù)庫進行預(yù)編譯 -
CallableStatement prepareCall(String sql):Statement的子類,處理存儲過程
2. 處理事務(wù)的常用方法
-
void setAutoCommit(boolean autoCommit):設(shè)置是否自動提交,默認(rèn)true -
void commit:提交事務(wù) -
void rollback:事務(wù)回滾 -
Savepoint setSavepoint:創(chuàng)建一個保存點 -
Savepoint setSavepoint(Stirng name):指定名稱來創(chuàng)建一個保存點 -
void rollback(Savepoint savepoint):將事務(wù)回滾到指定的保存點 -
void setTransactionIsolation(int level):設(shè)置事務(wù)隔離級別
Statement
執(zhí)行具體的SQL語句,以及執(zhí)行DDL、DCL、DML語句。
Statement子類 PreparedStatement
預(yù)編譯的Statement對象
SQL語句一次編譯多次執(zhí)行
允許數(shù)據(jù)庫預(yù)編譯SQL語句(常帶有參數(shù)或者叫占位符),這樣一來,以后每次只需要改變SQL命令的參數(shù),而不需要每次都編譯SQL語句,性能得到了提升
PreparedStatement主要方法
-
void setXXX(int parmIndex,XXX value):設(shè)置預(yù)編譯語句的參數(shù)
Statement常用方法
-
ResultSet executeQuery(String sql):只能執(zhí)行查詢語句,返回ResultSet -
int executeUpdate(String sql):主要用于執(zhí)行DML語句的,返回受影響行數(shù)。 -
boolean execute(String sql):執(zhí)行任何SQL語句 -
addBatch(String sql):添加到批處理 -
executeBatch():執(zhí)行批處理 -
clearBatch():清空批處理
ResultSet
結(jié)果集:查詢結(jié)果的封裝
ResultSet主要方法
移動指針的方法
-
next():移動指針到ResultSet記錄的下一行,如果存在該條記錄返回true - .......
獲取當(dāng)前行、指定列的值
-
getInt()、getString()針對不同數(shù)據(jù)類型的方法, - 通用的兩個泛型方法
<T> T getObject(int columnIndex,Class<T> type)、<T> T getObject(String columnLabel,Class<T> type)
JDBC實際操作
建庫建表的SQL語句
-- 建庫
CREATE DATABASE `mydb` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 建表
CREATE TABLE IF NOT EXISTS `user`(
`id` INT UNSIGNED AUTO_INCREMENT,
`username` VARCHAR(100) NOT NULL,
`password` VARCHAR(40) NOT NULL,
`name` VARCHAR(40) NOT NULL,
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
示例程序框架
我們會在業(yè)務(wù)邏輯代碼start的地方開始具體的執(zhí)行操作
public void excute() throws SQLException {
Connection conn = null;
PreparedStatement smt = null;
ResultSet resultset = null;
try {
//1、加載驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
//2、獲取Connection對象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8", "root", "***");
if (conn != null) {
System.out.println("連接成功");
}
conn.setAutoCommit(false);
//業(yè)務(wù)邏輯代碼start
//插入數(shù)據(jù)操作
String insertSql = "insert into user(username,password,name) values(?,?,?)";
smt = conn.prepareStatement(insertSql);
smt.setString(1, "xiaoming");
smt.setString(2, "123");
smt.setString(3, "小明");
int result = smt.executeUpdate();
if (result > 0) {
System.out.println("添加成功");
}
smt.clearParameters();
//修改數(shù)據(jù)操作
String updateSql = "update user set name=? where id=?";
smt = conn.prepareStatement(updateSql);
smt.setString(1, "小牛");
smt.setInt(2, 2);
int updateResult = smt.executeUpdate();
if (updateResult > 0) {
System.out.println("修改成功");
}
smt.clearParameters();
//查詢數(shù)據(jù)操作
String sql = "select *from user where id =?";
smt= conn.prepareStatement(sql);
smt.setInt(1,3);
resultset = smt.executeQuery();
while (resultset.next()) {
int uid = resultset.getInt("id");
System.out.println(String.format("id:%s,username:%s,password:%s,name:%s", uid,
resultset.getString("username"),
resultset.getString("password"),
resultset.getString("name")));
}
//業(yè)務(wù)邏輯代碼end
conn.commit();
} catch (Exception e) {
System.out.println(e);
conn.rollback();
}
//4、釋放資源 寫到finally里面,防止報錯不能執(zhí)行資源回收
finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (smt != null) {
try {
smt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultset != null) {
try {
resultset.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
執(zhí)行結(jié)果
連接成功
添加成功
修改成功
id:3,username:xiaoming,password:123,name:小明
業(yè)務(wù)邏輯代碼中如果有錯誤,連接對象將執(zhí)行回滾操作,保證數(shù)據(jù)的一致性。