學習筆記—JDBC

来源:https://www.cnblogs.com/shangyang/archive/2019/03/29/10594058.html
-Advertisement-
Play Games

JDBC的使用流程,通過JDBC進行對資料庫增刪改查的操作及代碼封裝。 ...


JDBC的概念

  JDBC(Java DataBase Connectivity,java資料庫連接)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成。JDBC提供了一種基準,據此可以構建更高級的工具和介面,使資料庫開發人員能夠編寫資料庫應用程式。

 

JDBC的使用流程

 導入jar包

  1、下載有關資料庫的jar包(下載地址:http://central.maven.org/maven2/mysql/mysql-connector-java/)

  2、導入jar包,在Build Path里配置環境

    Build Path-->Add JARs

載入驅動

// 載入驅動程式:Class.forName(driverClass)

// 載入mysql驅動:
Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");    // 8.0版本以後的mysql驅動

// 載入oracle驅動:
Class.forName("oracle.jdbc.driver.OracleDriver");

獲取資料庫連接對象

String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);

  參數含義:

    url: 表示要連接的數據地址

    user: 資料庫的用戶名

    password: 資料庫的密碼

  作用:

    連接到指定的資料庫並返回連接對象。

創建sql命令對象(編譯和發送sql命令給資料庫)

Statement stmt = conn.createStatement();

創建sql命令

String sql = "insert into user values(13,'王13','wang13')";

指定sql命令,獲得返回結果

int i = stmt.executeUpdate(sql);
ResultSet rs = stmt.executeQuery(sql)

  增刪改 時調用 stmt.executeUpdate(sql)方法。返回值為 int類型。大於等於 1 時表示成功,為 0 時表示失敗。  

  查詢 調用 stmt.executeQuery(sql)方法。返回ResultSet 類型,表示一個結果集。

  ResultSet對象是基於指針進行數據存儲的,類似枚舉。不便於數據的針對性的獲取。可將數據轉換到ArrayList中進行存儲。

關閉資源

        stmt.close();
        conn.close();

  關閉之前打開的資源。需要拋出異常。

 

對數據的增刪改查

