JAVA 基礎知識學習20

01JDBC概念和數據庫驅動程序

* A: JDBC概念和數據庫驅動程序
    * a: JDBC概述     
        * JDBC(Java Data Base Connectivity,java數據庫連接)是一種用於執行SQL語句的Java API,
            可以爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。是Java訪問數據庫的標準規範
        * JDBC提供了一種基準,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。
        * JDBC需要連接驅動,驅動是兩個設備要進行通信,滿足一定通信數據格式,數據格式由設備提供商規定,
            設備提供商爲設備提供驅動軟件,通過軟件可以與該設備進行通信。
        * 我們使用的是mysql的驅動mysql-connector-java-5.1.39-bin.jar
    * b: 總結
        * JDBC是java提供給開發人員的一套操作數據庫的接口
        * 數據庫驅動就是實現該接口的實現類

02JDBC原理

* A: JDBC原理
    * a: 描述
        * Java提供訪問數據庫規範稱爲JDBC,而生產廠商提供規範的實現類稱爲驅動
        * DBC是接口,驅動是接口的實現,沒有驅動將無法完成數據庫連接,從而不能操作數據庫!
            每個數據庫廠商都需要提供自己的驅動,用來連接自己公司的數據庫,也就是說驅動一般都由數據庫生成廠商提供。
        * 圖解見day29_source/JDBC實現原理.JPG

03準備數據

* A: 準備數據
    * a: 創建數據庫和表結構
        #創建數據庫
        create database mybase;
        #使用數據庫
        use mybase;
        ###創建分類表
        create table sort(
          sid int PRIMARY KEY AUTO_INCREMENT,
          sname varchar(100),
          sprice DOUBLE,
          sdesc VARCHAR(500)
        );

    * b: 向表中插入數據
        #初始化數據
        insert into sort(sname,sprice,sdesc) values('家電',2000, '優惠的促銷');
        insert into sort(sname,sprice,sdesc) values('傢俱',8900, '傢俱價格上調,原材料漲價');
        insert into sort(sname,sprice,sdesc) values('兒童玩具',290, '賺家長的錢');
        insert into sort(sname,sprice,sdesc) values('生鮮',500.99, '生鮮商品');
        insert into sort(sname,sprice,sdesc) values('服裝',24000, '換季銷售');
        insert into sort(sname,sprice,sdesc) values('洗滌',50, '洗髮水促銷');          

04JDBC的開發步驟

* A: JDBC的開發步驟
    * a: 步驟介紹
        1.註冊驅動
            告知JVM使用的是哪一個數據庫的驅動
        2.獲得連接
            使用JDBC中的類,完成對MySQL數據庫的連接
        3.獲得語句執行平臺
            通過連接對象獲取對SQL語句的執行者對象
        4.執行sql語句
            使用執行者對象,向數據庫執行SQL語句
            獲取到數據庫的執行後的結果
        5.處理結果
        6.釋放資源  一堆close()

05導入mysql數據庫驅動程序jar包

* A: 導入mysql數據庫驅動程序jar包
    * a: 步驟
        * 創建lib目錄,用於存放當前項目需要的所有jar包
        * 選擇jar包,右鍵執行build path / Add to Build Path

06註冊數據庫驅動程序

* A: 註冊數據庫驅動程序
    * a: 案例代碼
public class JDBCDemo {
                public static void main(String[] args)throws ClassNotFoundException,SQLException{
                    //1.註冊驅動 反射技術,將驅動類加入到內容
                    // 使用java.sql.DriverManager類靜態方法 registerDriver(Driver driver)
                    // Diver是一個接口,參數傳遞,MySQL驅動程序中的實現類
                    //DriverManager.registerDriver(new Driver());
                    //驅動類源代碼,註冊2次驅動程序
                    Class.forName("com.mysql.jdbc.Driver");                 
                }
            }

07獲取數據庫的連接對象

* A:獲取數據庫的連接對象
    * a: 案例代碼
    public class JDBCDemo {
                public static void main(String[] args)throws ClassNotFoundException,SQLException{
                    //1.註冊驅動 反射技術,將驅動類加入到內容
                    // 使用java.sql.DriverManager類靜態方法 registerDriver(Driver driver)
                    // Diver是一個接口,參數傳遞,MySQL驅動程序中的實現類
                    //DriverManager.registerDriver(new Driver());
                    //驅動類源代碼,註冊2次驅動程序
                    Class.forName("com.mysql.jdbc.Driver");

                    //2.獲得數據庫連接  DriverManager類中靜態方法
                    //static Connection getConnection(String url, String user, String password)  
                    //返回值是Connection接口的實現類,在mysql驅動程序
                    //url: 數據庫地址  jdbc:mysql://連接主機IP:端口號//數據庫名字
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    //用戶名和密碼用自己的
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);
                    System.out.println(con);                    
                }
            }

08獲取SQL語句的執行對象對象

* A: 獲取SQL語句的執行對象對象
    * a: 案例代碼
public class JDBCDemo {
                public static void main(String[] args)throws ClassNotFoundException,SQLException{
                    //1.註冊驅動 反射技術,將驅動類加入到內容
                    // 使用java.sql.DriverManager類靜態方法 registerDriver(Driver driver)
                    // Diver是一個接口,參數傳遞,MySQL驅動程序中的實現類
                    //DriverManager.registerDriver(new Driver());
                    //驅動類源代碼,註冊2次驅動程序
                    Class.forName("com.mysql.jdbc.Driver");

                    //2.獲得數據庫連接  DriverManager類中靜態方法
                    //static Connection getConnection(String url, String user, String password)  
                    //返回值是Connection接口的實現類,在mysql驅動程序
                    //url: 數據庫地址  jdbc:mysql://連接主機IP:端口號//數據庫名字
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);

