JavaJDBC程式設計

2022-01-08 14:00:01

JDBC,即Java Database Connectivity,java資料庫連線。是一種用於執行SQL語句的Java API,它是Java中的資料庫連線規範。這個API由java.sql.,javax.sql. 包中的一些類和介面組成,為Java開發人員運算元據庫提供了一個標準的API,可以為多種關聯式資料庫提供統一存取。

資料庫程式設計的必備條件

  • 程式語言,如Java,C、C++、Python等;
  • 資料庫驅動包:不同的資料庫,對應不同的程式語言;
  • 資料庫驅動包:不同的資料庫,對應不同的程式語言提供了不同的資料庫驅動包,如:MySQL提供了Java的驅動包mysql-connector-java,需要基於Java操作MySQL就需要該驅動包。同樣的,要基於Java操作Oracle資料庫則需要Oracle的資料庫驅動包ojdbc。

資料庫驅動包

下載驅動包地址:點進去之後,輸入MySQL;
在這裡插入圖片描述
本文下載的是 5.1.49

在這裡插入圖片描述
下載如下:在這裡插入圖片描述
接下來就是**設定IDEA:
在這裡插入圖片描述
在這裡插入圖片描述
ok**就設定成功了~

JDBC使用步驟

  1. 建立資料庫連線物件:Connection
 //建立資料庫連線:Connection
 Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/java43?user=root&password=wx710500&useUnicode" +
                "=true&characterEncoding=UTF-8&useSSL=false");

注意URL格式

MySQL資料連線的URL引數格式如下:
jdbc:mysql://伺服器地址:埠號/要連線的資料庫名?引數名=引數值

  1. 建立操作命令物件:Statement
 //通過連線物件conn建立操作命令物件Statement,該物件用來操作sql的一個抽象物件
  Statement s=conn.createStatement();
  1. 使用操作命令物件來執行SQL
//查詢操作:
        // (1) 呼叫Statement操作命令物件的executeQuery(sql)
        // (2) 返回一個ResultSet結果集物件(查詢SQL執行的結果集)
        ResultSet r=s.executeQuery("select id,name,role,salary from emp where id=3");

注意

更新操作(插入,修改,刪除):呼叫executeUpdate方法;返回結果集採用int接收,表示成功執行了幾條資料。

  1. 處理結果集物件:ResultSet
 //處理結果集:結果集可能是多行資料,遍歷來實現
        //呼叫next()
        while(r.next()){
            int id=r.getInt("id");
            String name=r.getString("name");
            String role=r.getString("role");
            Double salary=r.getDouble("salary");
            //此處是列印處理
            System.out.printf("id=%s,name=%s,role=%s,salary=%s\n",id,name,role,salary);

        }
  1. 釋放資源

(1)無論什麼情況都要釋放資源;
(2)釋放順序:與建立順序相反,此處釋放順序為(a.結果集物件;b.命令物件;c.連線物件)

完整程式碼:

package com.xntu.jdbc;

import java.sql.*;

public class Test {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Connection conn =null;
        Statement s =null;
        ResultSet r =null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //建立資料庫連線:Connection
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java43?user=root&password=wx710500&useUnicode" +
                    "=true&characterEncoding=UTF-8&useSSL=false");
            //通過連線物件conn建立操作命令物件Statement,該物件用來操作sql的一個抽象物件
            s = conn.createStatement();
            //查詢操作:
            // (1) 呼叫Statement操作命令物件的executeQuery(sql)
            // (2) 返回一個ResultSet結果集物件(查詢SQL執行的結果集)
            r = s.executeQuery("select id,name,role,salary from emp where id=3");
            //處理結果集:結果集可能是多行資料,遍歷來實現
            //呼叫next()
            while (r.next()) {
                int id = r.getInt("id");
                String name = r.getString("name");
                String role = r.getString("role");
                Double salary = r.getDouble("salary");
                System.out.printf("id=%s,name=%s,role=%s,salary=%s\n", id, name, role, salary);

            }
        }finally {
            //釋放資源
            //出現異常時,物件可能沒有被賦值,呼叫close就會出現空指標異常
            if (r != null)
                r.close();
            if (s != null)
                s.close();
            if (conn != null)
                conn.close();
        }
    }
}

