Java學習日誌(三十二): 原生JDBC,使用Java程序操作數據庫

JavaEE學習日誌持續更新----> 必看!JavaEE學習路線(文章總彙)

JDBC

JDBC的概念和原理

在這裏插入圖片描述

JDBC使用步驟

JDBC:使用java程序執行sql語句,對數據庫表進行增刪改查(CURD)
使用步驟:固定

  1. 註冊驅動,告之JVM我們使用的是哪種數據庫驅動程序(mysql,oracle…)

  2. 獲取數據庫連接對象Connection

       java程序:TCP客戶端  數據庫:TCP服務器
       使用客戶端訪問服務器,和服務器經過3次握手建立一個連接通路
       這個連接通路中有一個IO流對象,用於客戶端和服務器交互數據
    
  3. 獲取執行者對象Statement,用於執行sql語句,把sql語句發送到數據庫中執行

  4. 執行sql語句,獲取結果集
    - 增刪改:int affected(受影響的) 影響數據庫的有效行數
    - 查詢:ResultSet結果集,把查詢的多行結果存儲到一個結果集中

  5. 處理結果集
    - 增刪改:不用處理
    - 查詢:遍歷結果集

  6. 釋放資源

注意:1,2,3,6固定不變,4,5根據增刪改查不同而不同

第一步:註冊驅動

使用java.sql.DriverManager類中的方法實現:管理一組JDBC驅動程序的基本服務。
靜態方法
static void registerDriver​(Driver driver) 使用 DriverManager註冊給定的驅動程序。

參數:
  java.sql.Driver:是一個接口,每個驅動程序類必須實現的接口。
  傳遞Driver接口的實現類對象,由mysql驅動提供
  com.mysql.jdbc.Driver
public class Demo01JDBC {
    public static void main(String[] args) throws SQLException {       
     	DriverManager.registerDriver(new Driver());
    }
}

查看com.mysql.jdbc.Driver的源碼發現,有一個靜態代碼塊,已經註冊了驅動,我們再註冊一個驅動,就註冊了兩次,會產生浪費

static {
            try {
                DriverManager.registerDriver(new Driver());
            } catch (SQLException var1) {
                throw new RuntimeException("Can't register driver!");
            }
        }

解決方案:使用反射技術,獲取class文件,會執行類中的靜態代碼塊
格式:Class.forName("foo.bah.Driver")

public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    }
}

第二步:獲取數據庫連接對象Connection

使用java.sql.DriverManager類中的方法實現
靜態方法:
static Connection getConnection​(String url, String user, String password) 嘗試建立與給定數據庫URL的連接。

參數:
     String url:數據庫服務器的地址,固定格式
         - jdbc:mysql://ip:端口號/數據庫名稱
         - jdbc:mysql://localhost:3306/day03
     String user:數據庫用戶名
     String password:數據庫密碼
返回值:
     java.sql.Connection是一個接口,返回的是Connection接口的實現類對象
     由mysql驅動提供,我們可以使用Connection接口來接收這個實現類對象(多態)
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
    }
}

第三步:獲取執行者對象Statement

使用Connection接口中提供的方法實現:
Statement createStatement() 創建一個 Statement對象,用於將SQL語句發送到數據庫。

返回值:
     java.sql.Statement是一個接口,返回的是Statement接口的實現類對象
     由mysql驅動提供,我們可以使用Statement接口來接收這個實現類對象(多態)
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
    }
}

第四步:執行sql語句,獲取結果集

使用Statement接口中的方法實現:

  • int executeUpdate​(String sql) 執行給定的SQL語句,這可能是 INSERT , UPDATE ,或 DELETE語句,或者不返回任何內容,如SQL DDL語句的SQL語句。
  • ResultSet executeQuery​(String sql) 執行給定的SQL語句,該語句可能爲SELECT
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
        int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id) "+
                "VALUES('p012','鍵盤',500,'1','c001');");
    }
}

完整代碼

public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
        int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id) "+
                "VALUES('p012','鍵盤',500,'1','c001');");
        //5.處理結果集
        System.out.println(row);//1
        //6.釋放資源
        stat.close();
        conn.close();
    }
}

創建JDBCUtils工具類並測試

創建JDBC工具類,工具類中的方法都是靜態方法,方便直接通過類名使用

  • 定義一個靜態方法,獲取Collection對象並返回
  • 定義一個靜態方法,釋放資源

代碼示例:JDBCUtils工具類創建

import java.sql.*;

public class JDBCUtils {
    //定義4個靜態的成員變量,用於存儲數據庫連接的相關信息
    //註冊驅動的地址
    private static String driver = "com.mysql.jdbc.Driver";
    //數據庫的url地址
    private static String url = "jdbc:mysql://localhost:3306/day03";
    //數據庫用戶名
    private static String user = "root";
    //數據庫的密碼
    private static String password = "root";