                    //3.獲得語句執行平臺, 通過數據庫連接對象,獲取到SQL語句的執行者對象
                    // con對象調用方法   Statement createStatement() 獲取Statement對象,將SQL語句發送到數據庫
                    // 返回值是 Statement接口的實現類對象,,在mysql驅動程序
                    Statement stat = con.createStatement();
                    System.out.println(stat);
                }
            }

09執行insert語句獲取結果集

* A: 執行insert語句獲取結果集
    * a: 案例代碼
public class JDBCDemo {
                public static void main(String[] args)throws ClassNotFoundException,SQLException{
                    //1.註冊驅動 反射技術,將驅動類加入到內容
                    // 使用java.sql.DriverManager類靜態方法 registerDriver(Driver driver)
                    // Diver是一個接口,參數傳遞,MySQL驅動程序中的實現類
                    //DriverManager.registerDriver(new Driver());
                    //驅動類源代碼,註冊2次驅動程序
                    Class.forName("com.mysql.jdbc.Driver");

                    //2.獲得數據庫連接  DriverManager類中靜態方法
                    //static Connection getConnection(String url, String user, String password)  
                    //返回值是Connection接口的實現類,在mysql驅動程序
                    //url: 數據庫地址  jdbc:mysql://連接主機IP:端口號//數據庫名字
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);

                    //3.獲得語句執行平臺, 通過數據庫連接對象,獲取到SQL語句的執行者對象
                    // con對象調用方法   Statement createStatement() 獲取Statement對象,將SQL語句發送到數據庫
                    // 返回值是 Statement接口的實現類對象,,在mysql驅動程序
                    Statement stat = con.createStatement();
                    //  4.執行sql語句
                    // 通過執行者對象調用方法執行SQL語句,獲取結果
                    // int executeUpdate(String sql)  執行數據庫中的SQL語句, insert delete update
                    // 返回值int,操作成功數據表多少行
                    int row = stat.executeUpdate
                            ("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽車用品',50000,'瘋狂漲價')");
                    System.out.println(row);

                    //6.釋放資源  一堆close()
                    stat.close();
                    con.close();
                }
            }

10執行select語句獲取結果集

* A: 執行select語句獲取結果集
    * a: 案例代碼
public class JDBCDemo1 {
                public static void main(String[] args) throws Exception{
                    //1. 註冊驅動
                    Class.forName("com.mysql.jdbc.Driver");
                    //2. 獲取連接對象
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);
                    //3 .獲取執行SQL 語句對象
                    Statement stat = con.createStatement();
                    // 拼寫查詢的SQL
                    String sql = "SELECT * FROM sort";
                    //4. 調用執行者對象方法,執行SQL語句獲取結果集
                    // ResultSet executeQuery(String sql)  執行SQL語句中的select查詢
                    // 返回值ResultSet接口的實現類對象,實現類在mysql驅動中
                    ResultSet rs = stat.executeQuery(sql);
                    //5 .處理結果集
                    // ResultSet接口方法 boolean next() 返回true,有結果集,返回false沒有結果集
                    while(rs.next()){
                        //獲取每列數據,使用是ResultSet接口的方法 getXX方法參數中,建議寫String列名
                        System.out.println(rs.getInt("sid")+"   "+rs.getString("sname")+
                                "   "+rs.getDouble("sprice")+"   "+rs.getString("sdesc"));
                    }

                    rs.close();
                    stat.close();
                    con.close();
                }
            }

11SQL注入攻擊

* A: SQL注入攻擊
    * a: 注入問題
        * 假設有登錄案例SQL語句如下:
        * SELECT * FROM 用戶表 WHERE NAME = 用戶輸入的用戶名 AND PASSWORD = 用戶輸的密碼;
        * 此時,當用戶輸入正確的賬號與密碼後,查詢到了信息則讓用戶登錄。
            但是當用戶輸入的賬號爲XXX 密碼爲:XXX’  OR ‘a’=’a時,則真正執行的代碼變爲:
            * SELECT * FROM 用戶表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;
        * 此時,上述查詢語句時永遠可以查詢出結果的。那麼用戶就直接登錄成功了,顯然我們不希望看到這樣的結果,這便是SQL注入問題。
    * b: 案例演示
CREATE TABLE users(
                 id INT PRIMARY KEY AUTO_INCREMENT,
                 username VARCHAR(100),
                 PASSWORD VARCHAR(100)
            );

            INSERT INTO users (username,PASSWORD) VALUES ('a','1'),('b','2');

            SELECT * FROM users;

            -- 登錄查詢
            SELECT * FROM users WHERE username='dsfsdfd' AND PASSWORD='wrethiyu'1 
            OR 1=1

            SELECT * FROM users WHERE username='a' AND PASSWORD='1'OR'1=1'
            鍵盤錄入:
            1
            1'OR' 1=1

12SQL注入攻擊用戶登錄案例

* A: SQL注入攻擊用戶登錄案例
    * a: 案例代碼
