JDBC


個人理解:

  JDBC就是用了讓JAVA代碼能更好的與數據庫連接而由數據庫廠商提供的接口,驅動是其實現類。使用JDBC需要幾個步驟,同時對於增刪改查也分為兩種不同的操作,為了避免設置拼串時可能出現異常,使用preparedStatement進行預處理,為了減少代碼量,可以將相同的代碼封裝到一個工具類內。

一、概述:

  JDBC(Java Data Base Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。是Java訪問數據庫的標准規范

  JDBC提供了一種基准,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。

  DBC需要連接驅動,驅動是兩個設備要進行通信,滿足一定通信數據格式,數據格式由設備提供商規定,設備提供商為設備提供驅動軟件,通過軟件可以與該設備進行通信。

二、原理:

  Java提供訪問數據庫規范稱為JDBC,而生產廠商提供規范的實現類稱為驅動。

  JDBC是接口,驅動是接口的實現類,沒有驅動將無法完成數據庫連接,從而不能操作數據庫!每個數據庫廠商都需要提供自己的驅動,用來連接自己公司的數據庫,也就是說驅動一般都由數據庫生成廠商提供。

三、開發步驟:

  1、注冊驅動.

      告知JVM使用的是哪一個數據庫的驅動

  2、獲得連接.

      使用JDBC中的類,完成對MySQL數據庫的連接

  3、獲得語句執行平台

      通過連接對象獲取對SQL語句的執行者對象

  4、執行sql語句

      使用執行者對象,向數據庫執行SQL語句  獲取到數據庫的執行后的結果

  5、處理結果

  6、釋放資源.

      調用一堆close()方法.

package com.oracle.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注冊驅動(靜態方法)(包名+類名)
        Class.forName("com.mysql.jdbc.Driver");
        //2.獲取連接對象(導包都導sql里面的,不導jdbc里的;多態!報異常是因為用戶輸入的串可能寫錯)后面設置下數據格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);報地址為正確sql服務關了可能報錯
        //3.獲取語句執行平台:
        Statement sta=conn.createStatement();
        //4.執行SQL語句:增-----一套語句執行一句sql語句 返回的是一個Int值,是指執行了幾行
        String sql="insert into sort(sname) values('口紅')";
        int row=sta.executeUpdate(sql);
        System.out.println(row);
        //6.釋放資源(先開后關)
        sta.close();
        conn.close();
    }
}

1、導入驅動JAR包:

  創建lib目錄,用於存放當前項目需要的所有jar包

  選擇jar包,右鍵執行build path / Add to Build Path

2、注冊驅動:

3、獲得鏈接:

jdbc:mysql://localhost:3306/mydb

JDBC規定url的格式由三部分組成,每個部分中間使用冒號分隔。

   第一部分是jdbc,這是固定的;

   第二部分是數據庫名稱,那么連接mysql數據庫,第二部分當然是mysql了;

   第三部分是由數據庫廠商規定的,我們需要了解每個數據庫廠商的要求,mysql的第三部分分別由數據庫服務器的IP地址(localhost==127.0.0.1)、端口號(3306),以及DATABASE名稱(mydb)組成。

 4、獲得語句執行平台:

常用方法:

①、 int

   executeUpdate(String sql); --執行insert 、update、 delete語句.返回執行的行數int值。所有的增刪改都執行這個語句

②、 ResultSet

    executeQuery(String sql); --執行select語句.返回ResultSet的結果集對象(二維表格)

③、 boolean

    execute(String sql); --執行select返回true 執行其他的語句返回false.

5、處理結果集:(執行insert、update、delete無需處理)

  ResultSet實際上就是一張二維的表格,我們可以調用其boolean next()方法指向某行記錄,當第一次調用next()方法時,便指向第一行記錄的位置,這時就可以使用ResultSet提供的getXXX(int col)方法(與索引從0開始不同個,列從1開始)來獲取指定列的數據:

rs.next();//指向第一行
rs.getInt(1);//獲取第一行第一列的數據
package com.oracle.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class Demo04 {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
                //1.注冊驅動(靜態方法)(包名+類名)
                Class.forName("com.mysql.jdbc.Driver");
                //2.獲取連接對象(導包都導sql里面的,不導jdbc里的;多態!報異常是因為用戶輸入的串可能寫錯)后面設置下數據格式
                String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
                String user="root";
                String password="123456";
                Connection conn=DriverManager.getConnection(url,user,password);
                //System.out.println(conn);報地址為正確sql服務關了可能報錯
                //3.獲取語句執行平台:
                Statement sta=conn.createStatement();
                //4.執行sql語句
                String sql="select * from sort";
                ResultSet rs=sta.executeQuery(sql);
                //5.處理結果集(括號里一般是第1列、第2列,但是可以寫字段名)
                ArrayList<Sort> arr=new ArrayList<Sort>();
                while(rs.next()){
                    //System.out.println(rs.getInt("sid")+"..."+rs.getString("sname"));
                    Sort sort=new Sort();
                    sort.setSid(rs.getInt("sid"));
                    sort.setSname(rs.getString("sname"));
                    arr.add(sort);
                }
                System.out.println(arr);
                //6.釋放資源
                rs.close();
                sta.close();
                conn.close();
    }
}

