JDBC 、開發步驟、注入問題、預處理executeupdate、executequery方法、工具類


 JDBC概述

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

JDBC原理

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

 

理解:

java與數據庫連接的一種類,jdk提供的接口叫JDBC,數據庫的廠商提供的實現類叫驅動,驅動就是實現類,JDBC需要6個步驟,有兩種不同的增刪改查,反之拼串出現異常,用 PreparedSttement預處理方法,減少更多的代碼量,將重復的代碼封裝在一個類里。

JDBC開發步驟

1.注冊驅動.:告知JVM使用的是哪一個數據庫的驅動

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

3獲得語句執行平台:通過連接對象獲取對SQL語句的執行者對象

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

處理結果.放到容器,ArraList

6.釋放資源.   調用一堆close()方法,釋放內存

導入驅動jar包

解壓L:mysql-connector-java-5.1.37

目錄

docs:文檔手冊

src:放源碼

倒數第三:驅動包

1.md lib目錄

1:(項目文件夾new-Folder起名 lib),復制jar包粘貼到lib目錄,存放當前項目需要的所有jar包

2:選擇jar包,右鍵build path / Add to Build Path(添加到環境)牛奶瓶

 

 2.API詳解:注冊驅動 

3.獲得連接對象:類名:Connection

jdbc:mysql://localhost:3306/mydb

 

代碼:Connection con = DriverManager.getConnection
(“jdbc:mysql://localhost(or 127.0.0.1):3306/mydb”,”root”,”root”);

 

JDBC的url的格式三部分,部分中間使用冒號分隔

第一部分 JDBC 固定的

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

第三部分 locanhost  =127.0.0.1,端口 3306  和DATABASE名稱 (mysql組成)  

  

Connection conn  接口  ,DriverManager。。是實現類:多態形式    導包 全導sql包 

 4.獲得語句執行平台:Statement

格式:

String sql = "某SQL語句";
獲取Statement語句執行平台:Statement stmt = con.createStatement();

常用方法:

1、int int:executeUpdate(String sql); --執行 insert、update、delete 返回執行 int(返回行數)  增、刪、改、查都用它

2、Result   executeQuery(String sql);--執行select語句,返回resultset結果集對象,(二維表格)放到ArrayList

3、boolean  execute(String sql);執行select 返回true 執行其他 返回false

5處理結果集:(執行 inset 、update、delete無序處理)

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

6、釋放資源close (關閉順序:先開的后關 ,反之)

package com.oracle.demo01;
//數據的增刪改,把紅色的部分替換
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Add新增 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注冊驅動
        Class.forName("com.mysql.jdbc.Driver");//靜態方法  "" 里面放包名加類名
        //2.獲取鏈接對象 (報異常:因為用戶輸入的串可能寫錯)后面設置下數據格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插這句=紅娘
        String user="root";
        String password="123456";
     //Connection:接口   Driver:實現類型  多態形式    全導 sql包 Connection conn
=DriverManager.getConnection(url,user,password); //System.out.println(conn);//打印conn測試,如果sql服務關了,會報錯 //3.獲得執行語句平台  Statement Statement sta=conn.createStatement(); //4.執行sql語句 新增:一套語句執行一句sql語句 String sql="insert into sort(sname) values('口紅')";//外面雙引號 里面必須單引號
     String sql="update sort set sname='金箍棒' where sid=4"; //數據的改
     String sql="delete from sort where sid=1";//數據的刪 int row=sta.executeUpdate(sql);//執行語句 返回值int 是行數 System.out.println(row); //6.釋放資源(先開的后關)關的是變量名 sta.close();//sta在conn的后面 conn.close(); } }

 看異常

最頂上:信息,異常類,位置(找認識的位置)

1.com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column

原因:Sting類型沒有加單引號

2.Duplicate entry '1' for key 'PRIMARY'

原因,主鍵值存在或混亂,要先刪除數據或者清空表

3.com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'password' in

原因:可能輸入的值的類型不對,確定是否插入的元素時對應的值的類型正確

4.Data truncated for column 'Prices' at row 1

原因:數據過長導致被截斷,注意對應值的類型與長度限制——一般把長度調高一點就可以

 pm

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

rs.next();//指向第一行 rs.getInt(1);//獲取第一行第一列的數據
package com.oracle.demo01;
//查詢 Query 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 Query {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注冊驅動
        Class.forName("com.mysql.jdbc.Driver");//靜態方法    
        //2.獲取鏈接對象
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插這句=紅娘
        String user="root";        
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //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外面
        while(rs.next()){
            //System.out.println(rs.getInt(1)+"..."+rs.getString(2));//()里的1 和2可以改為 sid和 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();
    }
}

 

