JDBC學習筆記代碼

JDBC

什麼是JDBC

JDBC(Java DataBase Connectivity, Java數據庫連接) ,是一種用於執行SQL語句的Java API,爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成

連接數據庫

mysql8 之前連接

數據庫驅動名:com.mysql.jdbc.Driver

url連接jdbc:mysql://127.0.0.1:3306/mydb

public class test{
    public static void main(String[] args){
    	Class.forName("com.mysql.jdbc.Driver");
        String url="jdbc:mysql://127.0.0.1:3306/mydb";
        String user="root";
        String password="root";
        Connection conn = DriverManager.getConnection(url,user,password);
        
	}
}

mysql8之後連接

數據庫驅動名:com.mysql.cj.jdbc.Driver

url連接:jdbc:mysql://127.0.0.1:3306/mydbseSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai

public class test{
    public static void main(String[] args){
         * url 同一資源定位符
            *   協議          jdbc:mysql:
            *   ip地址        127.0.0.1/localhost
            *   端口號        3306
            *   具體的資源路徑 mydb
            *   useSSL=false             不使用SSL加密機制
            *   &useUnicode=true         使用unicode字符集
            *   &characterEncoding=utf8  使用utf8作爲通信字符集
            *   &serverTimezone=Asia/Shanghai  確定時區爲 Asia/Shanghai
            * 	user     賬號 root
            *	password 密碼 root
            * */
 		Class.forName("com.mysql.cj.jdbc.Driver");
         String url = "jdbc:mysql://127.0.0.1:3306/mydb?seSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
         String user = "root";
         String pwd = "root";
        Connection conn = DriverManager.getConnection(url,user,password);   
	}
}

常見異常

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver2

未添加jar包 或者 路徑錯誤

SQLException: No suitable driver found for jdbcs

協議錯誤

CommunicationsException: Communications link failure

通信失敗

SQLException: Access denied for user ‘root’@‘localhost’ (using password: YES)

拒絕訪問 密碼錯誤

SQLNonTransientConnectionException: Public Key Retrieval is not allowed

不允許檢索公鑰 用戶名錯誤

SQLIntegrityConstraintViolationException: Duplicate entry ‘50’ for key ‘PRIMARY’

主鍵重複輸入

executeQuert() 和 executeUpdate() 區別

執行查詢命令 : executeQuert()

執行增刪改命令 :executeUpdate()

ResultSet(結果解)接口

​ ResultSet對象 接收executeQuert() 的返回值

JDBC Statement 接口

用於發送SQL語句到數據庫中,或理解爲執行sql命令

添加數據(insert)

public class TestInsert {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加載驅動
        Class.forName("com.mysql.cj.jdbc.Driver2");
        //2.創建數據庫連接
        String url = "jdbc:mysql://127.0.0.1:3306/mydb?		useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        Connection conn = DriverManager.getConnection(url, user, pwd);
        //3.創建SQL命令發送器
        Statement st = conn.createStatement();
        String sql = "insert into dept values(50,'中部','北京')";
        //4.通過Statement發送SQL命令並得到結果
        int rows = st.executeUpdate(sql);
        System.out.println("執行完畢,對數據中" + rows + "行數據產生了影響");
        //5.關閉資源
        st.close();
        conn.close();
    }
}

修改數據(update)

public class TestUpdate {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加載驅動
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.創建數據庫連接
        String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        Connection conn = DriverManager.getConnection(url, user, pwd);
        //3.創建SQL命令發送器
        Statement st = conn.createStatement();
        String sql = "update  dept set dname='銷售部'where deptno=50 ";
        //4.通過Statement發送SQL命令並得到結果
        int rows = st.executeUpdate(sql);
        System.out.println("執行完畢,對數據中" + rows + "行數據產生了影響");
        //5.關閉資源
        st.close();
        conn.close();
    }
}

刪除數據(delete)

public class TestDelete {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加載驅動
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.創建數據庫連接
        String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        Connection conn = DriverManager.getConnection(url, user, pwd);
        //3.創建SQL命令發送器
        Statement st = conn.createStatement();
        String sql = "delete from dept where deptno=50";
        //4.通過Statement發送SQL命令並得到結果
        int rows = st.executeUpdate(sql);
        System.out.println("執行完畢,對數據中" + rows + "行數據產生了影響");
        //5.關閉資源
        st.close();
        conn.close();
    }
}

查詢數據(select)

public class TestExecuteQuery {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
      
