1. 啥是 JDBC ?
JDBC 全稱:
Java DataBase Connection
復制代碼
意思就是使用 java 代碼連接資料庫,
但是問題來了,世界上有一堆資料庫例如 Mysql、Oracle、mongodb 等,他們的使用方法都不太一樣,
難道我要連不同的資料庫就需要寫不同的 java 程式嗎?這也太麻煩了,

為了解決這個問題,SUN 公司(開發JDK的公司)就決定指定一套介面,這套介面就是使用 java 連接資料庫的規范,其實就是 JDBC,
而 JDBC 介面的實作類由資料庫廠家負責撰寫,他們撰寫后把實作類打包成 jar 包,
這個 jar 包就是一個驅動(例如電腦要連上網需要安裝網卡驅動),我們下載好這個驅動后把他放到我們的專案里,
接著撰寫 java 代碼去完善 jar 包要求的連接資料庫的資訊,然后就能連接到與驅動對應的資料庫了,
前面我們在學面向物件的時候知道介面體現了多型性,SUN 公司設計一個 JDBC 規范,不用過多關注資料庫廠商怎樣實作這個介面,大大提高了程式的可擴展性,

2. 匯入 jar 包
這里我們以連接 Mysql 為例,
- 將連接 mysql 資料庫的 jar 包放到 lib 目錄下,
注:jar 包就是連接資料庫的驅動,每個資料庫的廠商將自己實作了 JDBC 的代碼打包成 jar 包,

- 將 jar 包作為庫添加到專案中,
注:因為 jar 包就是編譯后的 java 代碼,所以這里就相當于在專案中添加了 java 代碼,
選擇 lib 目錄,右鍵選擇 Add as a Library,