public class JDBCDemo2 {
                public static void main(String[] args)throws Exception {
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username = "root";
                    String password = "123";
                    Connection con = DriverManager.getConnection(url, username, password);
                    Statement stat = con.createStatement();

                    Scanner sc = new Scanner(System.in);
                    String user = sc.nextLine();
                    String pass = sc.nextLine();

                    //執行SQL語句,數據表,查詢用戶名和密碼,如果存在,登錄成功,不存在登錄失敗
            //      String sql = "SELECT * FROM users WHERE username='dsfsdfd' AND PASSWORD='wrethiyu' OR 1=1";
                    String sql = "SELECT * FROM users WHERE username='"+user+"' AND PASSWORD='"+pass+"'";
                    System.out.println(sql);
                    ResultSet rs = stat.executeQuery(sql);
                    while(rs.next()){
                        System.out.println(rs.getString("username")+"   "+rs.getString("password"));
                    }

                    rs.close();
                    stat.close();
                    con.close();
                }
            }

13PrepareStatement接口預編譯SQL語句

* A: PrepareStatement接口預編譯SQL語句
    * a: 預處理對象
        * 使用PreparedStatement預處理對象時,建議每條sql語句所有的實際參數,都使用逗號分隔。
        * String sql = "insert into sort(sid,sname) values(?,?)";;
        * PreparedStatement預處理對象代碼:
        * PreparedStatement psmt = conn.prepareStatement(sql)

    * b: 執行SQL語句的方法介紹
        * int executeUpdate(); --執行insert update delete語句.
        * ResultSet executeQuery(); --執行select語句.
        * boolean execute(); --執行select返回true 執行其他的語句返回false.
    * c: 設置實際參數
        * void setXxx(int index, Xxx xx) 將指定參數設置爲給定Java的xx值。在將此值發送到數據庫時,驅動程序將它轉換成一個 SQL Xxx類型值。
        * 例如:
            * setString(2, "家用電器") 把SQL語句中第2個位置的佔位符? 替換成實際參數 "家用電器"
    * d: 案例代碼
/*
             *  Java程序實現用戶登錄,用戶名和密碼,數據庫檢查
             *  防止注入攻擊
             *  Statement接口實現類,作用執行SQL語句,返回結果集
             *  有一個子接口PreparedStatement  (SQL預編譯存儲,多次高效的執行SQL) 
             *  PreparedStatement的實現類數據庫的驅動中,如何獲取接口的實現類
             *  
             *  是Connection數據庫連接對象的方法
             *  PreparedStatement prepareStatement(String sql) 

             */
            public class JDBCDemo3 {
                public static void main(String[] args)throws Exception {
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username = "root";
                    String password = "123";
                    Connection con = DriverManager.getConnection(url, username, password);
                    Scanner sc = new Scanner(System.in);
                    String user = sc.nextLine();
                    String pass = sc.nextLine();

                    //執行SQL語句,數據表,查詢用戶名和密碼,如果存在,登錄成功,不存在登錄失敗
                    String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=?";
                    //調用Connection接口的方法prepareStatement,獲取PrepareStatement接口的實現類
                    //方法中參數,SQL語句中的參數全部採用問號佔位符
                    PreparedStatement pst =  con.prepareStatement(sql);
                    System.out.println(pst);
                    //調用pst對象set方法,設置問號佔位符上的參數
                    pst.setObject(1, user);
                    pst.setObject(2, pass);

                    //調用方法,執行SQL,獲取結果集
                    ResultSet rs = pst.executeQuery();
                    while(rs.next()){
                        System.out.println(rs.getString("username")+"   "+rs.getString("password"));
                    }

                    rs.close();
                    pst.close();
                    con.close();
                }
            }

14PrepareStatement接口預編譯SQL語句執行修改

* A: PrepareStatement接口預編譯SQL語句執行修改
    * 案例代碼
/*
             *  使用PrepareStatement接口,實現數據表的更新操作
             */
            public class JDBCDemo {
                public static void main(String[] args) throws Exception{
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);  

                    //拼寫修改的SQL語句,參數採用?佔位
                    String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
                    //調用數據庫連接對象con的方法prepareStatement獲取SQL語句的預編譯對象
                    PreparedStatement pst = con.prepareStatement(sql);
                    //調用pst的方法setXXX設置?佔位
                    pst.setObject(1, "汽車美容");
                    pst.setObject(2, 49988);
                    pst.setObject(3, 7);
                    //調用pst方法執行SQL語句
                    pst.executeUpdate();

                    pst.close();
                    con.close();
                }
            }


###15PrepareStatement接口預編譯SQL語句執行查詢
    * A: PrepareStatement接口預編譯SQL語句執行查詢
        * a: 案例代碼
            /*
             *  PrepareStatement接口實現數據表的查詢操作
             */
            public class JDBCDemo1 {
                public static void main(String[] args) throws Exception{
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql://localhost:3296/mybase";
                    String username="root";
                    String password="123";
                    Connection con = DriverManager.getConnection(url, username, password);  

                    String sql = "SELECT * FROM sort";

                    PreparedStatement pst = con.prepareStatement(sql);

                    //調用pst對象的方法,執行查詢語句,Select
                    ResultSet rs=pst.executeQuery();
                    while(rs.next()){
                        System.out.println(rs.getString("sid")+"  "+rs.getString("sname")+"  "+rs.getString("sprice")+"  "+rs.getString("sdesc"));
                    }
                    rs.close();
                    pst.close();
                    con.close();
                }
            }

