1. 程式人生 > >4.JDBC編程

4.JDBC編程

黑窗口 values 接口 span etc prepare png 增加 col

01.JDBC_Java程序和MySQL的關系: 1).Java程序跟其它MySQL客戶端一樣,就是一個"客戶端",用於"封裝SQL語句"並發送給MySQL服務器, MySQL服務器會直接返回結果給我們的程序。   技術分享圖片   (上面的命令行就是黑窗口,它與 SQLYog、JAVA程序一樣,同級) 02.JDBC_驅動的概念: 由數據庫廠商為每種編程語言提供的一個程序包。有兩種語言組成:前端:所面向的編程語言;後端:數據庫本身的語言。 它可以使各種編程語言直接訪問本語言,就可以訪問數據庫軟件,方便操作。 JDBC物理上由一組類和接口組成(通過工具類進行具體操作,JDBC接口實現類),隨JDK一起發放。
03.JDBC_JDBC的概念: 由SUN公司提出的Java連接數據庫的規範,它規範了Java連接各種數據庫所遵循的步驟和數據類型。它要求各數據庫廠商的驅動程序必須遵守這套規範,也需要Java程序員直接學習這套規範,這樣可以使得Java程序員訪問各種數據庫都使用同樣的步驟和數據類型。

技術分享圖片

04.JDBC_JDBC的四個核心類: 1).DriverManager(類) : 驅動管理器。 用於連接數據庫的"驅動程序",並通過驅動程序去連接數據庫軟件,向程序返回一個"連接通道(Connection對象)"。 2).Connection(接口) : "連接"對象。代表了程序和數據庫之間的一個"連接通道"。
3).Statement(接口) : SQL執行器。用於執行SQL語句。 4).ResultSet(接口) : 結果集。當Statement執行"查詢"語句時,會返回此對象。 05.JDBC_JDBC的開發步驟: 1).下載MySQL的Java驅動包,並復制到項目目錄下,並添加到構建路徑: mysql-connector-java-5.1.37-bin.jar 2).開發步驟: 1.註冊驅動 2.獲取連接 3.獲取SQL執行器 4.執行SQL,並獲取結果集(查詢) 5.解析結果集 6.關閉資源
/*
* 1.註冊驅動 * 2.獲取連接 * 3.獲取SQL執行器 * 4.執行SQL,並獲取結果集(查詢) * 5.解析結果集 * 6.關閉資源 */ public class Demo { public static void main(String[] args) throws Exception { //1.註冊驅動 // 數據庫.jdbc.驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1", "root", "root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL,並獲取結果集(查詢) String sql = "select * from product"; ResultSet rs = stmt.executeQuery(sql); //5.解析結果集 while(rs.next()){ System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } //6.關閉資源 rs.close(); stmt.close(); conn.close(); } @Test public void delete() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "delete from product where pid = 6"; int row = stmt.executeUpdate(sql); System.out.println("刪除影響的行數:" + row); stmt.close(); conn.close(); } }
06.JDBC_關於Statement的常用方法: 1).public int executeUpdate(String sql):用於執行添加(insert)、修改(update)、刪除(delete)語句的。 返回值:int,影響的行數。 2).public ResultSet executeQuery(String sql):用於執行查詢(select) 返回值:ResultSet結果集。 註意:兩種不能混用。不能用executeUpdate()執行查詢語句,反之也不可以。 07.JDBC_關於ResultSet的使用: 1).ResultSet就類似於之前的"叠代器" 叠代器:while(it.hasNext()) { 結果集:while(rs.next()) { it.next(); rs.get數據類型(String 列名) } 或者 rs.get數據類型(int 列索引) 大招: rs.getObject(String 列名) rs.getObject(int 列索引) }

08.JDBC_使用JDBC實現增刪改查:

public class Demo {
   @Test
public void add() throws Exception{ //1.註冊驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL語句 String sql = "insert into product values(null,‘鋼琴‘,28000,1)"; int row = stmt.executeUpdate(sql); System.out.println("添加影響的行數:" + row); //5.釋放資源 stmt.close(); conn.close(); }
   @Test
public void update() throws Exception{ //1.註冊驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL String sql = "update product set price = 38000 where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("修改影響的行數:" + row); //5.釋放資源 stmt.close(); conn.close(); }
   @Test
public void delete() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "delete from product where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("刪除影響的行數:" + row); stmt.close(); conn.close(); } @Test public void findAll() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "select * from product"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } rs.close(); stmt.close(); conn.close(); } }

09.JDBC_JDBC工具類的制作:

    public class JDBCUtils {
        //1.獲取Connection對象--代碼重用的目的 --靜態方法
        public static Connection getConnection() throws Exception{     //前兩步 定義了一個靜態方法
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root");
            return conn;
        }
        //2.關閉資源
        public static void closeAll(ResultSet rs,Statement stmt,Connection conn) throws SQLException{
            if(rs != null){
                rs.close();
            }
            if(stmt != null){
                stmt.close();
            }
            if(conn != null){
                conn.close();
            }
        }
    }

升級版:

import導包;
//定義一個數據庫工具類JdbcUtil,用來簡化數據庫操作出現的重復代碼。
//創建類JdbcUtil包含3個方法:
//1) 可以把幾個字符串定義成常量
//2) public static Connection getConnection() 得到數據庫的連接
//3) 在靜態代碼塊中註冊驅動,只需註冊一次即可。無需放在getConnection()方法中
//4) public static void close(Connection conn,Statement stmt,ResultSet rs) 關閉所有打開的資源
//5)public static void close(Connection conn,Statement stmt) 關閉沒有結果集的資源,可以調用上面的方法。
public class JDBCUtils {
     private static String driver = "com.mysql.jdbc.Driver";
     private static String url = "jdbc:mysql:///testdb2";
     private static String user = "root";
     private static String password = "root";
     static{
           try {
                Class.forName(driver);
           } catch (Exception e) {
                throw new RuntimeException(e) ;
           }
     }
     public static Connection getConnection() throws Exception{
           Connection conn = DriverManager.getConnection(url, user, password);
           return conn;
     }
     public static void close(Connection conn,Statement stmt,ResultSet rs){
           if (rs != null) {
                try {
                     rs.close();
                } catch (SQLException e) {
                }
           }
           if (stmt != null) {
                try {
                     stmt.close();
                } catch (SQLException e) {
                }
           }
           if (conn != null) {
                try {
                     conn.close();
                } catch (SQLException e) {
                }
           }
     }
     public static void close(Connection conn,Statement stmt){
           if (stmt != null) {
                try {
                     stmt.close();
                } catch (SQLException e) {
                }
           }
           if (conn != null) {
                try {
                     conn.close();
                } catch (SQLException e) {
                }
           }
     }
}

10.JDBC_SQL語句的封裝:

    public class Demo {
        public static void main(String[] args) throws Exception {
            Scanner sc = new Scanner(System.in);
            System.out.println("請輸入商品名稱:");
            String pname = sc.next();//海爾冰櫃
            System.out.println("價格:");
            int price = sc.nextInt();//2300
            System.out.println("類別ID:");
            int cid = sc.nextInt();//1

            //1.獲取連接對象
            Connection conn = JDBCUtils.getConnection();
            //2.獲取SQL執行器
            Statement stmt = conn.createStatement();
            //3.【封裝SQL語句】
            //先想象,封裝後的SQL語句:"insert into product values(null,‘海爾冰櫃‘,2300,1)"
            String sql = "insert into product values(null,‘" + pname +
                                "‘," + price + "," +
                                cid + ")";
            System.out.println(sql);

            //4.執行SQL語句
            int row = stmt.executeUpdate(sql);
            System.out.println("添加影響的行數:" + row);
            //5.釋放資源
            JDBCUtils.closeAll(null, stmt, conn);
        }
    }

11.JDBC_關於SQL註入的問題:

1).什麽是SQL註入:是指在用戶的數據中,包含了一些SQL的格式化符號,例如:)或者(或者,或者‘,如果程序接收後,不加以判斷直接封裝到SQL語句中會導致SQL語句的錯誤。這種現象就叫:SQL註入。 2).SQL註入的登錄演示:
import 導包;
public class Demo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入登錄名:");     //sfasdfg
        String loginName = sc.nextLine();       
        System.out.println("輸入密碼:");        //asfsadf ‘ or ‘1=1    //(後者1=1 恒成立,顯示登錄成功,所以有bug)
        String loginPwd = sc.nextLine();
        //1.獲取連接對象
        Connection conn = JDBCUtils.getConnection();
        Statement stmt = conn.createStatement();
        String sql = "select * from users where uname = ‘" + loginName +
                        "‘ and password = ‘" + loginPwd + "‘";
        System.out.println(sql);
        ResultSet rs = stmt.executeQuery(sql);
        if(rs.next()){
            System.out.println("歡迎:" + loginName + " 登錄系統!");
        }else{
            System.out.println("用戶名或密碼錯誤!!");
        }
        //2.釋放資源
        JDBCUtils.closeAll(rs, stmt, conn);
    }
}
3).怎樣解決SQL註入的問題: 不用Statement,改用它的子接口:PreparedStatement--預處理的SQL執行器 PreparedStatement:它可以嚴格的區分出"SQL語句"和"數據",不會將數據中的SQL的格式化符號解析為SQL格式化符號,而認為就是數據。

