Java連接MySQL

来源:https://www.cnblogs.com/kohler21/archive/2022/06/09/16358865.html
-Advertisement-
Play Games

JDBC概述 JDBC(Java Data Base Connectivity,java資料庫連接)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成。是Java訪問資料庫的標準規範。 JDBC提供了一種基準,據此可以構建更高級的工 ...


目錄

JDBC概述

JDBC(Java Data Base Connectivity,java資料庫連接)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成。是Java訪問資料庫的標準規範。

JDBC提供了一種基準,據此可以構建更高級的工具和介面,使資料庫開發人員能夠編寫資料庫應用程式。

JDBC需要連接驅動,驅動是兩個設備要進行通信,滿足一定通信數據格式,數據格式由設備提供商規定,設備提供商為設備提供驅動軟體,通過軟體可以與該設備進行通信。

JDBC原理

Java提供訪問資料庫規範稱為JDBC,而生產廠商提供規範的實現類稱為驅動。

JDBC是介面,驅動是介面的實現,沒有驅動將無法完成資料庫連接,從而不能操作資料庫!每個資料庫廠商都需要提供自己的驅動,用來連接自己公司的資料庫,也就是說驅動一般都由資料庫生成廠商提供。

JDBC開發步驟

Java資料庫鏈接主要包括以下幾步:

  1. 註冊驅動
  2. 獲得連接
  3. 獲得語句執行平臺
  4. 執行sql語句
  5. 處理結果
  6. 釋放資源

導入驅動包(jar包)(以eclipse為例)

在項目文件夾下創建lib目錄,用於存放當前項目需要的所有jar包(上面下載的jar包)選擇jar包,右鍵執行build path / Add to Build Path

註冊驅動

JDBC規範定義驅動介面java.sql.Driver,MySql驅動包提供了實現類com.mysql.jdbc.Driver、DriverManager工具類,提供註冊驅動的方法 registerDriver(),方法的參數是java.sql.Driver,所以我們可以通過如下語句進行註冊:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

但是並不提倡使用這種方法,原因如下:

通過查詢com.mysql.jdbc.Driver源碼,我們發現Driver類“主動”將自己進行註冊
*/
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
……
}

// 這樣會造成驅動被註冊兩次  而且這樣編碼不易於程式擴展和維護

通常開發我們使用Class.forName() 載入一個使用字元串描述的驅動類。
如果使用Class.forName()將類載入到記憶體,該類的靜態代碼將自動執行。
所以我們可以使用一下代碼來註冊驅動:

Class.forName("com.mysql.jdbc.Driver");

獲得連接

獲取連接需要方法 DriverManager.getConnection(url,username,password),三個參數分別表示,url 需要連接資料庫的位置(網址) username用戶名 password 密碼。

url比較複雜,下麵是mysql的url:
jdbc:mysql://localhost:3306/mydb
JDBC規定url的格式由三部分組成,每個部分中間使用冒號分隔。
第一部分是jdbc,這是固定的;
第二部分是資料庫名稱,那麼連接mysql資料庫,第二部分當然是mysql了;
第三部分是由資料庫廠商規定的,我們需要瞭解每個資料庫廠商的要求,mysql的第三部分分別由資料庫伺服器的IP地址(localhost)、埠號(3306),以及DATABASE名稱(mydb)組成。