16JDBC的工具類和測試

* A: JDBC的工具類和測試
    * a: 案例代碼
    //JDBCUtils工具類代碼
            public class JDBCUtils {
                private JDBCUtils(){}
                private static Connection con ;

                static{
                    try{
                        Class.forName("com.mysql.jdbc.Driver");
                        String url = "jdbc:mysql://localhost:3296/mybase";
                        String username="root";
                        String password="123";
                        con = DriverManager.getConnection(url, username, password);
                    }catch(Exception ex){
                        throw new RuntimeException(ex+"數據庫連接失敗");
                    }
                }

                /*
                 * 定義靜態方法,返回數據庫的連接對象
                 */
                public static Connection getConnection(){
                    return con;
                }


                public static void close(Connection con,Statement stat){

                     if(stat!=null){
                         try{
                             stat.close();
                         }catch(SQLException ex){}
                     }

                     if(con!=null){
                         try{
                             con.close();
                         }catch(SQLException ex){}
                     }

                }


                public static void close(Connection con,Statement stat , ResultSet rs){
                     if(rs!=null){
                         try{
                             rs.close();
                         }catch(SQLException ex){}
                     }

                     if(stat!=null){
                         try{
                             stat.close();
                         }catch(SQLException ex){}
                     }

                     if(con!=null){
                         try{
                             con.close();
                         }catch(SQLException ex){}
                     }

                }
            }
        //測試JDBCUtils工具類的代碼
        public class TestJDBCUtils {
            public static void main(String[] args)throws Exception {
                Connection con = JDBCUtils.getConnection();
                PreparedStatement pst = con.prepareStatement("SELECT sname FROM sort");
                ResultSet rs = pst.executeQuery();
                while(rs.next()){
                    System.out.println(rs.getString("sname"));
                }
                JDBCUtils.close(con, pst, rs);
            }
        }

17數據表數據存儲對象

* A: 數據表數據存儲對象
    * a: 準備工作
        * 導入jar包
        * 拷貝day32定義的工具類JDBCUtils

    * b: 案例代碼
        //定義實體類Sort
public class Sort {
                private int sid;
                private String sname;
                private double sprice;
                private String sdesc;
                public Sort(int sid, String sname, double sprice, String sdesc) {
                    this.sid = sid;
                    this.sname = sname;
                    this.sprice = sprice;
                    this.sdesc = sdesc;
                }
                public Sort(){}
                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;
                }
                public double getSprice() {
                    return sprice;
                }
                public void setSprice(double sprice) {
                    this.sprice = sprice;
                }
                public String getSdesc() {
                    return sdesc;
                }
                public void setSdesc(String sdesc) {
                    this.sdesc = sdesc;
                }
                @Override
                public String toString() {
                    return "Sort [sid=" + sid + ", sname=" + sname + ", sprice=" + sprice + ", sdesc=" + sdesc + "]";
                }               
            }

            /*
             *  JDBC讀取數據表sort,每行數據封裝到Sort類的對象中
             *  很多個Sort類對象,存儲到List集合中
             */
            public class JDBCDemo {
                public static void main(String[] args) throws Exception{
                    //使用JDBC工具類,直接獲取數據庫連接對象
                    Connection con = JDBCUtils.getConnection();
                    //連接獲取數據庫SQL語句執行者對象
                    PreparedStatement pst = con.prepareStatement("SELECT * FROM sort");
                    //調用查詢方法,獲取結果集
                    ResultSet rs = pst.executeQuery();
                    //創建集合對象
                    List<Sort> list = new ArrayList<Sort>();
                    while(rs.next()){
                        //獲取到每個列數據,封裝到Sort對象中
                        Sort s = new Sort(rs.getInt("sid"),rs.getString("sname"),rs.getDouble("sprice"),rs.getString("sdesc"));
                        //封裝的Sort對象,存儲到集合中
                        list.add(s);
                    }
                    JDBCUtils.close(con, pst, rs);
                    //遍歷List集合
                    for(Sort s : list){
                        System.out.println(s);
                    }
                }
            }

18properties配置文件

* A: properties配置文件     
    * a: 相關介紹
        * 開發中獲得連接的4個參數(驅動、URL、用戶名、密碼)通常都存在配置文件中,方便後期維護,程序如果需要更換數據庫,
            只需要修改配置文件即可。
        * 通常情況下,我們習慣使用properties文件,此文件我們將做如下要求:
            1.  文件位置:任意,建議src下
            2.  文件名稱:任意,擴展名爲properties
            3.  文件內容:一行一組數據,格式是“key=value”.
                a)  key命名自定義,如果是多個單詞,習慣使用點分隔。例如:jdbc.driver
                b)  value值不支持中文,如果需要使用非英文字符,將進行unicode轉換。

19properties文件的創建和編寫

* A: properties文件的創建和編寫
    * a: properties文件的創建
        * src路徑下建立database.properties(其實就是一個文本文件)
    * b: properties文件的編寫(內容如下)
        driverClass=com.mysql.jdbc.Driver
        url=jdbc:mysql://localhost:3296/mybase
        username=root
        password=123        

20加載配置文件