6、釋放資源:

  使用后的東西都需要關閉!關閉的順序是先得到的后關閉,后得到的先關閉。

四、注入問題:

  假設有登錄案例SQL語句如下:

  SELECT * FROM 用戶表 WHERE NAME = 用戶輸入的用戶名 AND PASSWORD = 用戶輸的密碼;

  此時,當用戶輸入正確的賬號與密碼后,查詢到了信息則讓用戶登錄。但是當用戶輸入的賬號為XXX 密碼為:XXX’  OR ‘a’=’a時,則真正執行的代碼變為:

  SELECT * FROM 用戶表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;

  此時,上述查詢語句時永遠可以查詢出結果的。那么用戶就直接登錄成功了,顯然我們不希望看到這樣的結果,這便是SQL注入問題。

主要是Statement是用拼串傳值的!這樣就會造成可能出現危險!

  為此,我們使用PreparedStatement(預編譯對象)來解決對應的問題。

五、預處理對象:

  使用PreparedStatement預處理對象時,建議每條sql語句所有的實際參數,都使用逗號分隔。

String sql = "insert into sort(sid,sname) values(?,?)";;

PreparedStatement預處理對象代碼:

PreparedStatement psmt = conn.prepareStatement(sql)

package com.oracle.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Demo07 {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //1.注冊驅動(靜態方法)(包名+類名)
        Class.forName("com.mysql.jdbc.Driver");
        //2.獲取連接對象(導包都導sql里面的,不導jdbc里的;多態!報異常是因為用戶輸入的串可能寫錯)后面設置下數據格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);報地址為正確sql服務關了可能報錯
        //3.獲取語句執行平台對象:
        String sql="select count(*) from user where uname=? and pwd=?";
        PreparedStatement pst=conn.prepareStatement(sql);
        //4.執行sql語句
        Scanner sc=new Scanner(System.in);
        System.out.println("請出入用戶名:");
        String uname=sc.next();
        System.out.println("請輸入密碼:");
        String pwd=sc.next();
        //給sql語句的?賦值
        pst.setString(1,uname);
        pst.setString(2, pwd);
        ResultSet rs= pst.executeQuery();//()里不能寫sql
        
        //5.處理結果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);//因為就一列
            System.out.println(count);    
        }
        //6.釋放資源
            rs.close();
            pst.close();
            conn.close();
    }
}

 

六、JDBC工具類:

  “獲得數據庫連接”操作,將在以后的增刪改查所有功能中都存在,可以封裝工具類JDBCUtils。提供獲取連接對象的方法,從而達到代碼的重復利用。

package com.oracle.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtils {
    //獲取連接對象的方法(靜態的)
    public static  Connection getConn(){
        Connection conn=null;
                try {
                    //1.注冊驅動(靜態方法)(包名+類名)
                    Class.forName("com.mysql.jdbc.Driver");
                    //2.獲取連接對象(導包都導sql里面的,不導jdbc里的;多態!報異常是因為用戶輸入的串可能寫錯)后面設置下數據格式
                    String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
                    String user="root";
                    String password="123456";
                    conn=DriverManager.getConnection(url,user,password);
                } catch (ClassNotFoundException | SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return conn;    
    }
    //釋放資源
    public static void close(Connection conn,Statement sta){
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    //釋放資源2
    public static void close(Connection conn,Statement sta,ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
package com.oracle.demo01;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo08 {

    public static void main(String[] args) throws SQLException {
        add();

    }
    //新增分類Sort
    public static void add() throws SQLException{
        //1.獲得連接對象
        Connection conn=JDBCUtils.getConn();
        //測試下是地址不System.out.println(conn);
        //2.獲取語句執行平台
        String sql="insert into sort (sname) values(?)";
        PreparedStatement pst=conn.prepareStatement(sql);
        //3.執行sql
        pst.setString(1, "打火機");
        int row=pst.executeUpdate();
        System.out.println(row);
        //4.釋放資源
        JDBCUtils.close(conn, pst);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM