學習筆記—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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...