package com.oracle.demo01;

public class Sort {
    //字段對應屬性
    private int sid;
    private String sname;
    //get set toString方法
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    @Override
    public String toString() {
        return "Sort [sid=" + sid + ", sname=" + sname + "]";
    }    
}
-------------------------------------------
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 Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注冊驅動
        Class.forName("com.mysql.jdbc.Driver");//靜態方法
        //2.獲取鏈接對象
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插這句=紅娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);
        //3.獲得執行語句平台
        Statement sta=conn.createStatement();    
        //4.執行sql
        String sql="select count(*) from sort";
        ResultSet rs=sta.executeQuery(sql);
        //5.處理結果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);
        }
        System.out.println(count);
        //6.釋放資源(先開的后關)
        rs.close();
        sta.close();
        conn.close();        
    }
}

四、注入問題:

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

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

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

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

查詢語句時永遠可以查詢出結果的。用戶就直接登錄成功了,這便是SQL注入問題

使用PreparedStatement來解決對應的問題。

package com.oracle.demo01;
//登錄功能 sql注入問題
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Demo05 {
    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";//0603后面插這句=紅娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);//打印conn測試,如果sql服務關了,會報錯
        //System.out.println(conn);
        //3.獲得執行語句平台
        Statement sta=conn.createStatement();    
        //4.執行sql
        //讓用戶輸入用戶名
        Scanner sc=new Scanner(System.in);
        System.out.println("請輸入用戶名");
        String uname=sc.next();
        //用戶輸入密碼
        System.out.println("請輸入密碼");
        String pwd=sc.next();
        String sql="select count(*) from "
                + "user where uname='"+uname+"' and pwd='"+pwd+"'";
        ResultSet rs=sta.executeQuery(sql);
        //5.處理結果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);
        }
        System.out.println(count);
        //6.釋放資源(先開的后關)
        rs.close();
        sta.close();
        conn.close();        
    }
}

 

預處理對象    PreparedStatement

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

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

PreparedStatement預處理對象代碼:

PreparedStatement psmt = conn.prepareStatement(sql)

常用方法:

執行SQL語句:

 int executeUpdate(); --insert update delete語句.增刪改

 ResultSet executeQuery(); --select語句.查詢

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

實際參數

void setXxx(int index, Xxx xx) 指定參數設置為xx值,將此值發送到數據庫時,驅動程序將它轉換成一個 SQL Xxx類型

 

舉例:setString(2, "家用電器") 把SQL語句中第2個位置的占位符? 替換成實際參數 "家用電器"

 

package com.oracle.demo01;
//預處理對象executeQuery方法

通過預處理對象的executeQuery方法,完成記錄的select語句的執行。格式

 1. 注冊驅動 2. 獲取連接 3. 獲取預處理對象4. SQL語句占位符設置實際參數5. 執行SQL語句6. 處理結果集(遍歷結果集合)7. 釋放資源
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 PrepareStatement {
    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";//0603后面插這句=紅娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);//打印conn測試,如果sql服務關了,會報錯
        //System.out.println(conn);
        //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();//調query的方法 ()里不用寫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;
//JDBC工具類 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();
            }
        }
    }
}

 PreparedStatement 新增功能:

package com.oracle.demo01;
//PreparedStatement 新增功能 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