## JDBC 簡介
JDBC(Java DataBase Connectivity,java數據庫連接)是一種用于執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序,同時,JDBC也是個商標名。
## JDBC 架構
JDBC API支持兩層和三層處理模型進行數據庫訪問,但在一般的JDBC體系結構由兩層組成:
- JDBC API: 提供了應用程序對JDBC的管理連接。
- JDBC Driver API: 支持JDBC管理到驅動器連接。
- JDBC API的使用驅動程序管理器和數據庫特定的驅動程序提供透明的連接到異構數據庫。
- JDBC驅動程序管理器可確保正確的驅動程序來訪問每個數據源。該驅動程序管理器能夠支持連接到多個異構數據庫的多個并發的驅動程序。
以下是JDBC結構圖,它顯示了驅動程序管理器方面的JDBC驅動程序和Java應用程序的位置:

## JDBC 常用API
- DriverManager
這個類管理數據庫驅動程序的列表。確定內容是否符合從Java應用程序使用的通信子協議正確的數據庫驅動程序的連接請求。識別JDBC在一定子協議的第一個驅動器將被用來建立數據庫連接。
- Driver
此接口處理與數據庫服務器通信。很少直接直接使用驅動程序(Driver)對象,一般使用DriverManager中的對象,它用于管理此類型的對象。它也抽象與驅動程序對象工作相關的詳細信息
- Connection
此接口與接觸數據庫的所有方法。連接對象表示通信上下文,即,與數據庫中的所有的通信是通過此唯一的連接對象。
- Statement
可以使用這個接口創建的對象的SQL語句提交到數據庫。一些派生的接口接受除執行存儲過程的參數。
- ResultSet
這些對象保存從數據庫后,執行使用Statement對象的SQL查詢中檢索數據。它作為一個迭代器,可以通過移動它來檢索下一個數據。
- SQLException
這個類用于處理發生在數據庫應用程序中的任何錯誤。
## JDBC 使用步驟
使用JDBC應用程序創建新數據庫需要以下步驟:
- 導入包
需要包含數據庫編程所需的JDBC類的包。項目中需要添加數據庫連接的jar包才能進行導入。例如:mysql-connector-java-5.1.46.jar。
- 注冊JDBC驅動程序
需要初始化驅動程序,以便可以程序中打開數據庫的通信通道。
- 打開連接
需要使用DriverManager.getConnection()方法來創建一個Connection對象,它表示與數據庫服務器的物理連接。要創建一個新的數據庫,不需要在準備數據庫URL時提供任何數據庫名稱,如下面的示例所述。
- 執行查詢
需要使用類型為Statement的對象來構建和提交SQL語句到數據庫。
- 清理環境
需要明確地關閉所有數據庫資源,而不依賴于JVM的垃圾收集,避免造成資源的浪費。
## JDBC 連接數據庫
在執行以下示例之前,請確保您已經準備好以下操作:
具有數據庫管理員權限,以在給定模式中創建數據庫。 要執行以下示例,需要用實際用戶名和密碼替換這里用戶名(username)和密碼(password)。
MySQL或數據庫已啟動并運行。
#### 準備測試數據
創建測試數據庫
```sql
CREATE DATABASE easilyj;
```
創建測試表
```sql
CREATE TABLE `user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) DEFAULT NULL,
`user_password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_id`)
);
```
#### 連接數據庫
```java
import java.sql.Connection;
import java.sql.DriverManager;
public class CreateDatabase {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
// 獲得數據庫連接
public static Connection getConnection() {
if (null == conn) {
try {
Class.forName("com.mysql.jdbc.Driver"); // 加載驅動
conn = DriverManager.getConnection(url, userName, passWord); // 創建數據庫連接
} catch (Exception e) {
e.printStackTrace();
System.out.println("JDBC 連接數據庫失敗");
}
}
return conn;
}
public static void main(String[] args) {
System.out.println("JDBC 連接數據庫成功");
System.out.println("JDBC 連接地址為:" + getConnection());
}
}
```
連接成功之后會返回一個獲得的連接的內存地址,運行結果:
```
JDBC 連接數據庫成功
JDBC 連接地址為:com.mysql.jdbc.JDBC4Connection@5a10411
```
## JDBC 插入數據
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class InsertDate {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 準備sql
String sql = "INSERT INTO user(user_name, user_password) VALUES ('小海綿', '123456')";
Connection conn = getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
pst.executeUpdate();
System.out.println("JDBC 插入成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 插入失敗");
}
}
}
```
運行結果:
```
JDBC 插入成功
```
## JDBC 更新數據
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class UpdateDate {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 準備sql
String sql = "update user set user_name='大海綿', user_password='654321' where user_id=1";
Connection conn = getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
pst.executeUpdate();
System.out.println("JDBC 更新成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 更新失敗");
}
}
}
```
運行結果:
```
JDBC 更新成功
```
## JDBC 查詢數據
建議再執行一遍新增,這樣數據庫就有兩條數據,方便觀察結果。
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SelectDate {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 準備sql
String sql = "select * from user";
Connection conn = getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
ResultSet rst = pst.executeQuery();
while (rst.next()) {
System.out.print(rst.getInt("user_id"));
System.out.print(rst.getString("user_name"));
System.out.println(rst.getString("user_password"));
}
System.out.println("JDBC 查詢成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 查詢失敗");
}
}
}
```
運行結果:
```
1大海綿654321
2小海綿123456
JDBC 查詢成功
```
## JDBC 條件查詢數據
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SelectByIdDate {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 準備sql
String sql = "select * from user where user_id = 1";
Connection conn = getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
ResultSet rst = pst.executeQuery();
while (rst.next()) {
System.out.print(rst.getInt("user_id"));
System.out.print(rst.getString("user_name"));
System.out.println(rst.getString("user_password"));
}
System.out.println("JDBC 條件查詢成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 條件查詢失敗");
}
}
}
```
運行結果:
```
1大海綿654321
JDBC 條件查詢成功
```
## JDBC 刪除數據
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DeleteDate {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 準備sql
String sql = "delete from user where user_id = 2";
Connection conn = getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
pst.executeUpdate();
System.out.println("JDBC 刪除成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 刪除失敗");
}
}
}
```
運行結果:
```
JDBC 刪除成功
```
## JDBC 工具類
經過上面的學習,會發現增刪改查都有很多共同點,不同之處只是SQL語句和接收返回值的方式不同,那么為了使程序的復用性更好,我們通常把相同的代碼提取出來。下面的代碼演示一個通過提取出來的工具類進行新增操作。
DBUtil工具類
```java
import java.sql.Connection;
import java.sql.DriverManager;
public class DBUtil {
private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 數據庫地址
private static String userName = "root"; // 數據庫用戶名
private static String passWord = "123456"; // 數據庫密碼
private static Connection conn = null;
public static Connection getConnection() {
if (null == conn) {
try {
// 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 創建數據庫連接
conn = DriverManager.getConnection(url, userName, passWord);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args) {
// 測試數據庫是否連通
System.out.println(getConnection());
}
}
```
新增數據改為以下代碼:
```java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class InsertDate {
public static void main(String[] args) {
// 準備sql
String sql = "INSERT INTO user(user_name, user_password) VALUES ('小海綿', '123456')";
Connection conn = DBUtil.getConnection();
PreparedStatement pst = null;
try {
// 創建預編譯語句
pst = conn.prepareStatement(sql);
// 執行SQL
pst.executeUpdate();
System.out.println("JDBC 插入成功");
// 關閉資源
pst.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("JDBC 插入失敗");
}
}
}
```
同樣的,可以將增刪改查都改成這種方式,使代碼更加的簡潔,更具有邏輯性和復用性。