一、JDBC概述
JDBC是一種可用於執行SQL語句的Java API (Application Programming Interface,應用程序設計接口),是連接數據庫和Java應用程序的紐帶。
1、JDBC-ODBC橋
JDBC-0DBC橋是一個JDBC驅動程序,完成了從JDBC操作到0DBC操作之間的轉換工作,允許JDBC驅動程序被用作ODBC的驅動程序。使用JDBC-ODBC橋連接數據庫的步驟如下:
(1)首先加載JDBC-ODBC橋的驅動程序。代碼如下:
Class.forNamet"sunjdbc.odbc.JdbcOdbcDriver”);
Class類是java.lang 包中的-一個類,通過該類的靜態方法forName()可加載sun.jdbc.odbc 包中的JdbcOdbcDriver類來建立JDBC-ODBC橋連接器。
(2)使用java.sql包中的Connection接口,並通過DriverManager類的靜態方法getConnection()創建連接對象。代碼如下:
Connection conn = DriverManager.getConnection("jdbc:odbc:數據源名字”,"user name","password");
數據源必須給出一個簡短的描述名。假設沒有設置username和password,則要與數據源tom交換數據。建立Connection對象的代碼如下:
Connection conn = DriverManagergetConnectionC"jdbc.odbc:tom”,",");
(3)向數據庫發送SQL語句。使用Statement 接口聲明一個SQL語句對象,並通過剛纔創建的連接數據庫對象conn的createStatement(方法創建這個SQL對象。代碼如下:
Statement sql = conn.createStatement);
JDBC-ODBC橋作爲連接數據庫的過渡性技術,現在已經不被Java廣泛應用了,現在被廣泛應用的是JDBC技術。但這並不表示JDBC-ODBC橋技術已經被淘汰,由於ODBC技術被廣泛地使用,使得Java可以利用JDBC-0DBC橋訪間幾乎所有的數據庫。JDBC-ODBC橋作爲sun.jdbc.odbe包與JDK一起自 動安裝,不需要特殊配置。
2、JDBC技術
JDBC的全稱是Java DataBase Connectivity,是一套面向對象的應用程序接口,指定了統一的訪問各種關係型數據庫的標準接口。JDBC是一種底層的API,因此訪問數據庫時需要在業務邏輯層中嵌入SQL語句。SQL語句是面向關係的,依賴於關係模型,所以通過JDBC技術訪問數據庫也是面向關係的。JDBC技術主要完成以下幾個任務:
- 與數據庫建立一個連接。
- 向數據庫發送 SQL語句。
- 處理從數據庫返回的結果。
需要注意的是,JDBC並不能直接訪問數據庫,必須依賴於數據庫廠商提供的JDBC驅動程序。
3、JDBC驅動程序的類型
JDBC的總體結構由4個組件一應用程序、 驅動程序管理器、驅動程序和數據源組成。JDBC驅動基本上分爲以下4種。
- JDBC-ODBC橋:依靠ODBC驅動器和數據庫通信。這種連接方式必須將ODBC二進制代碼加載到使用該驅動程序的每臺客戶機上。這種類型的驅動程序最適合於企業網或者用Java編寫的三層結構的應用程序服務器代碼。
- 本地API一部分用Java編寫的驅動程序:這類驅動程序把客戶機的API上的JDBC調用轉換爲Oracle、DB2、Sybase 或其他DBMS的調用。這種驅動程序也需要將某些二進制代碼加載到每臺客戶機上。
- JDBC 網絡驅動:這種驅動程序將JDBC轉換爲與DBMS無關的網絡協議,又被某個服務器轉換爲一-種DBMS協議,是-種利用Java編寫的JDBC驅動程序,也是最爲靈活的JDBC驅動程序。這種方案的提供者提供了適合於企業內部互聯網(Intranet) 用的產品。爲使這種產品支持Internet訪問,需要處理Web提出的安全性、通過防火牆的訪問等額外的要求。
- 本地協議驅動: 這是一種純Java的驅動程序。這種驅動程序將JDBC調用直接轉換爲DBMS所使用的網絡協議,允許從客戶機上直接調用DBMS服務器,是一種很實用的訪問Intranet的解決方法。
JDBC網絡驅動和本地協議驅動是JDBC訪問數據庫的首選,這兩類驅動程序提供了Java的所有優點。
二、JDBC中常用的類和接口
1、Connection接口
Connection接口代表與特定的數據庫的連接,在連接.上下文中執行SQL 語句並返回結果。Connection接口的常用方法如下表所示:
2、Statement接口
Statement接口用於在已經建立連接的基礎上向數據庫發送SQL語句。在JDBC中有3種Statement對象,分別是Staterment、PreparedStaterment 和CallableStatement。Statement 對象用於執行不帶參數的簡的SQL語句; PreparedStatement 繼承了Statement, 用來執行動態的SQL語句; CallableStatemnent 繼承了PreparedStatement, 用於執行對數據庫的存儲過程的調用。Statement 接口的常用方法如下表所示。
3、PreparedStatement接口
PreparedStatement接口用來動態地執行SQL語句。通過PreparedStatement實例執行的動態SQL語句,將被預編譯並保存到PreparedStatement實例中,從而可以反覆地執行該SQL語句。PreparedStatement接口的常用方法如下表所示。
4、DriverManager類
DriverManager類用來管理數據庫中的所有驅動程序。它是JDBC的管理層,作用於用戶和驅動程序之間,跟蹤可用的驅動程序,並在數據庫的驅動程序之間建立連接。如果通過getConnection0方法可以建立連接,則經連接返回,否則拋出SQLException異常。DriverManager 類的常用方法如下表所示。
5、ResultSet接口
ResultSet接口類似於一個臨時表,用來暫時存放數據庫查詢操作所獲得的結果集。ResultSet 實例具有指向當前數據行的指針,指針開始的位置在第一條 記錄的前面,通過next()方法可將指針向下移。ResultSet常用方法如下表所示。
三、數據庫操作實例
運行環境:eclipse版本:2019-09;JDK:12,驅動jar包:mysql-connector-java-8.0.19;MySQL Server 8.0。注意此處要將mysql-connector-java-8.0.19.jar添加至構建路徑。
例1:
import java.sql.*;
public class Gradation {
static Connection con;
static Statement sql;
static ResultSet res;
public Connection getConnection() {
try {
// 加載數據庫驅動類
//Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");
// 連接數據庫
// 注意此處因爲數據庫和系統時區差異會引起異常所以在在jdbc連接的url後面加上
// “?serverTimezone=UTC&characterEncoding=utf-8”
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test"
+"?serverTimezone=UTC&characterEncoding=utf-8", "root", "12345");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
Gradation c = new Gradation();
con = c.getConnection();
try {
sql = con.createStatement(); // 實例化Statement對象
res = sql.executeQuery("select * from tb_stu"); // 執行SQL語句,返回結果集
while (res.next()) { // 如果當前語句不是最後一條則進入循環
String id = res.getString("id");
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("編號:" + id); // 將列值輸出
System.out.print(" 姓名:" + name);
System.out.print(" 性別:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
輸出:
例2:
import java.sql.*;
public class Renewal {
static Connection con;
static PreparedStatement sql;
static ResultSet res;
public Connection getConnection() {
try {
// 加載數據庫驅動類
//Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");
// 連接數據庫
// 注意此處因爲數據庫和系統時區差異會引起異常所以在在jdbc連接的url後面加上
// “?serverTimezone=UTC&characterEncoding=utf-8”
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test"
+"?serverTimezone=UTC&characterEncoding=utf-8", "root", "12345");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
Renewal c = new Renewal();
con = c.getConnection();
try {
sql = con.prepareStatement("select * from tb_stu"); // 查詢數據庫
res = sql.executeQuery(); // 執行SQL語句
System.out.println("執行增加、修改、刪除前數據:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday"); // 遍歷查詢結果集
System.out.print("編號:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性別:" + sex);
System.out.println(" 生日:" + birthday);
}
// 預處理添加數據
sql = con.prepareStatement("insert into tb_stu(name,sex,birthday) values(?,?,?)");
sql.setString(1, "張一");
sql.setString(2, "女");
sql.setString(3, "2012-12-1");
sql.executeUpdate();
// 更新數據
sql = con.prepareStatement("update tb_stu set birthday = ? where id = ? ");
sql.setString(1, "2012-12-02");
sql.setInt(2, 1);
sql.executeUpdate();
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from tb_stu where id = 1");
// 查詢修改數據後的tb_stu表中數據
sql = con.prepareStatement("select * from tb_stu");
res = sql.executeQuery(); // 執行SQL語句
System.out.println("執行增加、修改、刪除後的數據:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("編號:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性別:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
輸出:
executeQuery()方法是在PreparedStatement對象中執行SQL查詢,並返回該查詢生成的ResultSet對象,而executeUpdate()方法是在PreparedStaterment對象中執行SQL語句,該語句必須是一個SQL數據操作語言(Data Manipulation Language, DML)語句,如INSERT. UPDATE或DELETE語句,或者是無返回內容的SQL語句,如DDL語句。