Java使用JDBC連接數據庫的詳細步驟

一、JDBC是什麼?

JDBC 指 Java 數據庫連接(Java Database Connectivity),是一種標準Java應用編程接口( JAVA API),JDBC就是一套sun公司定義的接口,JDBC本質上就是Sun公司制定的一套接口(interface)!每個數據庫廠商需要實現這套接口。我們隻需要調用需要即可用來連接 Java 編程語言和廣泛的數據庫。

JDBC API 庫包含下面提到的每個任務,都是與數據庫相關的常用用法。

  • 制作到數據庫的連接。
  • 創建 SQL 或 MySQL 語句。
  • 執行 SQL 或 MySQL 查詢數據庫。
  • 查看和修改所產生的記錄。

從根本上來說,JDBC 是一種規范,它提供瞭一套完整的接口,允許便攜式訪問到底層數據庫,因此可以用 Java 編寫不同類型的可執行文件,例如:

  1. Java 應用程序
  2. Java Applets
  3. Java Servlets
  4. Java ServerPages (JSPs)
  5. Enterprise JavaBeans (EJBs)

所有這些不同的可執行文件就可以使用 JDBC 驅動程序來訪問數據庫,這樣可以方便的訪問數據。

JDBC 具有 ODBC 一樣的性能,允許 Java 程序包含與數據庫無關的代碼。

二、使用步驟

1.註冊驅動

數據庫廠商的Java程序員所寫的實現類 叫做驅動 Driver

註冊驅動

第一種註冊方法代碼如下:(不常用)