        String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        //加載驅動
        Class.forName("com.mysql.cj.jdbc.Driver");
        //建立練級
        Connection conn = DriverManager.getConnection(url, user, pwd);
        //創建sql命令發送器
        Statement st = conn.createStatement();
        String sql = "select * from emp";
        //發送sql命令 並返回數據
        ResultSet rs = st.executeQuery(sql);
    	//ResultSet 使用方式2
        while (rs.next()) {
            //獲取行數據
            int enmno = rs.getInt(1);
            String eName=rs.getString(2);
            String job=rs.getString(3);
            int mgr = rs.getInt(4);
            Date hireDate= rs.getDate(5);
            double sal=  rs.getDouble(6);
            double comm=  rs.getDouble(7);
            int deptNo =rs.getInt(8);
            StringBuilder str = new StringBuilder();
            str.append(enmno+"  ").append(eName+"  ").append(job+"  ").append(mgr+"  ").append(hireDate+"  ").append(sal+"  ").append(comm+"  ").append(deptNo+"  ");
            System.out.println(str.toString());
        }
        rs.close();
        st.close();
        conn.close();
         //ResultSet 使用方式2
        /*while (rs.next()) {
            int enmno = rs.getInt("EMPNO");
            String eName=rs.getString("ENAME");
            String job=rs.getString("JOB");
            int mgr = rs.getInt("MGR");
            Date hireDate= rs.getDate("HIREDATE");
            double sal=  rs.getDouble("SAL");
            double comm=  rs.getDouble("COMM");
            int deptNo =rs.getInt("DEPTNO");
            StringBuilder str = new StringBuilder();
            str.append(enmno+"  ").append(eName+"  ").append(job+"  ").append(mgr+"  ").append(hireDate+"  ").append(sal+"  ").append(comm+"  ").append(deptNo+"  ");
            System.out.println(str.toString());
        }
*/
    }
}

將數據庫中的數據多條存入實體類中 並遍歷數據

public class TestExecuteQuery2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        List<Emp> list = getAllEmp();
        showEmp(list);
    }
    public static List<Emp> getAllEmp() {
        String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        String user = "root";
        String pwd = "root";
        ResultSet rs = null;
        Connection conn = null;
        Statement st = null;
        List<Emp> list = new ArrayList<>();
        try {
            //加載驅動
            Class.forName("com.mysql.cj.jdbc.Driver");
            //建立連接
            conn = DriverManager.getConnection(url, user, pwd);
            //創建sql命令發送器
            st = conn.createStatement();
            String sql = "select * from emp";
            //發送sql命令 本返回數據
            rs = st.executeQuery(sql);
            while (rs.next()) {
                //獲取行數據
                int enmno = rs.getInt("EMPNO");
                String eName = rs.getString("ENAME");
                String job = rs.getString("JOB");
                int mgr = rs.getInt("MGR");
                Date hireDate = rs.getDate("HIREDATE");
                double sal = rs.getDouble("SAL");
                double comm = rs.getDouble("COMM");
                int deptNo = rs.getInt("DEPTNO");
                Emp emp = new Emp(enmno,eName,job,mgr,hireDate,sal,comm,deptNo);
                list.add(emp);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //關閉資源
            if (null != rs) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != st) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != conn) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }
    /**
     * 遍歷集合
     * */
    public static void showEmp(List<Emp> list){
        for(Emp e:list){
            System.out.println(e);
        }
    }

}

sql注入風險

​ SQL語句中拼接的內容破壞了 SQL語句原有的判斷邏輯

select * from user where username='lisi' and password='ll' or '1'='1'

​ 使用Statement

