Java與資料庫 —— JDBC標準

104828720發表於2019-01-19

JDBC由來與描述

  • 沒有JDBC前
開發者想運算元據庫,必須需要了解每個資料庫對應的資料庫驅動程式API,由於每個資料庫驅動程式的API都不同,所以當需要遷移資料庫時,根本不平滑,需要大量修改與重寫
  • 有了JDBC後
Sum公司也知道問題之後,就提出一種約束 —— JDBC規範,讓所有資料庫廠商都按照這個JDBC規範來開發資料庫驅動程式,以便於Java程式能用統一方式操作不同的資料庫,資料庫遷移變成可行
  • JDBC描述
JDBC是一種Java web的規範,需要具體開發者(資料庫廠商)來實現

JDBC常用四大API

  • DriverManager
作用:
1、註冊驅動
Class.forName("com.jdbc.mysql.Driver");

2、獲取連線
Connection conn = DriverManager.getConnection();
  • Connection
作用:
1、建立執行SQL語句的物件(3種)
Statement createStatement()    // 執行SQL語句
PreparedStatement prepareStatement()   // 預編譯SQL並執行
CallableStatement prepareCall()    // 執行SQL儲存過程

2、進行事務管理
setAutoCommit(boolean b)
commit()
rollback()
  • Statement
作用:
1、執行SQL語句
boolean execute(String sql)   // 執行SQL語句,執行select就返回true,否則返回false
ResultSet executeQuery(String sql)     // 執行SQL中的select語句
int executeUpdate(String sql)          // 執行SQL中的insert/update/delete語句

2、執行批量SQL語句
addBatch(String sql)    // 新增到批量處理
executeBatch()          // 執行批量處理
clearBatch()            // 清空批量處理
  • ResultSet
(select語句)查詢結果的集合
作用:獲取到查詢的結果
next()           //判斷是否有下一條資料
getXXX()         //根據資料型別獲取查詢記錄的資料
getObject()      //通用獲取資料方法

JDBC資源釋放

釋放原則:晚建立,早釋放;資源稀有,不釋放很快會阻塞

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from user");

rs.close();
stmt.close();
conn.close();

JDBC CURD操作

  • 增加
Connection conn = null;
Statement stmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 獲取執行SQL語句物件
    stmt = conn.createStatement();
    // 編寫SQL
    String sql = "insert into user values ("xiaomin","女人",12)";
    // 執行SQL語句
    int i = stmt.executeUpdate(sql);
    if(i > 0){
        System.out.println("插入成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(stmt != null){
        try{
            stmt .close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            stmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 更新
Connection conn = null;
Statement stmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 獲取執行SQL語句物件
    stmt = conn.createStatement();
    // 編寫SQL
    String sql = "update user set name = `wt`";
    // 執行SQL語句
    int i = stmt.executeUpdate(sql);
    if(i > 0){
        System.out.println("更新成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(stmt != null){
        try{
            stmt .close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            stmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 刪除
Connection conn = null;
Statement stmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 獲取執行SQL語句物件
    stmt = conn.createStatement();
    // 編寫SQL
    String sql = "delete from user where id = 3";
    // 執行SQL語句
    int i = stmt.executeUpdate(sql);
    if(i > 0){
        System.out.println("刪除成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(stmt != null){
        try{
            stmt .close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            stmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 查詢
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 獲取執行SQL語句物件
    stmt = conn.createStatement();
    // 編寫SQL
    String sql = "select * from user";
    // 執行SQL語句
    rs = stmt.executeQuery(sql);
    if(rs.next()){
        System.out.print(rs.getString("name"));
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(rs != null){
        try{
            rs .close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            rs = null;
        }
    }
    if(stmt != null){
        try{
            stmt .close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            stmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}

JDBC SQL隱碼攻擊解決方案

開發時,使用 PreparedStatement物件 取代 Statement物件 來執行SQL有效避免SQL隱碼攻擊

  • 增加
Connection conn = null;
PreparedStatement pstmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 編寫SQL
    String sql = "insert into user values (?,?,?)";
    // 獲取執行SQL語句物件
    pstmt = conn.preparedStatement(sql);
    // 設定引數
    pstmt.setString(1, "qqq");
    pstmt.setString(2, "bbb");
    pstmt.setString(3, "ccc");
    // 執行SQL語句
    int i = pstmt.executeUpdate();
    if(i > 0){
        System.out.println("插入成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(pstmt != null){
        try{
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            pstmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 更新
Connection conn = null;
PreparedStatement pstmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 編寫SQL
    String sql = "update user set name = ?, age = ?, pwd = ? where id = ?";
    // 獲取執行SQL語句物件
    pstmt = conn.preparedStatement(sql);
    // 設定引數
    pstmt.setString(1, "wt");
    pstmt.setString(2, 15);
    pstmt.setString(3, "basdcx");
    pstmt.setString(4, 10);
    // 執行SQL語句
    int i = pstmt.executeUpdate();
    if(i > 0){
        System.out.println("更新成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(pstmt != null){
        try{
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            pstmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 刪除
Connection conn = null;
PreparedStatement pstmt = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 編寫SQL
    String sql = "delete from user where id = ?";
    // 獲取執行SQL語句物件
    pstmt = conn.preparedStatement(sql);
    // 設定引數
    pstmt.setString(1, 16);
    // 執行SQL語句
    int i = pstmt.executeUpdate();
    if(i > 0){
        System.out.println("刪除成功!");
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    if(pstmt != null){
        try{
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            pstmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}
  • 查詢
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

try{
    // 註冊驅動
    Class.forName("com.mysql.jdbc.Driver");
    // 獲得連線
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
    // 編寫SQL
    String sql = "select * from user where sex = ?";
    // 獲取執行SQL語句物件
    pstmt = conn.preparedStatement(sql);
    // 設定引數
    pstmt.setString(1, `男`);
    // 執行SQL語句
    rs = pstmt.executeQuery();
    while(rs.next()){
        System.out.println(rs.getString("name"));
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
     if(rs != null){
        try{
            rs.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            rs = null;
        }
    }
    if(pstmt != null){
        try{
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            pstmt = null;
        }
    }
    if(conn != null){
        try{
            conn.close();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}

連線池(資料來源)JDBC優化技術

資料庫連線頻繁建立與消耗,在資源使用上是一種浪費

  • 常用連線池
C3P0、HikariCP、Druid、Tomcat、Dbcp
  • 用法(以C3P0為例)
ComboPooledDataSource dataSource = new ComboPooledDataSource();   // 只需一個物件
// 獲取連線
Connection conn = dataSource.getConnection();

相關文章