JDBC技術(二)

JDBC技術(一):
https://blog.csdn.net/Veer_c/article/details/103845176
JDBC技術(二):
https://blog.csdn.net/Veer_c/article/details/103879890
JDBC技術(三):
https://blog.csdn.net/Veer_c/article/details/103880021
JDBC技術(四):
https://blog.csdn.net/Veer_c/article/details/103882264

由於我們頻繁的使用註冊驅動,釋放資源的方法,所以我們可以將上述方法抽取出來,形成 一個JDBC 工具類,這樣我們就很方便的進行獲取連接,釋放資源的方法:

package com.jdbc.Util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtil {
    private static String url = "jdbc:mysql://localhost:3306/day20";
    private static String user = "root";
    private static String password = "root";
    static{
        //隨着類的加載而夾在
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //獲取連接
    public static Connection getConn(){
        //註冊驅動
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    //釋放資源
    public static void close(Connection conn,Statement stmt,ResultSet rs){
        if (conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

3.執行DQL語句

package com.jdbc.b.statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.jdbc.Util.JDBCUtil;
public class Demo3 {
    public static void main(String[] args) {
        //定義一個連接對象和一個語句執行者
        Connection conn  =null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            //定義sql
            String sql = "SELECT * FROM student;";
            //獲取語句執行者對象
            stmt = conn.createStatement();
            //執行DQL查詢語句
            //ResultSet executeQuery(String sql)
            //throws SQLException執行給定的 SQL 語句,該語句返回單個 ResultSet 對象。
            rs = stmt.executeQuery(sql);
            //ResultSet是一個結果集
            /*//判斷有沒有下一行數據
            if (rs.next()) {
                //說明有下一行數數據
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //說明有下一行數數據
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //說明有下一行數數據
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //說明有下一行數數據
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }
            if (rs.next()) {
                //說明有下一行數數據
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }*/
            //使用while循環改進上面的代碼,獲取字段的數據(字段類型+列號)
/*          while (rs.next()) {
                System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3));
            }*/
            //使用字段名稱獲取字段的每一個數據
            while (rs.next()) {
                //當我們使用字段名稱去獲取字段數據的時候,字段名稱是不區分大小寫
                System.out.println(rs.getInt("ID")+"--"+rs.getString("NAME")+"--"+rs.getInt("AGE"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

注意:在執行DQL的時候,會返回一個結果集合,我們要將集合中的數據拿出來,這樣我們不知道下一個數據還有沒有,所以要提前進行判斷,而且還必須用相應的格式來將返回的值帶出來。
ResultSet的使用:
在這裏插入圖片描述
4.PreparedStatement()接口,用於執行預編譯的sql語句(是Statement的子接口)
預編譯命令:將sql語句中的參數設置爲動態參數,在之的查詢過程的時候,可以給參數重新設置值,是程序變得更加靈活。

package com.jdbc.c_preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.jdbc.Util.JDBCUtil;
public class Demo {
    public static void main(String[] args) {
        //testInsert();
        //testUpdate();
        //testDelete();
        testSelect();
    }
    private static void testSelect() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            //獲取連接
            conn  = JDBCUtil.getConn();
            //定義預編譯sql
            String sql = "SELECT * FROM student WHERE id=?;";
            //獲取預編譯sql對象
            stmt = conn.prepareStatement(sql);
            //給問好賦值
            stmt.setInt(1, 3);
            //發送參數並執行sql語句
            //ResultSet executeQuery()throws SQLException在此 
            //PreparedStatement 對象中執行 SQL 查詢,並返回該查詢生成的 ResultSet 對象。
            rs = stmt.executeQuery();
            //遍歷結果集
            while (rs.next()) {
                System.out.println(rs.getInt("id")+"--"+rs.getString("name")+"--"+rs.getInt("age"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testDelete() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        try{
            conn = JDBCUtil.getConn();
            //寫一個參數化的sql
            String sql = "DELETE FROM student WHERE id=?;";
            //獲取預編譯的sql對象
            stmt = conn.prepareStatement(sql);
            //給?設置參數
            stmt.setInt(1, 2);
            //發送參數並執行sql
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, null);
        }
    }
    private static void testUpdate() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "UPDATE student SET NAME=? WHERE id=?;";
            //執行預編譯sql
            stmt = conn.prepareStatement(sql);
            //給?賦值
            stmt.setString(1, "張學友");
            stmt.setInt(2, 5);
            //發送參數到數據庫服務器,並執行sql,將執行結果返回
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, null);
        }
    }
    private static void testInsert() {
        //定義連接對象和預編譯sql對象
        Connection conn  = null;
        PreparedStatement stmt = null;
        try{
            //獲取連接
            conn = JDBCUtil.getConn();
            //PreparedStatement prepareStatement(String sql)
            //throws SQLException創建一個 PreparedStatement 對象來將參數化的 SQL 語句發送到數據庫。
            String sql = "INSERT INTO student VALUES(?,?,?);";//參數化的sql,動態sql
            stmt = conn.prepareStatement(sql);//需要一個預編譯的sequel語句,將sq發送到數據庫端,檢查sql語法及用戶權限等信息
            //給之前參數化的sql語句設置參數
            //兩個參數:1:是給第幾個?設置數據    2:給?設置的數據
            stmt.setInt(1, 5);
            stmt.setString(2, "黎明");
            stmt.setInt(3, 60);
            //int executeUpdate()throws SQLException
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //釋放資源
            JDBCUtil.close(conn, stmt, null);
        }
    }
}

注意:在我們給程序分配一定的權限的時候,我們必須使用預編譯 命令,因爲如果直接使用Statement(),將用戶的信息完全暴露出來,這樣程序很不安全,所以我們應該使用預編譯命令,將用戶的信息傳遞進去,避免這種情況。
5.使用預編譯 命令處理用戶的的登錄問題

package com.jdbc.c_preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.jdbc.Util.JDBCUtil;
public class Login {
    //SELECT * FROM USER WHERE userName='james' OR 1=1 -- ' AND PASSWORD='123456';
    //sql注入行爲
    private static String user = "james' OR 1=1 -- ";
    private static String password = "123456";
    public static void main(String[] args) {
        //testStatement();
        testPreparedStatement();
    }
    private static void testPreparedStatement() {
        Connection conn  =null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            conn  =JDBCUtil.getConn();
            String sql = "SELECT * FROM USER WHERE userName=? AND PASSWORD=?;";
            stmt = conn.prepareStatement(sql);
            //給問號設置參數
            stmt.setString(1, user);
            stmt.setString(2, password);
            //發送參數並執行sql
            rs = stmt.executeQuery();
            if (rs.next()) {
                System.out.println("登陸成功");
            }else {
                System.out.println("登錄失敗");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testStatement() {
        Connection conn  =null;
        Statement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            stmt = conn.createStatement();
            String sql  ="SELECT * FROM USER WHERE userName='"+user+"' AND PASSWORD='"+password+"';";
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                System.out.println("登陸成功");
            }else {
                System.out.println("登錄失敗");
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

6.CallableStatement()接口,用於執行sql存儲過程的接口(是PreparedStatement的子接口)

package com.jdbc.d_callablestatement;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import com.jdbc.Util.JDBCUtil;
public class Demo {
    public static void main(String[] args) {
        //執行帶有輸入參數存儲過程
        //testIn();
        //執行帶有輸出參數的存儲過程
        testOut();
    }
    private static void testOut() {
        Connection conn  =null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "CALL pro_QueryNameById(?,?);";
            stmt = conn.prepareCall(sql);
            //給問號賦值
            stmt.setInt(1, 2);
            //如果存儲過程帶有輸出參數的時候,首先需要註冊,輸出參數的類型
            //void registerOutParameter(int parameterIndex,int sqlType)
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
            //發送參數並執行sql
            stmt.executeQuery();
            //從stmt中取出輸出參數的結果
            System.out.println(stmt.getString(2));
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //釋放資源
            JDBCUtil.close(conn, stmt, rs);
        }
    }
    private static void testIn() {
        Connection conn  =null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtil.getConn();
            String sql = "CALL pro_QueryById(?);";
            stmt = conn.prepareCall(sql);
            //給問號設置值
            stmt.setInt(1, 2);
            //發送參數並執行sql,只能調用excuteQuery()
            rs = stmt.executeQuery();
            if (rs.next()) {
                System.out.println(rs.getInt(1)+"--"+rs.getString(2));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //釋放資源
            JDBCUtil.close(conn, stmt, rs);
        }
    }
}

注意:在使用存儲過程的接口的時候,如果存儲過程會有返回值,那麼我們應該顯註冊一個返回值類型,然後在去接受這個返回值。
//如果存儲過程帶有輸出參數的時候,首先需要註冊,輸出參數的類型:
//void registerOutParameter(int parameterIndex,int sqlType)
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);

JDBC技術(一):
https://blog.csdn.net/Veer_c/article/details/103845176
JDBC技術(二):
https://blog.csdn.net/Veer_c/article/details/103879890
JDBC技術(三):
https://blog.csdn.net/Veer_c/article/details/103880021
JDBC技術(四):
https://blog.csdn.net/Veer_c/article/details/103882264

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章