[TOC]
## 一、JDBC連接
使用JDBC時,我們先了解什么是Connection。Connection代表一個JDBC連接,它相當于Java程序到數據庫的連接(通常是TCP連接)。打開一個Connection時,需要準備URL、用戶名和口令,才能成功連接到數據庫。
URL是由數據庫廠商指定的格式,例如,MySQL的URL是:
<br>
~~~
jdbc:mysql://<hostname>:<port>/<db>?key1=value1&key2=value2
~~~
<br>
假設數據庫運行在本機`localhost`,端口使用標準的`3306`,數據庫名稱是`learnjdbc`,那么URL如下:
~~~
jdbc:mysql://localhost:3306/learnjdbc?useSSL=false&characterEncoding=utf8
~~~
<br>
后面的兩個參數表示不使用SSL加密,使用UTF-8作為字符編碼(注意MySQL的UTF-8是`utf8`)。
要獲取數據庫連接,使用如下代碼:
```
package day07;
import java.sql.DriverManager;
public class day01jdbc {
public static void main(String args[]){
// JDBC連接的url,不同數據庫有不同的格式
String JDBC_URL = "jdbc:mysql://localhost:3306/go_gin_test";
String JDBC_USER = "root";
String JDBC_PASSWORD = "12345";
// 獲得連接
Connection conn = DriverManager.getConnection(JDBC_URL,JDBC_USER,JDBC_PASSWORD);
// 訪問數據庫
// 關閉連接
conn.close();
}
}
```
<br>
<br>
核心代碼是`DriverManager`提供的靜態方法`getConnection()`。`DriverManager`會自動掃描classpath,找到所有的JDBC驅動,然后根據我們傳入的URL自動挑選一個合適的驅動。
因為JDBC連接是一種昂貴的資源,所以使用后要及時釋放。使用`try (resource)`來自動釋放JDBC連接是一個好方法:
```
try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {
...
}
```
<br>
<br>
## 二、JDBC中常用類和接口
連接到數據庫(Connection)、建立操作指令(Statement)、執行查詢指令(executeQuery)、獲得查詢結果(ResultSet)等。
### 1、驅動程序管理類(DriverManager)
DriverManager類是JDBC的管理類,作用于用戶和驅動程序之間。它跟蹤在可用的驅動程序,并在數據庫和相應驅動程序之間建立連接。另外,DriverManager類也處理諸如驅動程序登陸時間限制及登錄和跟蹤消息的顯示事務。對于簡單的應用程序,一般程序員需要在此類中直接使用唯一的方法時DriverManager.getConnection()。該方法將建立與數據庫的鏈接。JDBC允許用戶調用DriverManager的方法getDriver()、getDrivers()和registerDriver()及Driver的方法connect().
### 2、聲明類(Statement)
Statement對象用于將SQL語句發送到數據庫中。實際上有三種Statement對象,它們都作為在給定鏈接上執行SQL語句的包容器:Statement、PreparedStatement(它從Statement繼承而來)和CallableStatement(它從PreparedStatement繼承而來)。它們都專用于發送特定類型的SQL語句:
(1)Statement對象用于執行不帶參數的簡單的SQL語句;Statement接口提供了執行語句和獲取結果的基本方法。
(2)PerparedStatement對象用于執行帶或不帶IN參數的預編譯SQL語句;PeraredStatement接口添加處理IN參數的方法;
(3)CallableStatement對象用于執行對數據庫已存儲過程的調用;CallableStatement添加處理OUT參數的方法。
#### Statement提供了許多方法,最常用的方法如下:
(1)execute()方法:運行語句,返回是否有結果集。
(2)executeQuery()方法:運行查詢語句,返回ReaultSet對象。
(3)executeUpdata()方法:運行更新操作,返回更新的行數。
(4)addBatch()方法:增加批處理語句。
(5)executeBatch()方法:執行批處理語句。
(6)clearBatch()方法:清除批處理語句。
### 3、數據庫連接類 (Connection)
Connection對象代表與數據庫的鏈接。連接過程包括所執行的SQL語句和在該連接上所返回的結果。一個應用程序可與單個數據庫有一個或多個連接,或者可與很多數據庫有連接。打開連接與數據庫建立連接的標準方法是調用DriverManager.getConnection()方法。
String url="jdbc:mysql://127.0.0.1:3306/imooc";
String user="root";
String password="tiger";
DriverManager.getConnection(url,user,password);
### 4、結果集合類 (ResultSet)
ResultSet包含符合SQL語句中條件的所有行記錄,并且它通過一套get方法(這些get方法可以訪問當前行中的不同列)提供了對這些行中數據的訪問。ResultSet.next()方法用于移動到ResultSet中的下一行,使下一行成為當前行。
5、JDBC編程步驟
(1)加載驅動程序:Class.forName(driverClass)
加載mysql驅動:Class.forName("com.mysql.jdbc.Driver");
加載oracle驅動:Class.forName("oracle.jdbc.driver.OracleDriver");
(2)獲得數據庫連接
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/imooc",user,password);
DriverManager.gerConnection(URL,user,password);
(3)創建Statement對象:conn.createStatement();
(4)向數據庫發送SQL命令
(5)處理數據庫的返回結果(ResultSet類)
<br>
**案例演示:**
```
package day07;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
import org.apache.log4j.Logger;
public class day01jdbc {
// MySQL 8.0 以下版本 - JDBC 驅動名及數據庫 URL
// static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
// static final String DB_URL = "jdbc:mysql://localhost:3306/go_gin_test";
// MySQL 8.0 以上版本 - JDBC 驅動名及數據庫 URL
/*
* final:修飾的類不能被繼承。
* static:修飾符能夠與變量、方法一起使用,表示是“靜態”的
* */
// static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
// static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/go_gin_test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
// 日志方法
private static Logger logger = Logger.getLogger(day01jdbc.class);
// 配置文件封裝方法
private static String LoadProperties(String jdbcPATH,String jdbcData) throws Exception {
Properties properties = new Properties(); // Properties該類主要用于讀取Java的配置文件,
// FileInputStream流被稱為文件字節輸入流,意思指對文件數據以字節的形式進行讀取操作如讀取圖片視頻等
InputStream iStream = new FileInputStream(new File(jdbcPATH));
properties.load(iStream); // 使用Properties對象里的方法讀取FileInputStream返回的字節流
/*
* getProperty在此屬性列表中搜索具有指定鍵的屬性。如果在此屬性列表中找不到該鍵,則會檢查默認屬性列表及其默認值(遞歸)。如果未找到該屬性,則該方法返回默認值參數。
* */
// String key = properties.getProperty("jdbc.USER");
String key = properties.getProperty(jdbcData);
return key;
}
public static void main(String[] args) throws Exception { //ClassNotFoundException 應用程序試圖加載類時,找不到相應的類,拋出該異常。
String DB_URL = LoadProperties("src/day07/jdbcmysql.properties","jdbc.DB_URL");
String USER = LoadProperties("src/day07/jdbcmysql.properties","jdbc.USER");
String PASS = LoadProperties("src/day07/jdbcmysql.properties","jdbc.PASS");
String JDBC_DRIVER = LoadProperties("src/day07/jdbcmysql.properties","jdbc.JDBC_DRIVER");
Connection conn = null;
Statement stmt = null;
try {
// 注冊 JDBC 驅動
logger.info(Class.forName(JDBC_DRIVER));
// 打開鏈接
System.out.println("連接數據庫...");
// DriverManager`提供的靜態方法`getConnection()`自動掃描classpath,找到所有的JDBC驅動,然后根據我們傳入的URL自動挑選一個合適的驅動。
conn = DriverManager.getConnection(DB_URL, USER, PASS);
logger.info(conn);
// 執行查詢
System.out.println(" 實例化Statement對象...");
stmt = conn.createStatement();
logger.info(stmt);
String sql;
sql = "SELECT id, `name`, money FROM gin_user";
ResultSet rs = stmt.executeQuery(sql);
// 展開結果集數據庫
while (rs.next()) { // next 返回第一個元素
// 通過字段檢索
int id = rs.getInt("id");
String name = rs.getString("name");
String money = rs.getString("money");
// 輸出數據
System.out.print("ID: " + id);
System.out.print(", NAME: " + name);
System.out.print(", money: " + money);
System.out.print("\n");
}
// 完成后關閉
rs.close();
stmt.close();
conn.close();
} catch (SQLException se) {
// 處理 JDBC 錯誤
logger.info(se);
se.printStackTrace();
} catch (Exception e) {
// 處理 Class.forName 錯誤
logger.info(e);
e.printStackTrace();
} finally {
// 關閉資源
try {
if (stmt != null) stmt.close();
} catch (SQLException se2) {
}// 什么都不做
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
```
**運行結果:**
```
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:54)----class com.mysql.cj.jdbc.Driver
連接數據庫...
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:60)----com.mysql.cj.jdbc.ConnectionImpl@38082d64
實例化Statement對象...
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:65)----com.mysql.cj.jdbc.StatementImpl@5d624da6
ID: 1, NAME: WW, money: 23492
ID: 2, NAME: 風清揚, money: 23021
ID: 3, NAME: 洪七公, money: 18000
ID: 4, NAME: 降龍十八掌, money: 8000
ID: 5, NAME: 張無忌, money: 6000
ID: 6, NAME: 張三豐, money: 13000
ID: 7, NAME: 楊過, money: 9210
ID: 8, NAME: 小龍女, money: 5000
ID: 9, NAME: 小龍女, money: 5200
ID: 10, NAME: WW, money: 3210
ID: 11, NAME: 馬可波羅, money: 10100
ID: 12, NAME: 令狐沖, money: 2340
ID: 13, NAME: 東方不敗, money: 7800
ID: 14, NAME: 獨孤求敗, money: 12380
ID: 15, NAME: 劍圣, money: 29380
ID: 16, NAME: taotaomao, money: 3400
ID: 17, NAME: meimeixin, money: 5400
ID: 18, NAME: kexinle, money: 6800
ID: 19, NAME: HdfFFs, money: 3452
ID: 20, NAME: PdSSc, money: 23410
ID: 21, NAME: asjkhd, money: 23121
Goodbye!
```
<br>
<br>
## 數據類型
有的童鞋可能注意到了,使用JDBC的時候,我們需要在Java數據類型和SQL數據類型之間進行轉換。JDBC在`java.sql.Types`定義了一組常量來表示如何映射SQL數據類型,但是平時我們使用的類型通常也就以下幾種:
| SQL數據類型 | Java數據類型 |
| --- | --- |
| BIT, BOOL | boolean |
| INTEGER | int |
| BIGINT | long |
| REAL | float |
| FLOAT, DOUBLE | double |
| CHAR, VARCHAR | String |
| DECIMAL | BigDecimal |
| DATE | java.sql.Date, LocalDate |
| TIME | java.sql.Time, LocalTime |
注意:只有最新的JDBC驅動才支持`LocalDate`和`LocalTime`。
- Java自動化測試
- 第一章:Java:基礎內容
- 1.1:Java:Hello Word
- 1.2:Java:熱身
- 1.3:Java:注釋
- 1.4:Java:標識符
- 1.5:Java:常量
- 1.6:Java:基本數據類型
- 1.7:Java:引用類型
- 1.8:Java:String類
- 第二章:Java:運算符
- 2.1:Java:算數運算符
- 2.2:Java:關系運算符
- 2.3:Java:邏輯運算
- 2.4:Java:賦值運算符
- 2.5;Java:三元運算符
- 2.6:Java:位運算符
- 第三章:Java:循環控制語句
- 3.1:Java:for循環
- 3.2:Java:while循環
- 3.3:Java:switch
- 3.4:Java:if else
- 3.5:Java:練習題
- 第四章:Java:函數與全局/局部變量
- 4.1:Java:局部變量
- 4.2:Java:全局變量
- 第五章:Java:方法
- 5.1:Java:初識方法
- 5.2:Java:方法調用
- 5.3:Java:方法重載
- 5.4:Java:構造方法
- 5.5:Java:方法的注意事項
- 第六章:Java:面向對象
- 6.1:Java:小案例
- 6.2:Java:this 關鍵字
- 6.3:Java:super 關鍵字
- 6.4:Java:static 關鍵字
- 6.5:Java:final關鍵字
- 6.6:Java:instanceof 運算符
- 6.7:Java:面向對象之封裝
- 6.8:Java:面向對象之繼承
- 6.9:Java:面向對象之多態
- 第七章:Java:面向對象高級進階
- 7.1:Java:抽象類
- 7.2:Java:Java中String類
- 7.3:Java:interface接口
- 7.4:Java:ArrayList
- 7.5:Java:HashSet
- 7.6:Java:HashMap
- 7.7:Java:反射(reflection)
- 第八章:Java:日志以及異常捕獲
- 8.1:Java:log4j
- 8.2:Java:異常初識基礎
- 8.3:Java:未被捕獲的異常
- 8.4:Java:try和catch的使用
- 8.5:Java:多重catch語句的使用
- 8.6:Java:throws/throw 關鍵字
- 8.7:Java:finally關鍵字
- 8.8:Java:自定義異常
- 第九章:Java:xml and IO
- 9.1:Java:IO基本概念
- 9.2:java:properties
- 9.3:Java:xml基本介紹
- 9.4:Java:xml操作實例
- 第十章:Java:JDBC編程
- 10.1:Java:JDBC介紹
- 10.2:Java:JDBC查詢
- 10.3:Java:JDBC插入
- 10.4:Java:Batch
- 10.5:Java:JDBC連接池
- 第十一章:Java:TestNG
- 11.1:java:TestNG簡介
- 11.2:Java:TestNG小實例
- 11.3:Java:TestNG.xml文件配置
- 11.4:Java:TestNG基本注解
- 11.5:Java:TestNG注解代碼
- 11.6:Java:TestNG預期異常
- 11.7:Java:TestNG忽略測試
- 11.8:Java:TestNG超時測試
- 11.9:Java:TestNG分組測試