* A: 加載配置文件
    * a: 案例代碼       
    /*
             *  加載properties配置文件
             *  IO讀取文件,鍵值對存儲到集合
             *  從集合中以鍵值對方式獲取數據庫的連接信息,完成數據庫的連接
             */
            public class PropertiesDemo {
                public static void main(String[] args) throws Exception{
                    FileInputStream fis = new FileInputStream("database.properties");
                    System.out.println(fis);
                    //使用類的加載器
                    InputStream in = PropertiesDemo.class.getClassLoader().getResourceAsStream("database.properties");
                    System.out.println(in);
                    Properties pro = new Properties();
                    pro.load(in);
                    System.out.println(in);                 
                }
            }




###21通過配置文件連接數據庫
    * A: 通過配置文件連接數據庫
        * a: 案例代碼
            /*
             *  加載properties配置文件
             *  IO讀取文件,鍵值對存儲到集合
             *  從集合中以鍵值對方式獲取數據庫的連接信息,完成數據庫的連接
             */
            public class PropertiesDemo {
                public static void main(String[] args) throws Exception{
                    FileInputStream fis = new FileInputStream("database.properties");
                    System.out.println(fis);
                    //使用類的加載器
                    InputStream in = PropertiesDemo.class.getClassLoader().getResourceAsStream("database.properties");
                    System.out.println(in);
                    Properties pro = new Properties();
                    pro.load(in);
                    //獲取集合中的鍵值對
                    String driverClass=pro.getProperty("driverClass");
                    String url = pro.getProperty("url");
                    String username = pro.getProperty("username");
                    String password = pro.getProperty("password");
                    Class.forName(driverClass);
                    Connection con = DriverManager.getConnection(url, username, password);
                    System.out.println(con);

                }
            }

22讀取配置文件的工具類

* A: 讀取配置文件的工具類
    * a: 案例代碼
        /*
             *  編寫數據庫連接的工具類,JDBC工具類
             *  獲取連接對象採用讀取配置文件方式
             *  讀取文件獲取連接,執行一次,static{}
             */
            public class JDBCUtilsConfig {
                private static Connection con ;
                private static String driverClass;
                private static String url;
                private static String username;
                private static String password;

                static{
                    try{
                        readConfig();
                        Class.forName(driverClass);
                        con = DriverManager.getConnection(url, username, password);
                    }catch(Exception ex){
                        throw new RuntimeException("數據庫連接失敗");
                    }
                }

                private static void readConfig()throws Exception{
                    InputStream in = JDBCUtilsConfig.class.getClassLoader().getResourceAsStream("database.properties");
                     Properties pro = new Properties();
                     pro.load(in);
                     driverClass=pro.getProperty("driverClass");
                     url = pro.getProperty("url");
                     username = pro.getProperty("username");
                     password = pro.getProperty("password");
                }


                public static Connection getConnection(){
                    return con;
                }

            }           

###23測試工具類
    * A: 測試工具類
        * a: 案例代碼
            public class TestJDBCUtils {
                public static void main(String[] args) {
                    Connection con = JDBCUtilsConfig.getConnection();
                    System.out.println(con);
                }
            }

01DButils工具類的介紹個三個核心類

* A: DButils工具類的介紹個三個核心類
    * a: 概述
        * DBUtils是java編程中的數據庫操作實用工具,小巧簡單實用。
        * DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少寫代碼。
        * DBUtils就是JDBC的簡化開發工具包。需要項目導入commons-dbutils-1.6.jar才能夠正常使用DBUtils工具。
    * b: Dbutils三個核心功能介紹
        * QueryRunner中提供對sql語句操作的API.
            * update(Connection conn, String sql, Object... params) ,用來完成表數據的增加、刪除、更新操作
            * query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用來完成表數據的查詢操作
        * ResultSetHandler接口,用於定義select操作後,怎樣封裝結果集.
        * DbUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法

02事務的簡單介紹(此知識點簡單瞭解,難度較大,就業班會詳細 講解)

* A: 事務的簡單介紹
    * a: 見day32/day32_source/事務.jgp

03QueryRunner類的update方法介紹

* A:QueryRunner類的update方法介紹
    * a: 方法介紹
        * update(Connection conn, String sql, Object... params) ,用來完成表數據的增加、刪除、更新操作
        *  使用QueryRunner類,實現對數據表的insert delete update
        *  調用QueryRunner類的方法 update (Connection con,String sql,Object...param)
            *  Object...param 可變參數,Object類型,SQL語句會出現?佔位符
            *  數據庫連接對象,自定義的工具類傳遞

04QueryRunner類實現insert添加數據

* A: QueryRunner類實現insert添加數據
    * a: 案例代碼
public class QueryRunnerDemo {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args)throws SQLException {
                    insert();           
                }               
                /*
                 * 定義方法,使用QueryRunner類的方法update向數據表中,添加數據
                 */
                public static void insert()throws SQLException{
                    //創建QueryRunner類對象
                    QueryRunner qr = new QueryRunner();
                    String sql = "INSERT INTO sort (sname,sprice,sdesc)VALUES(?,?,?)";
                    //將三個?佔位符的實際參數,寫在數組中
                    Object[] params = {"體育用品",289.32,"購買體育用品"};
                    //調用QueryRunner類的方法update執行SQL語句
                    int row = qr.update(con, sql, params);
                    System.out.println(row);
                    DbUtils.closeQuietly(con);
                }
            }

05QueryRunner類實現update修改數據

* A: QueryRunner類實現update修改數據
    * a: 案例代碼