代碼:Connection con = DriverManager.getConnection
(“jdbc:mysql://localhost:3306/mydb”,”root”,”root”);

獲得語句執行平臺

常用方法有以下三種:

  • int executeUpdate(String sql); --執行insert update delete語句.
  • ResultSet executeQuery(String sql); --執行select語句.
  • boolean execute(String sql); --執行select返回true 執行其他的語句返回false.
String sql = "某SQL語句";
獲取Statement語句執行平臺:Statement stmt = con.createStatement();

結果處理

執行insert、update、delete無需處理
我們使用ResultSet來處理結果,ResultSet實際上就是一張二維的表格,我們可以調用其boolean next()方法指向某行記錄,當第一次調用next()方法時,便指向第一行記錄的位置,這時就可以使用ResultSet提供的getXXX(int col)方法(與索引從0開始不同個,列從1開始)來獲取指定列的數據:

rs.next();//指向第一行
rs.getInt(1);//獲取第一行第一列的數據

常用方法有以下幾種:

  • Object getObject(int index) / Object getObject(String name) 獲得任意對象
  • String getString(int index) / Object getObject(String name) 獲得字元串
  • int getInt(int index) / Object getObject(String name) 獲得整形
  • double getDouble(int index) / Object getObject(String name) 獲得雙精度浮點型

釋放資源

與IO流一樣,使用後的東西都需要關閉!關閉的順序是先得到的後關閉,後得到的先關閉。

rs.close();
stmt.close();
con.close();

SQL 註入問題

假設有登錄案例SQL語句如下:

SELECT * FROM 用戶表 WHERE NAME = 用戶輸入的用戶名 AND PASSWORD = 用戶輸的密碼;

此時,當用戶輸入正確的賬號與密碼後,查詢到了信息則讓用戶登錄。但是當用戶輸入的賬號為XXX 密碼為:XXX’ OR ‘a’=’a時,則真正執行的代碼變為:

SELECT * FROM 用戶表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;

此時,上述查詢語句時永遠可以查詢出結果的。那麼用戶就直接登錄成功了,顯然我們不希望看到這樣的結果,這便是SQL註入問題。
為此,我們使用PreparedStatement來解決對應的問題。

預處理對象

使用PreparedStatement預處理對象時,建議每條sql語句所有的實際參數,都使用逗號分隔。

String sql = "insert into sort(sid,sname) values(?,?)";;
PreparedStatement預處理對象代碼:
PreparedStatement psmt = conn.prepareStatement(sql)

常用方法:
{% note info %} 執行SQL語句
int executeUpdate(); --執行insert update delete語句.
ResultSet executeQuery(); --執行select語句.
boolean execute(); --執行select返回true執行其他的語句返回false.
{% endnote %}
{% note warning %}

設置實際參數
void setXxx(int index,Xxxxx)將指定參數設置為給定Java的xx值。在將此值發送到資料庫時,驅動程式將它轉換成一個 SQL Xxx類型值。
{% endnote %}

預處理對象executeUpdate方法

通過預處理對象的executeUpdate方法,完成記錄的insertupdatedelete語句的執行。操作格式統一如下:

  • 註冊驅動
  • 獲取連接
  • 獲取預處理對象
  • SQL語句占位符設置實際參數
  • 執行SQL語句
  • 釋放資源

插入操作(insert)

實現向表中插入指定的新內容

public void demo01() throws Exception {
        // 1註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2獲取連接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3獲得預處理對象
        String sql = "insert into sort(sname) values(?)";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL語句占位符設置實際參數
        stat.setString(1, "奢侈品");
        // 5執行SQL語句
        int line = stat.executeUpdate();
        System.out.println("新添加記錄數:" + line);
        // 6釋放資源
        stat.close();
        conn.close();
}

更新操作(update)

public void demo02() throws Exception {
        // 1註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2獲取連接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3獲得預處理對象中
        String sql = "update sort set sname=? where sid=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL語句占位符設置實際參數
        stat.setString(1, "數位產品");
        stat.setInt(2, 1);
// 5執行SQL語句
        int line = stat.executeUpdate();
        System.out.println("更新記錄數:" + line);
        // 6釋放資源
        stat.close();
        conn.close();
}

刪除操作

public void demo03() throws Exception {
        // 1註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2獲取連接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3獲得預處理對象
        String sql = "delete from sort where sid=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL語句占位符設置實際參數
        stat.setInt(1, 1);
// 5執行SQL語句
        int line = stat.executeUpdate();
        System.out.println("刪除記錄數:" + line);
        // 6釋放資源
        stat.close();
        conn.close();
}

預處理對象executeQuery方法

通過預處理對象的executeQuery方法,完成記錄的select語句的執行。操作格式統一如下:

  • 註冊驅動
  • 獲取連接
  • 獲取預處理對象
  • SQL語句占位符設置實際參數
  • 執行SQL語句
  • 處理結果集(遍歷結果集合)
  • 釋放資源

查詢操作

public void demo04() throws Exception {
        // 1註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2獲取連接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3獲得預處理對象
        String sql = "select * from sort";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL語句占位符設置實際參數
    // 5執行SQL語句
        ResultSet rs = stat.executeQuery();
        // 6處理結果集(遍歷結果集合)
        while( rs.next() ){
            //獲取當前行的分類ID
            String sid = rs.getString("sid");//方法參數為資料庫表中的列名
            //獲取當前行的分類名稱
            String sname = rs.getString("sname");
            //顯示數據
            System.out.println(sid+"-----"+sname);
        }
        // 7釋放資源
        rs.close();
        stat.close();
        conn.close();
}
public void demo05() throws Exception {
        // 1註冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2獲取連接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3獲得預處理對象
        String sql = "select * from sort where sname=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL語句占位符設置實際參數
        stat.setString(1, "奢侈品");
// 5執行SQL語句
        ResultSet rs = stat.executeQuery();
        // 6處理結果集(遍歷結果集合)
        while( rs.next() ){
            //獲取當前行的分類ID
            String sid = rs.getString("sid");//方法參數為資料庫表中的列名
            //獲取當前行的分類名稱
            String sname = rs.getString("sname");
            //顯示數據
            System.out.println(sid+"-----"+sname);
        }
        // 7釋放資源
        rs.close();
        stat.close();
        conn.close();
}

JDBC工具類

“獲得資料庫連接”操作,將在以後的增刪改查所有功能中都存在,可以封裝工具類JDBCUtils。提供獲取連接對象的方法,從而達到代碼的重覆利用。
該工具類提供方法:public static Connection getConn ()。代碼如下:

/*
 * JDBC工具類
 */
public class JDBCUtils {
    public static final  String DRIVERNAME = "com.mysql.jdbc.Driver";
    public static final  String URL = "jdbc:mysql://localhost:3306/mydb";
    public static final  String USER = "root";
    public static final  String PASSWORD = "root";

    static {
        try {
            Class.forName(DRIVERNAME);
        } catch (ClassNotFoundException e) {
            System.out.println("資料庫驅動註冊失敗!");
        }
    }
    //提供獲取連接的方法
    public static Connection getConn() throws Exception {
        // 2. 獲得連接
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        // 返回連接
        return conn;
    }
}

如圖片失效等問題,參閱公眾號文章:https://mp.weixin.qq.com/s/Nlmj6ObCdTeGCQXog_GBrw

歡迎關註我的公眾號,共同學習


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

-Advertisement-
Play Games
更多相關文章
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 時間的獲取及時間各格式間的轉換是比較常用的操作,但一是多種語言經常容易弄混,二是同一種語言同一個功能可能有不同的實現函數,導致每次處理時間經常要百度所以來記錄一下。 另外個人真不喜歡同樣功能有多種寫法的形式,從理想角度說多種實現方式讓不同的人都能以其喜歡的方式進行編寫;但實際上當你忘記的時候,你就總 ...
  • 沙包和打傘的故事 美國在1961年到1972年組織實施的一系列載人登月飛行任務。目的是實現載人登月飛行和人對月球的實地考察,為載人行星飛行和探測進行技術準備,它是世界航天史上具有劃時代意義的一項成就。阿波羅計劃始於1961年5月,至1972年12月第6次登月成功結束,歷時約11年,耗資255億美元。 ...
  • 一、分詞 - jieba 優秀的中文分詞庫,依靠中文詞庫,利用詞庫確定漢子之間關聯的概率,形成分詞結果 import jieba word = '偉大的中華人民共和國' jieba.cut(word) jieba.lcut(word) 二、詞雲庫 - wordcloud 對數據中出現頻率較高的 關鍵 ...
  • pom版本 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.7</version> </dependency> 1.自定義合併單元格 在某些業務場景中可能會有合併單 ...
  • 主要內容 1·學習java日誌體系及日誌工具的演進 2·瞭解日誌採集、處理、分析等各階段的常用中間件 3·學會搭建完整的elk日誌平臺 4·學習日誌打點,切麵,日誌文件等輸出手段 5·項目實戰,完成一訪問日誌鏈路的跟蹤 1、Java日誌體系 1.1 體系概述 1.1.1 日誌介面 JCL:Apach ...
  • 前面我們詳細介紹了SSO、OAuth2的定義和實現原理,也舉例說明瞭如何在微服務框架中使用spring-security-oauth2實現單點登錄授權伺服器和單點登錄客戶端。目前很多平臺都提供了單點登錄授權伺服器功能,比如我們經常用到的QQ登錄、微信登錄、新浪微博登錄、支付寶登錄等等。 如果我們自己 ...
  • 一個工作了3年的粉絲,去一個互聯網公司面試,結果被面試官懟了。 面試官說:”這麼簡單的問題你都不知道? 沒法聊了,回去等通知吧“。 這個問題是: ”什麼是可重入鎖,以及它的作用是什麼?“ 對於這個問題,來看看普通人和高手的回答吧 普通人: 嗯。。。。。。。。。。。。。。。。。。 高手: 好的。 可重 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...