Java數據庫開發-Mysql鏈接

本文爲你們介紹 Java 如何使用JDBC 鏈接 MySQL 數據庫。java

JDBC概述

JDBC(Java Data Base Connectivity,java數據庫鏈接)是一種用於執行SQL語句的Java API,能夠爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。是Java訪問數據庫的標準規範。mysql

JDBC提供了一種基準,據此能夠構建更高級的工具和接口,使數據庫開發人員可以編寫數據庫應用程序。sql

JDBC須要鏈接驅動,驅動是兩個設備要進行通訊,知足必定通訊數據格式,數據格式由設備提供商規定,設備提供商爲設備提供驅動軟件,經過軟件能夠與該設備進行通訊。數據庫

本文使用的是mysql的驅動mysql-connector-java-5.1.39-bin.jar
<span> Download Now</span> 服務器

JDBC原理

Java提供訪問數據庫規範稱爲JDBC,而生產廠商提供規範的實現類稱爲驅動。
JDBC.png
JDBC是接口,驅動是接口的實現,沒有驅動將沒法完成數據庫鏈接,從而不能操做數據庫!每一個數據庫廠商都須要提供本身的驅動,用來鏈接本身公司的數據庫,也就是說驅動通常都由數據庫生成廠商提供。工具

JDBC開發步驟

Java數據庫連接主要包括如下幾步:ui

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

導入驅動包(jar包)

在項目文件夾下建立lib目錄,用於存放當前項目須要的全部jar包(上面下載的jar包)選擇jar包,右鍵執行build path / Add to Build Path
鏈接.png編碼

註冊驅動

JDBC規範定義驅動接口java.sql.Driver,MySql驅動包提供了實現類com.mysql.jdbc.Driver、DriverManager工具類,提供註冊驅動的方法 registerDriver(),方法的參數是java.sql.Driver,因此咱們能夠經過以下語句進行註冊:url

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

可是並不提倡使用這種方法,緣由以下:spa

/*
經過查詢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語句的執行。操做格式統一以下:

  1. 註冊驅動
  2. 獲取鏈接
  3. 獲取預處理對象
  4. SQL語句佔位符設置實際參數
  5. 執行SQL語句
  6. 釋放資源

插入操做(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語句的執行。操做格式統一以下:

  1. 註冊驅動
  2. 獲取鏈接
  3. 獲取預處理對象
  4. SQL語句佔位符設置實際參數
  5. 執行SQL語句
  6. 處理結果集(遍歷結果集合)
  7. 釋放資源

查詢操做

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;
    }
}
相關文章
相關標籤/搜索