    //靜態代碼塊:優先執行,只執行一次
    static {
        //註冊驅動
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //定義一個靜態方法,獲取Collection對象並返回
    public static Connection getConnection(){
        Connection conn = null;
        try {
            //獲取Connection對象並返回
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            /*
                如果獲取數據庫連接對象失敗,那麼程序就沒有必要繼續執行了
                所以可以把編譯異常轉換爲運行時異常,讓程序停止下來
             */
            throw new RuntimeException("獲取數據庫連接對象失敗"+e);
        }
        return conn;
    }
    //定義一個靜態方法,釋放資源
    public static void close(ResultSet rs, Statement stat, Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat!=null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

測試類

/*
 測試JDBCUtils工具類
 */
public class Demo02testJDBCUtils {
    public static void main(String[] args) {
        //使用JDBCUtil工具類中的方法getConnection獲取數據庫連接對象
        Connection conn = JDBCUtils.getConnection();
        System.out.println(conn);//com.mysql.jdbc.JDBC4Connection@256216b3
    }
}

使用JDBC技術對數據庫進行操作

增刪改

@Test
    public void testInsert() {
        //使用JDBCUtils工具類中的方法getConnection獲取數據庫連接對象
        Connection conn = JDBCUtils.getConnection();
        //獲取執行者對象
        Statement stat = null;
        try {
            stat = conn.createStatement();
            //執行sql語句,獲取結果
            //增加數據
            int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id)"+
                    " VALUES('p014','鼠標',500,'1','c001'),('p015','鼠標',500,'1','c001');");
            //修改數據
            //int row = stat.executeUpdate("UPDATE products SET price = 7999 WHERE pid = 'p013';");
            //刪除數據
            //int row = stat.executeUpdate("DELETE from products where pid in('p001','p002','p003');");
            //處理結果
            System.out.println(row+"行數據添加成功!");


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //釋放資源
            JDBCUtils.close(null,stat,conn);
        }
    }

查詢

執行sql語句,獲取結果集
ResultSet executeQuery​(String sql) 執行給定的SQL語句,該語句可能爲SELECT

返回值:
   java.sql.ResultSet是一個接口,返回的是ResultSet接口的實現類對象。
   由mysql驅動提供,我們可以使用ResultSet接口來接收這個實現類對象(多態)

處理結果集,遍歷結果集:和迭代器的使用方式一模一樣

  • ResultSet中有一個方法叫next判斷有沒有下一行數據;有返回true,沒用返回false
    boolean next() 將光標從當前位置向前移動一行。
  • ResultSet中有一個方法叫getXXX(列的索引/列名)取出結果
    int getInt​(int columnIndex)列的索引,從1開始
    int getInt​(String columnLabel)列名
    注意:數據庫的列是什麼類型,就用get類型的方法獲取這個字段
    也可以使用getObject來獲取所有類型的字段,返回值是Object類型

代碼示例:

@Test
    public void testSelect() throws SQLException {
        //使用JDBCUtils工具類中的方法getConnection獲取數據庫連接對象
        Connection conn = JDBCUtils.getConnection();
        //獲取執行者對象
        Statement stat = conn.createStatement();
        /*
            執行sql語句,獲取結果集
            ResultSet executeQuery​(String sql) 執行給定的SQL語句,該語句可能爲SELECT
            返回值:
                java.sql.ResultSet是一個接口,返回的是ResultSet接口的實現類對象
                由mysql驅動提供,我們可以使用ResultSet接口來接收這個實現類對象(多態)
         */
        ResultSet rs = stat.executeQuery("select * from products;");
        //System.out.println(rs);//com.mysql.jdbc.JDBC42ResultSet@3224f60b
        /*
            處理結果集,遍歷結果集
            和迭代器的使用方式一模一樣
            ResultSet中有一個方法叫next判斷有沒有下一行數據;有返回true,沒用返回false
                boolean next() 將光標從當前位置向前移動一行。
            ResultSet中有一個方法叫getXXX(列的索引/列名)取出結果
                int getInt​(int columnIndex):列的索引,從1開始
                int getInt​(String columnLabel):列名
                注意:數據庫的列是什麼類型,就用get類型的方法獲取這個字段
                也可以使用getObject來獲取所有類型的字段,返回值是Object類型
         */
        while(rs.next()){
            /*String pid = rs.getString(1);
            String pname = rs.getString(2);
            int price = rs.getInt(3);
            String flag = rs.getString(4);
            String category_cid = rs.getString(5);*/
            String pid = rs.getString("pid");
            String pname = rs.getString("pname");
            int price = rs.getInt("price");
            String flag = rs.getString("flag");
            String category_cid = rs.getString("category_id");
            System.out.println(pid+"\t"+pname+"\t"+price+"\t"+flag+"\t"+category_cid);
        }
        //釋放資源
        JDBCUtils.close(rs,stat,conn);

    }

執行結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章