12.JDBC_使用PreparedStatement解決SQL註入的問題:

    Scanner sc = new Scanner(System.in);
    System.out.println("請輸入登錄名:");
    String loginName = sc.nextLine();
    System.out.println("輸入密碼:");
    String loginPwd = sc.nextLine();

    Connection conn = JDBCUtils.getConnection();
    //1.先封裝SQL語句,數據部分要用?號占位,任何數據類型不需要單引號
    String sql = "select * from users where uname = ? and password = ?";             //紅色 就是改過的區別
    //2.獲取PreparedStatemet對象
    PreparedStatement ps = conn.prepareStatement(sql);
    //3.填充數據
    ps.setString(1, loginName);     //這個1代表第一個?號
    ps.setString(2, loginPwd);       //這個2代表第二個?號

    //4.執行
    ResultSet rs = ps.executeQuery();//註意:不要再傳SQL語句了,因為之前已經有SQL語句了(ps中已傳入數據了)
    if(rs.next()){
        System.out.println("歡迎:" + loginName + " 登錄系統!");
    }else{
        System.out.println("用戶名或密碼錯誤!!");
    }
    //2.釋放資源
    JDBCUtils.closeAll(rs, ps, conn);

13.JDBC_使用PreparedStatement完成增刪改查(CRUD)--(增刪改查之前一定要確定JDBCUtils工具類 中操作的表格是否在該數據庫下)

  public void add() throws Exception{
        //1.獲取連接對象
        Connection conn = JDBCUtils.getConnection();
        //2.獲取預處理對象
        String sql = "insert into product values(null,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        //3.填充數據
        ps.setString(1, "奔馳");
        ps.setInt(2, 440000);
        ps.setInt(3, 1);
        //4.執行SQL
        int row = ps.executeUpdate();
        System.out.println("添加影響的行數:" + row);
        //5.釋放資源
        JDBCUtils.closeAll(null, ps, conn);          //記得,別忘了關閉資源
    }
    public void update() throws Exception{
        //1.獲取連接對象
        Connection conn = JDBCUtils.getConnection();
        //2.獲取預處理對象
        String sql = "update product set pname = ? , price = ? where pid = ?";     //所以的數據都 用? 替換掉(set在表名後)
        PreparedStatement ps = conn.prepareStatement(sql);
        //3.填充數據
        ps.setString(1, "奔馳E級");
        ps.setInt(2, 420000);
        ps.setInt(3, 9);
        //4.執行SQL
        int row = ps.executeUpdate();
        System.out.println("修改影響的行數:"  + row);
        //5.釋放資源
        JDBCUtils.closeAll(null, ps, conn);
    }
    public void delete() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        String sql = "delete from product where pid = ?";          //刪除沒有 * 號,切記
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 9);
        int row = ps.executeUpdate();
        System.out.println("刪除影響的行數:" + row);
        JDBCUtils.closeAll(null, ps, conn);
    }
    public void findAll() throws Exception{          //查找所有 ,不需要填充數據
        Connection conn = JDBCUtils.getConnection();
        String sql = "select * from product";
        PreparedStatement ps = conn.prepareStatement(sql);

        ResultSet rs = ps.executeQuery();
        while(rs.next()){                                   //查詢所有用 while
            System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
                            + rs.getInt("price") + "\t" + rs.getInt("cid"));
        }
        JDBCUtils.closeAll(rs, ps, conn);
    }
    @Test
    public void findById() throws Exception{
        Connection conn = JDBCUtils.getConnection();
        String sql = "select * from product where pid = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 1);

        ResultSet rs = ps.executeQuery();
        if(rs.next()){                    //切記查找一個,需要用if
            System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
                                        + rs.getInt("price") + "\t" + rs.getInt("cid"));
        }

        JDBCUtils.closeAll(rs, ps, conn);

    }
註意點: 查詢所有用while;查詢某個用if. 而且封裝的對象或集合 要放在while或if判斷語句內! 查詢,格式: String sql = "select name, sal from emp where name like ?" String sql = "select * from emp where id = ?"; 刪除,格式: String sql = "delete from emp where id = ?"; 修改,格式: String sql = "update emp set sal = ? where id = ? "; 增加,格式: String sql = "insert into product values(null,?,?,?)";

4.JDBC編程