public static User login(String username,String password) {
         User users = null;
         Connection conn=null;
         int n=0;
         try {
             Class.forName("com.mysql.cj.jdbc.Driver");
             String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
             String user = "root";
             String pwd = "root";
             conn = DriverManager.getConnection(url, user, pwd);

             Statement st = conn.createStatement();
             String sql = "select * from user where username='"+username+"' and password='"+password+"'";
             System.out.println(sql);
             ResultSet rs =  st.executeQuery(sql);
             if(rs.next()){
                 int id = rs.getInt("id");
                 String userName= rs.getString("username");
                 String pwd2 =rs.getString("password");
                 users= new User(id,userName,pwd2);
             }

         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             e.printStackTrace();
         } finally {
             if (null != conn){
                 try {
                     conn.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
         return users;
     }
sql注入風險解決方式:使用PreparedStatement
public static User login2(String username,String password) {
        User users = null;
        Connection conn=null;
        int n=0;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
            String user = "root";
            String pwd = "root";
            conn = DriverManager.getConnection(url, user, pwd);

            String sql = "select * from user where username='"+username+"' and password='"+password+"'";

            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs =  ps.executeQuery();
            if(rs.next()){
                int id = rs.getInt("id");
                String userName= rs.getString("username");
                String pwd2 =rs.getString("password");
                users= new User(id,userName,pwd2);
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (null != conn){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return users;
    }

JDBC PreparedStatement 接口

Statement 和 PreparedStatement 區別和聯繫

​ 聯繫 :PreparedStatement extends Statement

​ 區別:1.PreparedStatment安全性高,可以避免SQL注入

​ 2.PreparedStatment簡單不繁瑣,不用進行字符串拼接

​ 3.PreparedStatment性能高,用在執行多個相同數據庫DML操作時

添加數據(insert)

public class TestPreparedStatement {
  public static final String DRIVER = "com.mysql.cj.jdbc.Driver";
  private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb?	    useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
  private static final String USER = "root";
  private static final String PWD = "root";
  public static void main(String[] args)throws Exception {
      insert(66,"asdfaf","jiadjfa");
  }
  /**
    * 功能描述:添加
    * @param:
    * @return:
    */
   public static void insert(int deptno,String dname,String loc)  throws Exception{
       Class.forName(DRIVER);
       Connection conn = DriverManager.getConnection(URL, USER, PWD);
       String sql = "insert into dept values(?,?,?) ";
       PreparedStatement ps = conn.prepareStatement(sql);
       ps.setInt(1,deptno);
       ps.setString(2,dname);
       ps.setString(3,loc);
       int n = ps.executeUpdate();
       ps.close();
       conn.close();
    }  
}

修改數據(update)

public class TestPreparedStatement {
  public static final String DRIVER = "com.mysql.cj.jdbc.Driver";
  private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb?	    useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
  private static final String USER = "root";
  private static final String PWD = "root";
  public static void main(String[] args)throws Exception {
      insert(66,"asdfaf","jiadjfa");
  }
   /**
     * 功能描述:修改
     * @param:
     * @return:
     */
  public static void update(int deptno,String dname)  throws Exception{
      Class.forName(DRIVER);
      Connection conn = DriverManager.getConnection(URL, USER, PWD);
      String sql = "update dept set dname=? where deptno=? ";
      PreparedStatement ps = conn.prepareStatement(sql);
      ps.setString(1,dname);
      ps.setInt(2,deptno);
      int n = ps.executeUpdate();
      ps.close();
      conn.close();
  }  
}

刪除數據(delete)

public class TestPreparedStatement {
  public static final String DRIVER = "com.mysql.cj.jdbc.Driver";
  private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb?	    useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
  private static final String USER = "root";
  private static final String PWD = "root";
  public static void main(String[] args)throws Exception {
      insert(66,"asdfaf","jiadjfa");
  }
  /**
    * 功能描述:刪除
    * @param:
    * @return:
    */
  public static void delete(int deptno)  throws Exception{
     Class.forName(DRIVER);
     Connection conn = DriverManager.getConnection(URL, USER, PWD);
     String sql = "delete from dept where deptno=? ";
     PreparedStatement ps = conn.prepareStatement(sql);
     ps.setInt(1,deptno);
     int n = ps.executeUpdate();
     ps.close();
     conn.close();
  }
}

查詢數據(select)

public class TestPreparedStatement {
  public static final String DRIVER = "com.mysql.cj.jdbc.Driver";
  private static final String URL = "jdbc:mysql://127.0.0.1:3306/mydb?	    useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
  private static final String USER = "root";
  private static final String PWD = "root";
  public static void main(String[] args)throws Exception {
      insert(66,"asdfaf","jiadjfa");
  }
 /**
   * 功能描述:模糊查詢
   * @param:
   * @return:
   */
 public static void find(String n) throws Exception {
      Class.forName(DRIVER);
      Connection conn = DriverManager.getConnection(URL, USER, PWD);
      String sql = "select * from emp where ename like ? ";
      PreparedStatement ps = conn.prepareStatement(sql);
      ps.setString(1,"%"+n+"%");
      ResultSet rs = ps.executeQuery();
      while (rs.next()) {
          int enmno = rs.getInt("EMPNO");
          String eName=rs.getString("ENAME");
          String job=rs.getString("JOB");
          int mgr = rs.getInt("MGR");
          Date hireDate= rs.getDate("HIREDATE");
          double sal=  rs.getDouble("SAL");
          double comm=  rs.getDouble("COMM");
          int deptNo =rs.getInt("DEPTNO");
          StringBuilder str = new StringBuilder();
          str.append(enmno+"  ").append(eName+"  ").append(job+"  ").append(mgr+"  ").append(hireDate+"  ").append(sal+"  ").append(comm+"  ").append(deptNo+"  ");
            System.out.println(str.toString());
     }
        rs.close();
        ps.close();
        conn.close();
  }
}

JDBC事務

禁止事務自動提交(setAutoCommit)

​ setAutoCommit(false);

手動提交事務(commit)

​ conn.commit()

回滾(rollback)

​ conn.rollback()

public class TestTransaction {
    public static void main(String[] args) {
        //1.加載驅動
        PreparedStatement pst = null;
        Connection conn = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
            String user = "root";
            String pwd = "root";
            //2.創建數據庫連接
            conn = DriverManager.getConnection(url, user, pwd);
            //禁止事務自動提交
            conn.setAutoCommit(false);
            String sql = "update account set money= money-100 where username=?";
            pst = conn.prepareStatement(sql);
            pst.setString(1, "張三");
            //發送SQL命令
            pst.executeUpdate();
            sql = "update account set money=money+100 where username=?";
            pst = conn.prepareStatement(sql);
            pst.setString(1, "李四");
            //發送SQL命令
            pst.executeUpdate();
        } catch (ClassNotFoundException e) {
            try {
                //回滾
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (null != conn) {
                try {
                    //提交事務
                    conn.commit();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //關閉資源
            if (null != pst) {
                try {
                    pst.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != conn) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

JDBC API 總結

Connection接口 方法

代表數據庫連接

void close() 立即釋放此 Connection 對象的數據庫和 JDBC 資源,而不是等待它們被自動釋放。
void commit() 使所有上一次提交/回滾後進行的更改成爲持久更改,並釋放此 Connection 對象當前持有的所有數據庫鎖。
Statement createStatement() 創建一個 Statement 對象來將 SQL 語句發送到數據庫。
CallableStatement prepareCall(Stringsql) 創建一個 CallableStatement 對象來調用數據庫存儲過程。
PreparedStatement prepareStatement(Stringsql) 創建一個 PreparedStatement 對象來將參數化的 SQL 語句發送到數據庫。
PreparedStatement [prepareStatement](mk:@MSITStore:C:\Users\Administrator\Desktop\JDK_API_1_6_zh_CN.CHM::/java/sql/Connection.html#prepareStatement(java.lang.String, int))(Stringsql, int autoGeneratedKeys) 創建一個默認 PreparedStatement 對象,該對象能獲取自動生成的鍵。
void rollback() 取消在當前事務中進行的所有更改,並釋放此 Connection 對象當前持有的所有數據庫鎖。
void setAutoCommit(boolean autoCommit) 將此連接的自動提交模式設置爲給定狀態。

DriverManager類 方法

管理一組 JDBC 驅動程序的基本服務

方法摘要
staticConnection getConnection(Stringurl) 試圖建立到給定數據庫 URL 的連接。
staticConnection [getConnection](mk:@MSITStore:C:\Users\Administrator\Desktop\JDK_API_1_6_zh_CN.CHM::/java/sql/DriverManager.html#getConnection(java.lang.String, java.util.Properties))(Stringurl,Propertiesinfo) 試圖建立到給定數據庫 URL 的連接。
staticConnection [getConnection](mk:@MSITStore:C:\Users\Administrator\Desktop\JDK_API_1_6_zh_CN.CHM::/java/sql/DriverManager.html#getConnection(java.lang.String, java.lang.String, java.lang.String))(Stringurl,Stringuser,Stringpassword) 試圖建立到給定數據庫 URL 的連接。

Statement接口 方法

用於將 SQL 語句發送到數據庫中,或理解爲執行sql語句

方法 作用
ResultSet executeQuery(String sql) 執行SQL查詢並獲取到ResultSet對象
boolean execute(String sql) 可以執行任意SQL語句,然後獲得一個布爾值,表示是否返回ResultSet
int executeUpdate(String sql) 可以執行插入、刪除、更新等操作,返回值是執行該操作所影響的行數

ResultSet接口 方法

ResultSet裏的數據一行一行排列,每行有多個字段,且有一個記錄指針,指針所指的數據行叫做當前數據行,我們只能來操作當前的數據行。我們如果想要取得某一條記錄,就要使用ResultSet的next()方法 ,如果我們想要得到ResultSet裏的所有記錄,就應該使用while循環

ResultSet對象自動維護指向當前數據行的遊標。每調用一次next()方法,遊標向下移動一行

方法名 說 明
boolean next() 將光標從當前位置向下移動一行
boolean previous() 遊標從當前位置向上移動一行
void close() 關閉ResultSet 對象
int getInt(int colIndex) 以int形式獲取結果集當前行指定列號值
int getInt(String colLabel) 以int形式獲取結果集當前行指定列名值
float getFloat(int colIndex) 以float形式獲取結果集當前行指定列號值
Float getFloat(String colLabel) 以float形式獲取結果集當前行指定列名值
String getString(int colIndex) 以String 形式獲取結果集當前行指定列號值
StringgetString(String colLabel) 以String形式獲取結果集當前行指定列名值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章