public class QueryRunnerDemo {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args)throws SQLException {
                    update();
                }               
                /*
                 *  定義方法,使用QueryRunner類的方法update將數據表的數據修改
                 */
                public static void update()throws SQLException{
                    //創建QueryRunner類對象
                    QueryRunner qr = new QueryRunner(); 
                    //寫修改數據的SQL語句
                    String sql = "UPDATE sort SET sname=?,sprice=?,sdesc=? WHERE sid=?";
                    //定義Object數組,存儲?中的參數
                    Object[] params = {"花卉",100.88,"情人節玫瑰花",4};
                    //調用QueryRunner方法update
                    int row = qr.update(con, sql, params);
                    System.out.println(row);
                    DbUtils.closeQuietly(con);
                }               
            }

06QueryRunner類實現delete刪除數據

* A: QueryRunner類實現delete刪除數據
    * a: 案例代碼
public class QueryRunnerDemo {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args)throws SQLException {
                    delete();
                }
                /*
                 *  定義方法,使用QueryRunner類的方法delete將數據表的數據刪除
                 */
                public static void delete()throws SQLException{
                    //創建QueryRunner類對象
                    QueryRunner qr = new QueryRunner(); 
                    //寫刪除的SQL語句
                    String sql = "DELETE FROM sort WHERE sid=?";
                    //調用QueryRunner方法update
                    int row = qr.update(con, sql, 8);
                    System.out.println(row);
                    /*
                     *  判斷insert,update,delete執行是否成功
                     *  對返回值row判斷
                     *  if(row>0) 執行成功
                     */
                    DbUtils.closeQuietly(con);
                }               
            }

07JavaBean類

* A: JavaBean類
    * a: 概念
        * JavaBean就是一個類,在開發中常用封裝數據。具有如下特性
            1.  需要實現接口:java.io.Serializable ,通常實現接口這步驟省略了,不會影響程序。
            2.  提供私有字段:private 類型 字段名;
            3.  提供getter/setter方法:
            4.  提供無參構造

08DBUtils工具類結果集處理的方式

* A: DBUtils工具類結果集處理的方式
    * a: QueryRunner實現查詢操作
        *   query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用來完成表數據的查詢操作
    * b: ResultSetHandler結果集處理類
        * ArrayHandler  將結果集中的第一條記錄封裝到一個Object[]數組中,數組中的每一個元素就是這條記錄中的每一個字段的值
        * ArrayListHandler  將結果集中的每一條記錄都封裝到一個Object[]數組中,將這些數組在封裝到List集合中。
        * BeanHandler   將結果集中第一條記錄封裝到一個指定的javaBean中。
        * BeanListHandler   將結果集中每一條記錄封裝到指定的javaBean中,將這些javaBean在封裝到List集合中
        * ColumnListHandler 將結果集中指定的列的字段值,封裝到一個List集合中
        * ScalarHandler 它是用於單數據。例如select count(*) from 表操作。
        * MapHandler    將結果集第一行封裝到Map集合中,Key 列名, Value 該列數據
        * MapListHandler    將結果集第一行封裝到Map集合中,Key 列名, Value 該列數據,Map集合存儲到List集合

09QueryRunner類的方法query

* A: QueryRunner類的方法query
    * a: QueryRunner數據查詢操作
        * 調用QueryRunner類方法query(Connection con,String sql,ResultSetHandler r, Object..params)
        *  ResultSetHandler r 結果集的處理方式,傳遞ResultSetHandler接口實現類
        *  Object..params SQL語句中的?佔位符
        *  注意: query方法返回值,返回的是T 泛型, 具體返回值類型,跟隨結果集處理方式變化
    * b: 案例代碼
        public class QueryRunnerDemo1 {
            private static Connection con = JDBCUtilsConfig.getConnection();
        }

10結果集處理ArrayHandler

* A: 結果集處理ArrayHandler
    * 案例代碼
public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    arrayHandler();
                }   
                /*
                 *  結果集第一種處理方法, ArrayHandler
                 *  將結果集的第一行存儲到對象數組中  Object[]
                 */
                public static void arrayHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT * FROM sort";
                    //調用方法query執行查詢,傳遞連接對象,SQL語句,結果集處理方式的實現類
                    //返回對象數組
                    Object[] result = qr.query(con, sql, new ArrayHandler());
                    for(Object obj : result){
                        System.out.print(obj);
                    }
                }   
            }

11結果集處理ArrayListHandler

* A: 結果集處理ArrayListHandler
    * a: 案例代碼
public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    arrayListHandler();
                }
                /*
                 *  結果集第二種處理方法,ArrayListHandler
                 *  將結果集的每一行,封裝到對象數組中, 出現很多對象數組
                 *  對象數組存儲到List集合
                 */
                public static void arrayListHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT * FROM sort";      
                    //調用query方法,結果集處理的參數上,傳遞實現類ArrayListHandler
                    //方法返回值 每行是一個對象數組,存儲到List
                    List<Object[]> result=  qr.query(con, sql, new ArrayListHandler());

                    //集合的遍歷
                    for( Object[] objs  : result){
                        //遍歷對象數組
                        for(Object obj : objs){
                            System.out.print(obj+"  ");
                        }
                        System.out.println();
                    }
                }
            }

12結果集處理BeanHandler

* A: 結果集處理BeanHandler
    * a: 案例代碼