public class 註冊驅動 {
    public static void main(String[] args) {
        try {
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
 
}

第二種方利用反射的特性,加載過程中註冊驅動的過程。

關於反射的補充: Java中的靈魂-反射機制

關於JDBC—MySQL中以類加載的方式註冊驅動(反射)詳解鏈接:

JDBC—MySQL以類加載的方式註冊驅動(反射)

class.forName(com.mysql.jdbc.Driver);

上述一行代碼就可以通過反射這個動作調用類,實現Driver類的加載 但是需要使用try和catch語句塊環繞

2.獲取連接

要連接數據庫的url—- String url="jdbc:mysql://localhost:3306/test?"+ "useUnicode=true&characterEncoding=UTF8";//防止亂碼
要連接數據庫的用戶名—- String user="xxxx";
要連接數據庫的密碼—- String pass="xxxx";

接下來我們分析下url:
"jdbc(這是協議以jdbc開頭):mysql(這是子協議,數據庫管理系統稱)://localhost(數據庫來源地址):3306(目標端口)/test(要查詢的表的表名)?"
"useUnicode=true&characterEncoding=UTF8";添加這個是為瞭防止亂碼,指定使用Unicode字符集 ,且使用UTF-8來編輯。

            /*
                url包括哪幾部分:
                    協議
                    IP
                    Port
                    資源名

                eg:http://180.101.49.11:80/index.html
                    http:// 通信協議
                    180.101.49.11 IP地址
                    80 端口號
                    index.html 資源名
            */
 // 2、獲取連接
			/*
				url包括哪幾部分:
					協議
					IP
					Port
					資源名
				eg:http://180.101.49.11:80/index.html
					http:// 通信協議
					180.101.49.11 IP地址
					80 端口號
					index.html 資源名
			*/
            // static Connection getConnection(String url, String user, String password)
            String url = "jdbc:mysql://127.0.0.1:3306/hello";
            String user = "root";
            System.out.println(" ");
            String password = "rota";
            conn = DriverManager.getConnection(url,user,password);
            System.out.println("數據庫連接對象 :     " + conn);	//數據庫連接對象com.mysql.jdbc.JDBC4Connection@1ae369b7

3.獲取數據庫操作對象

            // 3、獲取數據庫操作對象
            // Statement 類中 createStatement() 創建一個 Statement 對象來將 SQL 語句發送到數據庫。
            stmt = conn.createStatement();
 
            // 4、執行sql語句
            // int executeUpdate(String sql)
            // 專門執行DML語句
            // 返回值是“影響數據庫中的記錄條數”
            int count = stmt.executeUpdate("update dept set dname = '銷售部',loc = '合肥' where deptno = 20;");
            System.out.println(count == 1 ? "保存成功":"保存失敗");

4.執行sql語句

            // 4、執行sql語句
            // int executeUpdate(String sql)
            // 專門執行DML語句
            // 返回值是“影響數據庫中的記錄條數”
            int count = stmt.executeUpdate("update dept set dname = '銷售部',loc = '合肥' where deptno = 20;");
            System.out.println(count == 1 ? "保存成功":"保存失敗");

5.處理查詢結果集

rs = stmt.executeQuery("select empno,ename,sal from emp");
 
            while(rs.next()){
				/*
				String empno = rs.getString(1);
				String ename = rs.getString(2);
				String sal = rs.getString(3);
				System.out.println(empno + "," + ename + "," + sal);
				*/
 
				/*
				// 按下標取出,程序不健壯
				String empno = rs.getString("empno");
				String ename = rs.getString("ename");
				String sal = rs.getString("sal");
				System.out.println(empno + "," + ename + "," + sal);
				*/
 
				/*
				// 以指定的格式取出
				int empno = rs.getInt(1);
				String ename = rs.getString(2);
				double sal = rs.getDouble(3);
				System.out.println(empno + "," + ename + "," + (sal + 100));
				*/
 
                int empno = rs.getInt("empno");
                String ename = rs.getString("ename");
                double sal = rs.getDouble("sal");
                System.out.println(empno + "," + ename + "," + (sal + 200));
            }

其中執行增刪改的方法返回值是int類型

執行查詢的方法返回值是操作結果集對象,即使ResultSet的實例化對象!

6.釋放資源

finally {
            // 6、釋放資源
            // 從小到大依次關閉
            //finally語句塊內的語句一定會執行!
            if(stmt != null) {
                try	{
                    stmt.close();
                }
                catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try	{
                    conn.close();
                }
                catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

上述六步連貫:

第一次優化:(比較兩種註冊驅動的方法)

 
 
 
import java.sql.*;
 
public class JDBCTest01 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;//先創建連接對象 和 操作對象 並且引用為空,是為瞭對象變量的生命周期不僅僅局限於try語句塊內,而是在整個main方法內,方便後續finally語句塊內釋放資源
        try{
            // 1、註冊驅動
            Driver driver = new com.mysql.jdbc.Driver();	//多態,父類型引用指向子類型對象
            DriverManager.registerDriver(driver);
 
            // 2、獲取連接
			/*
				url包括哪幾部分:
					協議
					IP
					Port
					資源名
				eg:http://180.101.49.11:80/index.html
					http:// 通信協議
					180.101.49.11 IP地址
					80 端口號
					index.html 資源名
			*/
            // static Connection getConnection(String url, String user, String password)
            String url = "jdbc:mysql://127.0.0.1:3306/hello";
            String user = "root";
            System.out.println(" ");
            String password = "rota";
            conn = DriverManager.getConnection(url,user,password);
            System.out.println("數據庫連接對象 :     " + conn);	//數據庫連接對象com.mysql.jdbc.JDBC4Connection@1ae369b7
 
            // 3、獲取數據庫操作對象
            // Statement 類中 createStatement() 創建一個 Statement 對象來將 SQL 語句發送到數據庫。
            stmt = conn.createStatement();
 
            // 4、執行sql語句
            // int executeUpdate(String sql)
            // 專門執行DML語句
            // 返回值是“影響數據庫中的記錄條數”
            int count = stmt.executeUpdate("update dept set dname = '銷售部',loc = '合肥' where deptno = 20;");
            System.out.println(count == 1 ? "保存成功":"保存失敗");
 
            // 5、處理查詢結果集
 
        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            // 6、釋放資源
            // 從小到大依次關閉
            //finally語句塊內的語句一定會執行!
            if(stmt != null) {
                try	{
                    stmt.close();
                }
                catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try	{
                    conn.close();
                }
                catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

第二次優化:(比較兩種註冊驅動的方法)

package com.zdx.source.code.jdbc;
 
/*
	JDBC完成Delete
*/
import java.sql.*;
 
public class JDBCTest02 {
    public static void main(String[] args) {
        // 1、註冊驅動
        // 2、獲取連接
        // 3、獲取數據庫操作對象
        // 4、執行sql語句
        // 5、獲取查詢結果集
        // 6、釋放資源
 
        Connection conn = null;
        Statement stmt = null;
        try {
            Driver driver = new com.mysql.jdbc.Driver();
            DriverManager.registerDriver(driver);
 
            String url = "jdbc:mysql://127.0.0.1:3306/mydatabase";
            String user = "root";
            String password = "146";
            conn = DriverManager.getConnection(url,user,password);
 
            stmt = conn.createStatement();
 
            int count = stmt.executeUpdate("delete from dept where deptno = 50");
 
            System.out.println(count == 1? "刪除成功":"刪除失敗");
 
        } catch(SQLException e){
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    conn.close();
                } catch(SQLException e){
                    e.printStackTrace();
                }
            }
            if(stmt != null) {
                try {
                    stmt.close();
                } catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

第三次優化:(最佳註冊驅動獲取連接)

package com.zdx.source.code.jdbc;
 
/*
	註冊驅動的另一種方式
*/
 
import java.sql.*;
 
public class JDBCTest03 {
    public static void main(String[] args) {
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
 
            // 獲取連接
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase","root","146");
            System.out.println(conn);
 
        } catch(SQLException e){
            e.printStackTrace();
        } catch(ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}

第四次優化:(使用資源綁定器)

package com.zdx.source.code.jdbc;
 
/*
	使用資源綁定器
*/
 
import java.sql.*;
import java.util.*;
 
public class JDBCTest04 {
    public static void main(String[] args) {
 
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        String driver = bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");
 
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName(driver);
 
            conn = DriverManager.getConnection(url,user,password);
 
            stmt = conn.createStatement();
 
            int count = stmt.executeUpdate("insert into dept(deptno,dname,loc) values(50,'人事部','北京');");
 
            System.out.println(count == 1? "保存成功":"保存失敗");
 
        } catch(SQLException e){
            e.printStackTrace();
        } catch(ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    conn.close();
                } catch(SQLException e){
                    e.printStackTrace();
                }
            }
            if(stmt != null) {
                try {
                    stmt.close();
                } catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

第五次優化:(對操作結果集的處理)

package com.zdx.source.code.jdbc;
 
/*
	執行DQL語句
*/
 
import java.sql.*;
import java.util.*;
 
public class JDBCTest05 {
    public static void main(String[] args) {
        // 1、註冊驅動
        // 2、建立連接
        // 3、獲取數據庫操作對象
        // 4、執行sql語句
        // 5、獲取查詢結果集
        // 6、釋放資源
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
 
        try{
            ResourceBundle rb = ResourceBundle.getBundle("jdbc");
            String driver = rb.getString("driver");
            String url = rb.getString("url");
            String user = rb.getString("user");
            String password = rb.getString("password");
 
            Class.forName(driver);
 
            conn = DriverManager.getConnection(url,user,password);
 
            stmt = conn.createStatement();
 
            rs = stmt.executeQuery("select empno,ename,sal from emp");
 
            while(rs.next()){
				/*
				String empno = rs.getString(1);
				String ename = rs.getString(2);
				String sal = rs.getString(3);
				System.out.println(empno + "," + ename + "," + sal);
				*/
 
				/*
				// 按下標取出,程序不健壯
				String empno = rs.getString("empno");
				String ename = rs.getString("ename");
				String sal = rs.getString("sal");
				System.out.println(empno + "," + ename + "," + sal);
				*/
 
				/*
				// 以指定的格式取出
				int empno = rs.getInt(1);
				String ename = rs.getString(2);
				double sal = rs.getDouble(3);
				System.out.println(empno + "," + ename + "," + (sal + 100));
				*/
 
                int empno = rs.getInt("empno");
                String ename = rs.getString("ename");
                double sal = rs.getDouble("sal");
                System.out.println(empno + "," + ename + "," + (sal + 200));
            }
 
        } catch(Exception e){
            e.printStackTrace();
        }finally{
            if(rs != null){
                try{
                    rs.close();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
            if(stmt != null){
                try{
                    stmt.close();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try{
                    conn.close();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

總結:

在上述五次優化代碼的過程中,針對這六步

        // 1、註冊驅動
        // 2、獲取連接
        // 3、獲取數據庫操作對象
        // 4、執行sql語句
        // 5、獲取查詢結果集
        // 6、釋放資源

第一步的註冊驅動最終使用瞭反射,已達最優

第二步的獲取連接已達最優,已經有能力去完成JDBC連接數據庫的工具類的封裝瞭

看到這裡可以移步去學習—————>工具類的封裝啦!

註:

第三步的獲取數據庫操作對象中我們是使用Statement接口

public interface Statement extends Wrapper, AutoCloseable 

還可以優化成為PreparedStatement

public interface PreparedStatement extends Statement

在實際開發過程中由於PreparedStatement能防止註入,且預先編譯SQL語句的特性使得程序健壯性提高,所以實際開發中99.9%使用PreparedStatement。這是後話,由於封裝工具類主要封裝的是註冊驅動,獲取連接和釋放資源,後續將專門寫一篇博客討論PreparedStatement

此外在實際開發中除瞭掌握上述六步還需要掌握事務提交回滾三部曲。

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: