JDBC 入門

1. JDBC 簡介

  • JDBC (Java DataBase Connectivity) 就是 Java 數據庫鏈接, 說白了就是用 Java 語言向
    數據庫發送 SQL 語句.
  • JDBC 實際上是訪問數據庫的規範(就是一組接口). 而驅動就是該接口的實現類.

2. java 代碼操做數據庫步驟:

- 導 jar 包: 驅動!! mysql 對應的是 `mysql-connector-java`
- 加載驅動類: `Class.forName('類名');`
- 給出 url, username, password;
- 使用 DriverManager 類獲得 Connection 對象.
- 須要聲明兩個異常: `ClassNotFoundException` 和 `SQLException`.
public class Demo{

    /*
     * 鏈接數據庫, 獲得 Connection 對象
     * 對數據庫進行增, 刪, 改
     *
     */

     public void fun() throws ClassNotFoundException, SQLException{
            // 加載驅動類(註冊驅動)
            Class.forName("com.mysql.jdbc.Driver");
                /*
                 * 與下面代碼等同
                 *    com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
                 *    DriverManager.registerDriver(driver);
                 *
                 *  每種數據庫的驅動都須要實現 java.sql.Driver 接口.
                 *  Class.forName 用來加載一個類,在加載類的過程當中, 會執行該類的靜態代碼塊.
                 *  全部的 java.sql.Driver 實現類, 都提供了靜態代碼塊, 塊內的代碼就是把
                 *  本身註冊到 DriverManager 中.
                 *
                 *  jdbc 4.0 以後, 每一個驅動 jar 包中, 在 META-INF/services 目錄下提供了
                 *  一個名爲 java.sql.Driver 的文件, 文件的內容就是 java.sql.Driver 的實現類名稱.
                 *  
                 */

             // jdbc 協議的格式, jdbc:廠商的名稱:子協議(由廠商本身來規定)
             // 對 MySql 而言, 它的子協議結構: //主機:端口號/數據庫名稱
             String url = "jdbc:mysql://localhost:3306/mydb1";

             // 數據庫用戶名和密碼
             String username = "root";
             String password = "root";

             // 使用 DriverManager, 獲得 Connection. 須要導入 java.sql.Connection 包
             Connection con = DriverManager.getConnection(url,username,password);

        /*
        *  對數據庫作增, 刪, 改
        *     1. 經過 Connection 對象獲得 Statement 對象, 它的功能是向數據庫發送 sql 語句.
        *     2. 調用它的 int executeUpdate(String sql), 發送 DML, DDL 語句.
        */
             // java.sql.Statement 包
              Statement stmt = con.createStatement();

              // 向數據庫中添加數據
              String sql = "INSERT INTO stu VALUES(1113,'zhangsan',24,'male')";

              // 返回值爲 int 類型, 表示 sql 語句所影響的行數
              int r = stmt.executeUpdate(sql);

        /*
         * 執行查詢
         *    1. 獲得 Connection 對象
         *    2. 獲得 Statement 對象,發送 select 語句
         *       調用 Statement 對象的 ResultSet rs = stmt.executeQuery(String querySql);
         *    3. 對查詢返回的"表格"進行解析!
         *       返回的"表格" rs, 有兩個虛擬的位置: beforeFirst, afterLast
         *       rs 的內部有一個行光標, 默認位置爲 beforeFirst.
         *       ResultSet 的 next() 方法能夠把光標向下移動一行.
         *       next() 返回 boolean 類型的值, 表示當前行是否存在.
         *       ResultSet 提供了一系列的 getXxxx() 方法, 獲取某一列中的數據.
         *                 其中, getString() 和 getObject() 兩個方法較爲經常使用.
         *         JavaSE  java.sql.ResultSet 包
         */

             // 查詢 t_stu 表格
             String sql2 = "SELECT * FROM t_stu";
             ResultSet rs = stmt.executeQuery(sql2);

             // 解析"表格"
             while(rs.next()){
                String name = rs.getString("sname");
                int age = rs.getInt("age");
                String gender = rs.getString("gender");

                System.out.println(name+','+age+','+gender);
            }
            
            /*
             * 若是不知道列的內容, 還可使用下面的方法獲取
             *
             *  獲取列數
             * int count = rs.getMetaData().getColumnCount();
             * while(rs.next()){
             *      for(int i=1; i<=count; i++){
             *            獲取列中的數據
             *            System.out.print(rs.getObject(i));
             *            若是不是一行結尾, 則在每一個列後面加逗號
             *            if(i<count){
             *                System.out.print(", ");
             *            }
             *        }  
             *       每一行以後, 換行
             *       System.out.println();
             * }
             */

        // 關閉資源
        // 倒關: 先獲得的對象後關閉, 後獲得的對象先關閉.
        rs.close();
        stmt.close();
        con.close(); // 這個東西必須關閉!!
   }
}

3. JDBC 之代碼規範化

  1. 所謂規範化代碼就是不管是否出現異常, 都要關閉 ResultSet, Statement 以及 Connection.
public void query(){
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;

    try{
        con = DriverManager.getConnection();
        stmt = con.createStatement();

        String sql = "SELECT * FROM user";
        rs = stmt.executeQuery(sql);

        while(rs.next()){
            String username = rs.getString(1); // 獲取第一列的值, 參數爲列編號或列名
            String password = rs.getString(2); // 獲取第二列的值
            System.out.println(username+","+password);
        }
    } catch(Exception e){
        throw new RuntimeException(e);
    } finally{
        try{
            if(rs != null) rs.close();
            if(stmt != null) stmt.close();
            if(con != null) con.close();
        } catch(SQLException e){
            throw new RuntimeException(e);
        }
    }
}

4. JDBC 對象介紹

  • JavaSE 文檔中 java.sql 目錄下

1. DriverManagerjava

2. Connection 對象mysql

  • 主要用來獲取 Statement 對象: Statement stmt = con.createStatement();

3. Statement 對象sql

  • int executeUpdate(String sql); 執行更新操做, 即執行 insert, update, delete 語句.
    返回 int 類型, 表示 SQL 操做影響的行數.
  • ResultSet executeQuery(String sql); 執行查詢操做, 返回 ResultSet.
  • boolean execute(); 能夠用來執行增, 刪, 改, 查全部 SQL 語句. 返回的是 boolean 類型,
    表示 SQL 語句是否有結果集.

4. ResultSet 之滾動結果集數據庫

  • ResultSet 表示結果集, 它是一個二維的表格! ResultSet 內部維護一個行光標, Result 提供了一系列的
    方法來移動光標.
  • 其餘數據庫默認的結果集不可滾動,不敏感, 不可更新!! 只能使用 next() 方法來移動光標.
    MySql 得到的默認結果集是可滾動.
  • ResultSet 提供了一系列的 getXxx() 方法, 來獲取某一列中的數據.
    其中, getString() 和 getObject() 兩個方法較爲經常使用, 參數爲列編號或列名.
  • 當使用 Connection 的 createStatement 時, 已經肯定了 Statement 生成的結果集是什麼特性!
  • 結果集特性: 是否可滾動, 是否敏感, 是否可更新!

5. 獲取列相關的內容服務器

  • 獲取結果即元數據: rs.getMetaData(); 返回值爲 ResultSetMetaData();
  • 獲取結果集列數: int getColumnCount();
  • 獲取指定列的列名: String getColumnName(int colIndex);

5. PreparedStatement 接口

1. 它是 Statement 接口的子接口.
2. 它的強大之處:
  • 防 SQL 攻擊
  • 提升代碼的可讀性, 可維護性
  • 提升效率
3. 使用步驟:
  • 給出 SQL 模板!! 即 SQL 語句中全部的參數使用問號來替代!
  • 調用 Connection 的 PreparedStatement prepareStatement(String sql模板);
  • 調用 pstmt 的 setXxx() 系列方法, 爲 SQL 模板中的 "?" 賦值.
  • 調用 pstmt 的 executeUpdate() 或 executeQuery(), 注意, 這兩個方法都不須要參數.
// 示例:查詢表中的姓名爲張三, 年齡爲24 的詳細信息

    // 給出 SQL 模板
    String sql = "SELECT * FROM t_user WHERE username=? AND age=?";

    // 獲取 PreparedStatement 對象, 注意 con.prepareStatement, 爲 prepare
    PreparedStatement pstmt = con.prepareStatement(sql);

    // 爲參數賦值
    pstmt.setString(1,"張三"); // 給第一個問號賦值, 值爲 "張三"
    pstmt.setInt(2,24); // 給第二個問號賦值, 值爲 24, 不須要使用引號.

    // 向數據庫發送查詢語句
    ResultSet rs = pstmt.executeQuery();
4. 預處理的原理
1. 服務器執行 sql 語句,須要執行的工做:
  • 校驗 sql 語句的語法!
  • 編譯: 將 sql 語句變成一個與函數類似的東西.
  • 執行: 至關於調用函數.
2. PreparedStatement
  • 使用該接口的前提: 鏈接的數據庫必須支持預處理! 幾乎沒有不支持的.
  • 每一個 pstmt 都與一個 sql 模板綁定在一塊兒, 先把 sql 模板給數據庫, 數據庫進行校驗.
    再進行編譯, 執行時,只是把參數傳遞過去而已!
  • 若二次執行時,就不用再次校驗語法, 也不用再次編譯! 直接執行!

6. MySql 的預處理

  • MySql 的預處理功能默認是關閉的,須要本身手動打開.


參考資料:ide

相關文章
相關標籤/搜索