public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    beanHandler();
                }
                /*
                 *  結果集第三種處理方法,BeanHandler
                 *  將結果集的第一行數據,封裝成JavaBean對象
                 *  注意: 被封裝成數據到JavaBean對象, Sort類必須有空參數構造
                 */
                public static void beanHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT * FROM sort ";
                    //調用方法,傳遞結果集實現類BeanHandler
                    //BeanHandler(Class<T> type) 
                    Sort s = qr.query(con, sql, new BeanHandler<Sort>(Sort.class));
                    System.out.println(s);
                }
            }

13結果集處理BeanListHandler

* A: 結果集處理BeanListHandler
    * a: 案例代碼
public class QueryRunnerDemo1 {
            private static Connection con = JDBCUtilsConfig.getConnection();
            public static void main(String[] args) throws SQLException{
                beanListHander();
            }
            /*
             *  結果集第四種處理方法, BeanListHandler
             *  結果集每一行數據,封裝JavaBean對象
             *  多個JavaBean對象,存儲到List集合
             */
            public static void beanListHander()throws SQLException{
                QueryRunner qr = new QueryRunner();
                String sql = "SELECT * FROM sort ";
                //調用方法query,傳遞結果集處理實現類BeanListHandler
                List<Sort> list = qr.query(con, sql, new BeanListHandler<Sort>(Sort.class));
                for(Sort s : list){
                    System.out.println(s);
                }
            }
        }


###14結果集處理ColumnListHandler
    * A: 結果集處理ColumnListHandler
        * a: 案例代碼
            public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    columnListHandler();
                }   
                /*
                 *  結果集第五種處理方法,ColumnListHandler
                 *  結果集,指定列的數據,存儲到List集合
                 *  List<Object> 每個列數據類型不同
                 */
                public static void columnListHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT * FROM sort ";     
                    //調用方法 query,傳遞結果集實現類ColumnListHandler
                    //實現類構造方法中,使用字符串的列名
                    List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("sname"));
                    for(Object obj : list){
                        System.out.println(obj);
                    }
                }   
            }

15結果集處理ScalarHandler

* A: 結果集處理ScalarHandler
    * a: 案例代碼
public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    scalarHandler();
                }   
                /*
                 *  結果集第六種處理方法,ScalarHandler
                 *  對於查詢後,只有1個結果
                 */
                public static void scalarHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT COUNT(*) FROM sort";
                    //調用方法query,傳遞結果集處理實現類ScalarHandler
                    long count = qr.query(con, sql, new ScalarHandler<Long>());
                    System.out.println(count);
                }
            }

16結果集處理MapHandler

* A: 結果集處理MapHandler
    * a: 案例代碼
public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    mapHandler();
                }
                /*
                 *  結果集第七種處理方法,MapHandler
                 *  將結果集第一行數據,封裝到Map集合中
                 *  Map<鍵,值> 鍵:列名  值:這列的數據
                 */
                public static void mapHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT  * FROM sort";
                    //調用方法query,傳遞結果集實現類MapHandler
                    //返回值: Map集合,Map接口實現類, 泛型
                    Map<String,Object> map = qr.query(con, sql, new MapHandler());
                    //遍歷Map集合
                    for(String key : map.keySet()){
                        System.out.println(key+".."+map.get(key));
                    }
                }
            }

###17結果集處理MapListHandler
    * A: 結果集處理MapListHandlerr
        * a: 案例代碼
            public class QueryRunnerDemo1 {
                private static Connection con = JDBCUtilsConfig.getConnection();
                public static void main(String[] args) throws SQLException{
                    mapListHandler();
                }
                /*
                 *  結果集第八種處理方法,MapListHandler
                 *  將結果集每一行存儲到Map集合,鍵:列名,值:數據
                 *  Map集合過多,存儲到List集合
                 */
                public static void mapListHandler()throws SQLException{
                    QueryRunner qr = new QueryRunner();
                    String sql = "SELECT  * FROM sort";
                    //調用方法query,傳遞結果集實現類MapListHandler
                    //返回值List集合, 存儲的是Map集合
                    List<Map<String,Object>> list = qr.query(con, sql, new MapListHandler());
                    //遍歷集合list
                    for( Map<String,Object> map : list ){
                        for(String key : map.keySet()){
                            System.out.print(key+"..."+map.get(key));
                        }
                        System.out.println();
                    }

                }
            }

18連接池介紹

* A: 連接池介紹
    * a: 連接池介紹
        * 實際上就是存放連接的池子(容器)
        * 在開發中“獲得連接”或“釋放資源”是非常消耗系統資源的兩個過程
        * 爲了解決此類性能問題,通常情況我們採用連接池技術,來共享連接Connection。
        * 這樣我們就不需要每次都創建連接、釋放連接了,這些操作都交給了連接池         

19連接池概念規範和DataSource接口

* A: 連接池概念規範和DataSource接口   
    * a: 連接池概念規範
        * 用池來管理Connection,這樣可以重複使用Connection。
        * 不用自己來創建Connection,而是通過池來獲取Connection對象
        * 使用完Connection後,調用Connection的close()方法也不會真的關閉Connection,而是把Connection“歸還”給池
        * 連接池技術可以完成Connection對象的再次利用
    * b: DataSource接口
        * Java爲數據庫連接池提供了公共的接口:javax.sql.DataSource
        * 各個廠商需要讓自己的連接池實現這個接口。這樣應用程序可以方便的切換不同廠商的連接池
        * 常見的連接池:DBCP、C3P0

20DBCP連接池介紹

* A: DBCP連接池介紹
    * a: DBCP連接池介紹
        * DBCP也是一個開源的連接池,是Apache Common成員之一,在企業開發中也比較常見,tomcat內置的連接池
    * tomcat服務器簡單介紹 

21導入jar包

* A: 導入jar包
    * a: jar包介紹 
        * mysql-connector-java-5.1.37-bin.jar:數據庫驅動
        * commons-dbutils-1.6.jar:提供QueryRunner類方便進行增刪改查操作
        * commons-dbcp-1.4.jar:
        * commons-pool-1.5.6.jar:提供高效的數據庫連接池技術
    * b: 導入jar包
        * 在項目根路徑下建立文件夾lib
        * 拷貝以上jar包,選定拷貝的jar包/右鍵/Build Path/Add to Build Path

22BasicDataSource類的使用

* A: BasicDataSource類的使用
    * a: 案例代碼
    /*
             *  連接池jar包中,定義好一個類 BasicDataSource
             *  實現類數據源的規範接口 javax.sql.DataSource
             */
            public class DataSoruceDemo {
                public static void main(String[] args) {
                    //創建DataSource接口的實現類對象
                    //實現類, org.apache.commons.dbcp
                    BasicDataSource dataSource = new BasicDataSource();
                    //連接數據庫的4個最基本信息,通過對象方法setXXX設置進來
                    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
                    dataSource.setUrl("jdbc:mysql://localhost:3306/mybase");
                    dataSource.setUsername("root");
                    dataSource.setPassword("123");

                    try{
                    //調用對象方法getConnection獲取數據庫的連接
                        Connection con = dataSource.getConnection();
                        System.out.println(con);
                    }catch(SQLException ex){
            //          System.out.println(ex);
                        ex.printStackTrace();
                        throw new RuntimeException("數據庫連接失敗");
                    }
                }
            }

23BasicDataSource類的常見配置

* A: BasicDataSource類的常見配置
    * a: 常見配置
        分類  屬性          描述
        必須項 
                driverClassName 數據庫驅動名稱
                url             數據庫的地址
                username        用戶名
                password        密碼
        基本項(擴展) 
                maxActive       最大連接數量
                minIdle         最小空閒連接
                maxIdle         最大空閒連接
                initialSize     初始化連接

24實現數據庫連接池工具類

* A: 實現數據庫連接池工具類
    * a: 案例代碼
/*
             *  使用DBCP實現數據庫的連接池
             *  連接池配置,自定義類,
             *  最基本四項完整
             *  對於數據庫連接池其他配置,自定義
             */

            import javax.sql.DataSource;

            import org.apache.commons.dbcp.BasicDataSource;
            public class JDBCUtils{
                //創建出BasicDataSource類對象
                private static BasicDataSource datasource = new BasicDataSource();

                //靜態代碼塊,對象BasicDataSource對象中的配置,自定義
                static{
                    //數據庫連接信息,必須的
                    datasource.setDriverClassName("com.mysql.jdbc.Driver");
                    datasource.setUrl("jdbc:mysql://localhost:3306/day33_user");
                    datasource.setUsername("root");
                    datasource.setPassword("123");
                    //對象連接池中的連接數量配置,可選的
                    datasource.setInitialSize(10);//初始化的連接數
                    datasource.setMaxActive(8);//最大連接數量
                    datasource.setMaxIdle(5);//最大空閒數
                    datasource.setMinIdle(1);//最小空閒
                }


                //定義靜態方法,返回BasicDataSource類的對象
                public static DataSource getDataSource(){
                    return datasource;
                }
            }

25工具類的測試

* A: 工具類的測試
    * a: 案例代碼
    /*
             *  測試寫好的工具類,
             *  提供的是一個DataSource接口的數據源
             *  QueryRunner類構造方法,接收DataSource接口的實現類
             *  後面,調用方法update,query,無需傳遞他們Connection連接對象
             */

            import java.sql.SQLException;
            import java.util.List;

            import org.apache.commons.dbutils.QueryRunner;
            import org.apache.commons.dbutils.handlers.ArrayListHandler;

            import cn.itcast.jdbcutils.JDBCUtils;
            public class QueryRunnerDemo{
                public static void main(String[] args) {
                    select();
                }
                //定義2個方法,實現數據表的添加,數據表查詢
                //QueryRunner類對象,寫在類成員位置
                private static QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); 

                //數據表查詢
                public static void select(){
                    String sql = "SELECT * FROM sort";
                    try{
                    List<Object[]> list = qr.query(sql, new ArrayListHandler());
                    for(Object[] objs : list){
                        for(Object obj : objs){
                            System.out.print(obj+"\t");
                        }
                        System.out.println();
                    }
                    }catch(SQLException ex){
                        throw new RuntimeException("數據查詢失敗");
                    }
                }

                //數據表添加數據
                public static void insert(){
                    String sql = "INSERT INTO sort (sname,sprice,sdesc)VALUES(?,?,?)";
                    Object[] params = {"水果",100.12,"剛剛上市的核桃"};
                    try{
                        int row = qr.update(sql, params);
                        System.out.println(row);
                    }catch(SQLException ex){
                        throw new RuntimeException("數據添加失敗");
                    }
                }

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