執行結果:
在這裡插入圖片描述
與資料庫查詢結果相一致
在這裡插入圖片描述

JDBC優化部分程式碼

優化1: 獲取Connection物件通常有兩種方式:

  • DriverManager 靜態方法獲取;

缺點

無法重複利用,每次使用完以後釋放資源時,通過connection.close()都是關閉物理連線。

  • DataSource 資料來源獲取,也稱作資料庫連線池獲取;

程式碼如下

//先建立資料庫連線池,再通過連線池獲取資料庫連線物件
  DataSource ds = new MysqlDataSource();
//建立資料庫連線池:初始化時,就會建立一定數量的資料庫連線,這些連線物件是可以重複使用,效率更高
 //整個url帶引數可以只使用setURL方法,也可以將引數呼叫方法的方式來設定
   ((MysqlDataSource) ds).setURL("jdbc:mysql://localhost:3306/java43");
   ((MysqlDataSource) ds).setUser("root");
   ((MysqlDataSource) ds).setPassword("wx710500");
   ((MysqlDataSource) ds).setUseUnicode(true);
   ((MysqlDataSource) ds).setCharacterEncoding("UTF-8");
   ((MysqlDataSource) ds).setUseSSL(false);
   conn = ds.getConnection();

該種方式效能高,可以重複使用,往往實際應用中多使用

優化2:Statement物件

Statement物件主要是將SQL語句傳送到資料庫中。JDBC API中主要提供了三種Statement物件:

  • Statement 物件:用於執行不帶引數的簡單SQL語句;
  • PreparedStatement 物件:用於執行帶或不帶引數的SQL語句;SQL語句會預編譯在資料庫裡面;執行速度快於Statement物件。
  • CallableStatement 物件:用於執行資料庫儲存過程的呼叫;

優化部分整體程式碼:

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.*;

public class test {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet r = null;
        try {
            //建立資料庫連線池,通過連線池獲取資料庫連線物件
            DataSource ds = new MysqlDataSource();
            //設定URL
            ((MysqlDataSource) ds).setURL("jdbc:mysql://localhost:3306/java43");
            ((MysqlDataSource) ds).setUser("root");
            ((MysqlDataSource) ds).setPassword("wx710500");
            ((MysqlDataSource) ds).setUseUnicode(true);
            ((MysqlDataSource) ds).setCharacterEncoding("UTF-8");
            ((MysqlDataSource) ds).setUseSSL(false);
            //通過連線池物件獲取連線物件
            conn = ds.getConnection();

            //使用操作命令物件PreparedStatement
            String queryName = "skdjsj' or '1'='1";
            int queryId = 3;
            //準備一個帶?預留位置的sql
            String sql = "select id,name,role,salary from emp where name=? or id=?";
            //建立預編譯的操作命令物件
            ps = conn.prepareStatement(sql);
            //替換預留位置:呼叫setXXX方法,第一個引數,表示第幾個預留位置(從1開始),第二個引數,表示要替換的值
            //替換的值是什麼型別,就呼叫setXXX方法
            ps.setString(1, queryName);
            ps.setInt(2, queryId);

            //執行sql,需要使用無參的方法
            r = ps.executeQuery(); //查詢操作

            //處理結果集:結果集可能是多行資料,需要遍歷來獲取
            // 呼叫next就移動到下一行,返回true代表該行有資料,返回false代表該行沒有資料
            while (r.next()) {
                int id = r.getInt("id");
                String name = r.getString("name");
                String role = r.getString("role");
                Double salary = r.getDouble("salary");
                System.out.printf("id=%s, name=%s, role=%s, salary=%s\n",
                        id,  name, role, salary);
            }
        }finally {//無論如何,都要釋放資源
            //釋放資源:
            //出現異常的時候,物件可能還沒有賦值(初始化),呼叫close就會出現空指標異常
            if(r != null)
                r.close();
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        }

    }
}

結果如下:在這裡插入圖片描述