3. 開發步驟
- 加載資料庫的驅動
Class.forName("com.mysql.jdbc.Driver");
復制代碼
注:這里驅動的名字要和資料庫的版本對應,
Mysql5版本:
Class.forName("com.mysql.jdbc.Driver");
復制代碼
Mysql8版本:
Class.forName("com.mysql.cj.jdbc.Driver");
復制代碼
- 創建資料庫的連接
// 2. 獲得資料庫連接
String url = "jdbc:mysql://localhost:3306/course_price";
String user = "root";
String password = "12345678";
Connection conn = DriverManager.getConnection(url, user, password);
復制代碼
創建資料庫的連接需要三個引數:
url,user,password
復制代碼
要想連接資料庫,第一需要知道資料庫是什么型別的資料庫,第二需要知道連接的資料庫名稱吧,所以 url 的格式:
jdbc:資料庫型別://localhost:3306/資料庫名稱
復制代碼
有了 url,還需要知道資料庫的賬號密碼,所以有了這三個引數,就能通過 java 程式連接資料庫了,
- 測驗連接
public static void main(String[] args) {
Connection conn = null;
try {
// 1. 加載資料庫驅動
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 獲得資料庫連接
String url = "jdbc:mysql://localhost:3306/course_price";
String user = "root";
String password = "12345678";
// 3. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
if(null!=conn){
System.out.println("資料庫連接成功");
}else{
System.out.println("資料庫連接失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//4、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
測驗結果:

注:Connection、PrepareStatement、ResultSet 都會占用一定的資源,它們需要全部釋放/關閉,
- 常見錯誤
賬號或者密碼錯誤
Access denied for user 'root'@'localhost' (using password: YES)
復制代碼
資料庫名稱錯誤
Unknown database 'course_pric'
復制代碼
url 中資料庫型別錯誤
No suitable driver found for jdbc:mysq://localhost:3306/course_price
復制代碼
4. 讀取組態檔資訊
我們在開發的時候,一般會將連接資料庫的資訊寫到組態檔里面,這樣如果連接資訊有改變,直接改組態檔里面的資訊就行,
4.1 新建 jdbc.properties 檔案
url=jdbc:mysql://localhost:3306/course_price
user=root
password=12345678
driver:com.mysql.jdbc.Driver
復制代碼

4.2 加載組態檔資訊
// 1. 加載組態檔
Properties pro=new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url=pro.getProperty("url");
String user=pro.getProperty("user");
String password=pro.getProperty("password");
String driver=pro.getProperty("driver");
復制代碼
4.3 完整代碼
public static void main(String[] args) {
Connection conn = null;
try {
// 1. 加載組態檔
Properties pro=new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url=pro.getProperty("url");
String user=pro.getProperty("user");
String password=pro.getProperty("password");
String driver=pro.getProperty("driver");
// 3. 加載資料庫的驅動
Class.forName(driver);
// 4. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
if(null!=conn){
System.out.println("資料庫連接成功");
}else{
System.out.println("資料庫連接失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//5、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
5. 實作增刪改查
5.1 資料庫操作物件
連接資料庫之后我們就可以使用 java 程式操作資料庫,盡情地蹂躪資料庫中的資料了,
那怎樣操作資料庫中的資料呢?其實就是使用 java 程式執行 SQL 陳述句,然后回傳執行結果,
我們創建的資料庫連接物件 connection 有一個小弟,這小弟叫資料庫操作物件,它專門用來執行 SQL 陳述句并回傳執行結果,
這個小弟有兩種型別:
Statement 和 PrepareStatement,
復制代碼
Statement 是先進行 SQL 陳述句拼接,再進行 SQL 陳述句的編譯,存在SQL注入問題,
PreparedStatement 是預先編譯 SQL 陳述句(帶有占位符的SQL),然后再給占位符賦值,可以防止 SQL 注入,
因為 PreparedStatement 效率高并且可以防 SQL 注入,所以這里我們使用 PreparedStatement 物件進行增刪改查,
5.2 查詢資料
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1. 加載組態檔
Properties pro = new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
String driver = pro.getProperty("driver");
// 3. 加載資料庫的驅動
Class.forName(driver);
// 4. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
// 5. sql 陳述句
String sql = "select * from user";
// 6. 創建執行sql的物件
ps = conn.prepareStatement(sql);
// 7. 執行結果
rs = ps.executeQuery();
while (rs.next()) {
System.out.println("id:" + rs.getString("id"));
System.out.println("name:" + rs.getString("name"));
System.out.println("------");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//8、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
注:
-
- ResultSet 表示執行的結果
-
- while(resultSet.next()) 表示如果執行結果有資料,就一直遍歷資料,
執行結果:

5.3 添加資料
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
// 1. 加載組態檔
Properties pro = new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
String driver = pro.getProperty("driver");
// 3. 加載資料庫的驅動
Class.forName(driver);
// 4. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
// 5. sql 陳述句
String sql = "insert into user(id,name) values(?,?)";
// 6. 創建執行sql的物件
ps = conn.prepareStatement(sql);
// 7. 給 ?賦值
ps.setInt(1, 5);
ps.setString(2, "張無忌");
// 8. 執行sql
int count = ps.executeUpdate();
if (count > 0) {
System.out.println("添加成功");
} else {
System.out.println("添加失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//9、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
執行結果:

5.4 修改資料
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
// 1. 加載組態檔
Properties pro = new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
String driver = pro.getProperty("driver");
// 3. 加載資料庫的驅動
Class.forName(driver);
// 4. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
// 5. sql 陳述句
String sql = "update user set name = ? where id = ?";
// 6. 創建執行sql的物件
ps = conn.prepareStatement(sql);
// 7. 給 ?賦值
ps.setString(1, "周芷若");
ps.setInt(2, 5);
// 8. 執行sql
int count = ps.executeUpdate();
if (count > 0) {
System.out.println("修改成功");
} else {
System.out.println("修改失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//9、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
執行結果:

5.5 洗掉資料
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
// 1. 加載組態檔
Properties pro = new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
String driver = pro.getProperty("driver");
// 3. 加載資料庫的驅動
Class.forName(driver);
// 4. 創建資料庫的連接
conn = DriverManager.getConnection(url, user, password);
// 5. sql 陳述句
String sql = "delete from user where id = ?";
// 6. 創建執行sql的物件
ps = conn.prepareStatement(sql);
// 7. 給 ?賦值
ps.setInt(1, 4);
// 8. 執行sql
int count = ps.executeUpdate();
if (count > 0) {
System.out.println("洗掉成功");
} else {
System.out.println("洗掉失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//9、釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
執行結果:

6. 工具類
從上面的例子中,我們發現每次操作都要寫一堆連接資料庫的資訊,操作完還要釋放資源,真是煩死了,那能不能簡化一下呢?
能,把資料庫連接封裝成工具類,
我們之前學 static 關鍵字的時候知道 static 修飾的方法可以直接用類名呼叫,所以特別適合工具類的使用,
JDBC 工具類:
public class JDBCUtils {
private static String user;
private static String password;
private static String url;
private static String driver;
static {
// 靜態代碼塊只需要加載一次,讀取資源檔案
try {
// 1. 加載組態檔
Properties pro = new Properties();
pro.load(new FileReader("resource/jdbc.properties"));
// 2. 獲取組態檔中連接資料庫的資訊
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
// 3. 創建資料庫連接驅動
Class.forName(driver);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 4. 獲取連接物件
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
// 5. 釋放資源
public static void close(PreparedStatement ps, Connection conn) {
close(null, ps, conn);
}
// 6. 釋放資源(多載)
public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != ps) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
復制代碼
有了 JDBC 連接的工具類,代碼就可以很清爽,例如:
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
// 1. 獲取資料庫連接物件
conn = JDBCUtils.getConnection();
// 2. sql 陳述句
String sql = "delete from user where id = ?";
// 3. 創建執行sql的物件
ps = conn.prepareStatement(sql);
// 4. 給 ?賦值
ps.setInt(1, 4);
// 5. 執行sql
int count = ps.executeUpdate();
if (count > 0) {
System.out.println("洗掉成功");
} else {
System.out.println("洗掉失敗");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 6. 釋放資源
JDBCUtils.close(ps, conn);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375785.html
標籤:其他