增加 (insert)

        // 聲明jdbc變數
        Connection conn = null;
        Statement stmt = null;    
        // 聲明jdbc參數
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";     
        try {
            // 1 載入驅動類
            Class.forName(driver);       
            // 2.獲取資料庫連接對象(連接指定資料庫)
            conn = DriverManager.getConnection(url, user, password);         
            // 3.創建sql命令對象(編譯和發送sql命令給資料庫)
            stmt = conn.createStatement();          
            // 4.創建sql命令
            String sql = "insert into user values(13,'王13','wang13')";       
            // 5.指定sql命令
            int i = stmt.executeUpdate(sql);
            System.out.println("執行結果:" + i);      
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 6.關閉資源
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

 修改 (update)

        // 聲明jdbc變數
        Connection conn = null;
        Statement stmt = null;

        // 聲明jdbc參數
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        try {
            // 1 載入驅動類
            Class.forName(driver);

            // 2.獲取資料庫連接對象(連接指定資料庫)
            conn = DriverManager.getConnection(url, user, password);

            // 3.創建sql命令對象(編譯和發送sql命令給資料庫)
            stmt = conn.createStatement();

            // 4.創建sql命令
            String sql = "update user set username='王update' where id=13";

            // 5.指定sql命令
            int i = stmt.executeUpdate(sql);
            System.out.println("執行結果:" + i);

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 6.關閉資源
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

 刪除 (delete)

        // 聲明jdbc變數
        Connection conn = null;
        Statement stmt = null;

        // 聲明jdbc參數
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        try {
            // 1 載入驅動類
            Class.forName(driver);

            // 2.獲取資料庫連接對象(連接指定資料庫)
            conn = DriverManager.getConnection(url, user, password);

            // 3.創建sql命令對象(編譯和發送sql命令給資料庫)
            stmt = conn.createStatement();

            // 4.創建sql命令
            String sql = "delete from user where id=11";

            // 5.指定sql命令
            int i = stmt.executeUpdate(sql);
            System.out.println("執行結果:" +  i);

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 6.關閉資源
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

查詢(select)

        // 聲明jdbc變數
        Connection conn = null;
        Statement stmt = null;    
        // 聲明jdbc參數
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";
        try {
            // 1 載入驅動類
            Class.forName(driver);
            // 2.獲取資料庫連接對象(連接指定資料庫)
            conn = DriverManager.getConnection(url, user, password);
            // 3.創建sql命令對象(編譯和發送sql命令給資料庫)
            stmt = conn.createStatement();
            // 4.創建sql命令
            String sql = "select * from user";
            // 5.指定sql命令
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getInt(1) + "  " + rs.getString("username") + "  " + rs.getString(3));
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 6.關閉資源
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

  

JDBC的事務管理

  事務:一個事件的完成需要幾個子操作的聯合完成。只要有一個子操作執行失敗,則數據回滾到原始狀態,都成功則提交數據。

  JDBC預設為自動提交事務。進行增刪改操作時應將其設置為手動提交。

conn.setAutoCommit(false);

  預設值為true,自動提交。 false 為手動提交。

  使用try catch進行SQL命令執行提交和回滾。

        try {
            conn.commit();
        } catch (SQLException e) {
            conn.rollback();
            e.printStackTrace();
        }

  try 中使用 conn.commit() 進行數據提交,若報錯則在 catch 中使用 conn.rollback() 進行事務回滾。

 

使用PreparedStatement對象進行資料庫操作

PreparedStatement對象與Statement對象的比較

  Statement對象進行資料庫操作時可能會出現 sql 註入的風險。

  preparedStatement對象在sql語句中使用占位符,可以防止sql註入。可以預編譯,批量執行同一條SQL語句時效率遠大於Statement對象。

// statement對象執行sql語句
Statement stmt = conn.createStatement();
String sql = "insert into user values(13,'王13','wang13')";        
int i = stmt.executeUpdate(sql);


// preparedStatement對象執行sql語句
String sql = "insert into user values(?,?,?)";
PraparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 15);
ps.setString(2, "王15");
ps.setString(3, "123456");
int i = ps.executeUpdate();

 優化封裝代碼

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
user=root
password=123456
db.properties
 1 import java.io.IOException;
 2 import java.io.InputStream;
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 import java.sql.Statement;
 9 import java.util.Properties;
10 
11 public class JUtil {
12     private static String driver;
13     private static String url;
14     private static String user;
15     private static String password;
16     
17     static {
18         // 創建properties對象獲取屬性文件的內容
19         Properties p = new Properties();
20         // 獲取屬性文件的讀取對象流
21         InputStream is = JUtil.class.getResourceAsStream("/db.properties");
22         try {
23             // 載入屬性配置文件
24             p.load(is);
25             // 獲取jdbc參數
26             driver = p.getProperty("driver");
27             url = p.getProperty("url");
28             user = p.getProperty("user");
29             password = p.getProperty("password");
30             // 載入驅動
31             Class.forName(driver);
32         } catch (IOException e) {
33             // TODO Auto-generated catch block
34             e.printStackTrace();
35         } catch (ClassNotFoundException e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         }
39     }
40     
41     // 獲取Connection對象
42     public static Connection getConn() {
43         Connection conn = null;
44         try {
45             conn = DriverManager.getConnection(url, user, password);
46         } catch (SQLException e) {
47             // TODO Auto-generated catch block
48             e.printStackTrace();
49         }
50         return conn;
51     }
52     
53     // 獲取PreparedStatement對象
54     public static PreparedStatement getPre(Connection conn,String sql) {
55         PreparedStatement ps = null;
56         try {
57             ps = conn.prepareStatement(sql);
58         } catch (SQLException e) {
59             // TODO Auto-generated catch block
60             e.printStackTrace();
61         }
62         return ps;
63     }
64     
65     // 關閉資源
66     public static void closeAll(Statement stmt,Connection conn) {
67         try {
68             stmt.close();
69         } catch (SQLException e) {
70             // TODO Auto-generated catch block
71             e.printStackTrace();
72         }
73         try {
74             conn.close();
75         } catch (SQLException e) {
76             // TODO Auto-generated catch block
77             e.printStackTrace();
78         }
79     }
80 }
工具類Jutil
 1         /**
 2      * 封裝DML
 3      * @param sql    sql語句
 4      * @param objs    參數數組
 5      * @return i 大於等於 1 時執行成功,等於 0 時執行失敗。
 6      */
 7     private int executeDML(String sql,Object ... objs) {
 8         Connection conn = null;
 9         PreparedStatement ps = null;
10         int i= 0;
11         try {
12             // 創建連接對象
13             conn = JUtil.getConn();
14             // 手動提交事物
15             conn.setAutoCommit(false);
16             // 獲得sql語句及參數
17             ps = JUtil.getPre(conn, sql);
18             // 給占位符賦值
19             for(int j = 0; j < objs.length; j++) {
20                 ps.setObject(j+1, objs[j]);
21             }
22             // 執行sql命令
23             i = ps.executeUpdate();
24             // 提交
25             conn.commit();
26         } catch (SQLException e) {
27             try {
28                 // 回滾
29                 conn.rollback();
30             } catch (SQLException e1) {
31                 e1.printStackTrace();
32             }
33         } finally {
34             JUtil.closeAll(ps, conn);
35         }
36         return i;
37     }
封裝DML(增刪改)
 1     /**
 2      * 增加
 3      * @param id
 4      * @param name
 5      * @param pwd
 6      * @return  i 大於等於 1 時執行成功,等於 0 時執行失敗。
 7      */
 8     public int insert(int id,String name,String pwd) {
 9         String sql = "insert into user values(?,?,?)";
10         int i = executeDML(sql,id,name,pwd);
11         return i;
12     }
insert增加
 1     /**
 2      * 修改
 3      * @param id
 4      * @param name
 5      * @param pwd
 6      * @return  i 大於等於 1 時執行成功,等於 0 時執行失敗。
 7      */
 8     public int update(int id,String name,String pwd) {
 9         String sql = "update user set username=? where id=?";
10         int i = executeDML(sql,name,id);
11         return i;
12     }
update修改
 1     /**
 2      * 刪除
 3      * @param id
 4      * @param name
 5      * @param pwd
 6      * @return  i 大於等於 1 時執行成功,等於 0 時執行失敗。
 7      */
 8     public int delete(int id,String name,String pwd) {
 9         String sql = "delete from user where id=?";
10         int i = executeDML(sql, id);
11         return i;
12     }
delete刪除
 1     /**
 2      * 查詢
 3      * @return
 4      */
 5     public List<User> select() {
 6         Connection conn = JUtil.getConn();
 7         String sql = "select * from user";
 8         PreparedStatement ps =  JUtil.getPre(conn, sql);
 9         List<User> us = new ArrayList<User>();
10         try {
11             ResultSet rs = ps.executeQuery();
12             while(rs.next()) {
13                 User u = new User();
14                 u.setId(rs.getInt(1));
15                 u.setName(rs.getString(2));
16                 u.setPwd(rs.getString(3));
17                 us.add(u);
18             }
19         } catch (SQLException e) {
20             e.printStackTrace();
21         } finally {
22             JUtil.closeAll(ps, conn);
23         }
24         return us;
25     }
select查詢

 

常見的JDBC錯誤

  1.   ClassNotFoundException:

    驅動類未找到

  2.   java.sql.SQLException: No suitable driver found for :mysql://localhost:3306/test

    URL錯誤
  3.   No database selected
             未找到資料庫

  4.  Access denied for user 'root1'@'localhost' (using password: YES)

             用戶名或密碼錯誤

  5.  java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax;
             sql語句錯誤

  6.   java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '13' for key 'PRIMARY'
           主鍵衝突
     


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # vue項目(用webpack構建)的前提是已安裝了node.js,vue,vue-cli,webpack # 主要命令構建:vue init webpack 項目名(純英文,且不可駝峰)運行:npm run dev打包:npm run build(需要修改配置信息) # element-ui## ...
  • 前言 前文介紹過用Python寫爬蟲,但是當任務多的時候就比較慢, 這是由於Python自帶的http庫urllib2發起的http請求是阻塞式的,這意味著如果採用單線程模型,那麼整個進程的大部分時間都阻塞在等待服務端把數據傳輸過來的過程中。所以我們這次嘗試用node.js去做這個爬蟲。 為什麼選擇 ...
  • Document 電腦算數誤差: 0.1+0.2 = 0.30000000000000004 17.45*3*0.9 = 47.114999999999995 17.45*0.9*3 = 47.115 用math進行計算,避免誤差,見下方js ... ...
  • **vue可視化圖表 基於Echarts封裝好的v-charts** 近期公司又一個新的需求,要做一個訂單和銷售額統計的項目,需要用到可視化圖表來更直觀的展示數據。首先我想到的是Echarts,眾所周知Echarts是一個應用很廣的可視化圖表庫,用來展示統計數據更合適不過,但是偶然間發現了一個更為方 ...
  • 一、寫在前面 首先呢,由於之前重裝系統,又要重新配置環境,然後還有一些別的事,導致我一直沒有寫爬蟲了,不過現在又可以繼續寫了。 然後我這次說的模擬登錄新浪微博呢,不是使用Selenium模擬瀏覽器操作,畢竟Selenium的效率是真的有些低,所以我選擇用Python發送請求實現模擬登錄,整個過程還算 ...
  • import requests from bs4 import BeautifulSoup from math import ceil header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (... ...
  • 一般公司的項目一般都是用Oracle、Mysql、SQL Server等一些國外的資料庫。前段時間公司做了一個國家政府保密單位的項目,別人要求用國產資料庫,所以研究了下,最後決定用神舟通用的,其實國產也很好幾家做資料庫的還不錯,下邊簡單總結了下,以供參考 1:南大通用 公司簡介 天津南大通用數據技術 ...
  • 題目如下。解題步驟參考的是https://cloud.tencent.com/developer/news/373865中作者的思路。 1.首先,兩個四位數相加等於一個五位數,那麼這個五位數的第一位必定是1,也就是“三”=1,。 2.繼續分析“祥”+“三”,若是“祥”(8),“三”為1,那麼低位必定 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...