国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

JDBC的擴展知識點(diǎn)總結

發(fā)布時(shí)間:2021-07-17 21:51 來(lái)源:腳本之家 閱讀:0 作者:GaryLea 欄目: 編程語(yǔ)言

目錄

    一、數據庫的事務(wù)

    1.1 事務(wù)概述

    • 事務(wù):一組邏輯操作單元,使數據從一種狀態(tài)變換到另一種狀態(tài)
    • 事務(wù)處理(事務(wù)操作):保證所有事務(wù)都作為一個(gè)工作單元來(lái)執行,即使出現了故障,都不能改變這種執行方式。當在一個(gè)事務(wù)中執行多個(gè)操作時(shí),要么所有的事務(wù)都被提交(commit),那么這些修改就永久地保存下來(lái);要么數據庫管理系統將放棄所作的所有修改,整個(gè)事務(wù)回滾(rollback)到最初狀態(tài)
    • 為確保數據庫中數據的一致性,數據的操縱應當是離散的成組的邏輯單元:當它全部完成時(shí),數據的一致性可以保持,而當這個(gè)單元中的一部分操作失敗,整個(gè)事務(wù)應全部視為錯誤,所有從起始點(diǎn)以后的操作應全部回退到開(kāi)始狀態(tài)
    • 舉個(gè)栗子,當小明給小紅轉賬時(shí),因為種種原因沒(méi)有轉賬成功,小明的錢(qián)減少了,小紅卻沒(méi)有收到錢(qián),此時(shí)就需要事務(wù)回滾,否則小明就得哭死…

    1.2 事務(wù)的屬性

    事務(wù)的ACID(acid)屬性

    • 原子性(Atomicity)
    • 原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
    • 一致性(Consistency)
    • 事務(wù)必須使數據庫從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。
    • 隔離性(Isolation)
    • 事務(wù)的隔離性是指一個(gè)事務(wù)的執行不能被其他事務(wù)干擾,即一個(gè)事務(wù)內部的操作及使用的數據對并發(fā)的其他事務(wù)是隔離的,并發(fā)執行的各個(gè)事務(wù)之間不能互相干擾。
    • 持久性(Durability)
    • 持久性是指一個(gè)事務(wù)一旦被提交,它對數據庫中數據的改變就是永久性的,接下來(lái)的其他操作和數據庫故障不應該對其有任何影響

    1.3 JDBC事務(wù)處理

    當一個(gè)連接對象被創(chuàng )建時(shí),默認情況下是自動(dòng)提交事務(wù):每次執行一個(gè) SQL 語(yǔ)句時(shí),如果執行成功,就會(huì )向數據庫自動(dòng)提交,而不能回滾

    為了讓多個(gè) SQL 語(yǔ)句作為一個(gè)事務(wù)執行:

    1. 調用 Connection 對象的 setAutoCommit(false); 以取消自動(dòng)提交事務(wù)

    2.在所有的 SQL 語(yǔ)句都成功執行后,調用 commit(); 方法提交事務(wù)

    3.在出現異常時(shí),調用 rollback(); 方法回滾事務(wù)

    4.若此時(shí) Connection 沒(méi)有被關(guān)閉, 則需要恢復其自動(dòng)提交狀態(tài)

    1.4 數據庫事務(wù)使用的過(guò)程

    使用數據庫的事務(wù),我們需要配合異常處理try

    public void testJDBCTransaction() {
    Connection conn = null;
    try {
    // 1.獲取數據庫連接
    conn = JDBCUtils.getConnection();
    // 2.開(kāi)啟事務(wù)
    conn.setAutoCommit(false);
    // 3.進(jìn)行數據庫操作
    
    // 4.若沒(méi)有異常,則提交事務(wù)
    conn.commit();
    } catch (Exception e) {
    e.printStackTrace();
    // 5.若有異常,則回滾事務(wù)
    try {
    conn.rollback();
    } catch (SQLException e1) {
    e1.printStackTrace();
    }} finally {
    JDBCUtils.close(null, null, conn); }  }
    

    1.5 使用數據庫事務(wù)的好處

    使用COMMIT 和 ROLLBACK語(yǔ)句,我們可以:

    • 確保數據完整性。
    • 數據改變被提交之前預覽。
    • 將邏輯上相關(guān)的操作分組

    提交或回滾前的數據狀態(tài)

    • 改變前的數據狀態(tài)是可以恢復的
    • 執行 DML 操作的用戶(hù)可以通過(guò) SELECT 語(yǔ)句查詢(xún)提交或回滾之前的修正
    • 其他用戶(hù)不能看到當前用戶(hù)所做的改變,直到當前用戶(hù)結束事務(wù)。
    • DML語(yǔ)句所涉及到的行被鎖定, 其他用戶(hù)不能操作

    提交后的數據狀態(tài)

    • 數據的改變已經(jīng)被保存到數據庫中。
    • 改變前的數據已經(jīng)丟失。
    • 所有用戶(hù)可以看到結果。
    • 鎖被釋放, 其他用戶(hù)可以操作涉及到的數據

    說(shuō)了這么多,還是使用代碼來(lái)舉例說(shuō)明更加清晰(數據庫連接的JDBCUtils類(lèi)上一章寫(xiě)過(guò)了):

    package com.company.jdbcDemo;
    
    import com.company.jdbcDemo.JDBCUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    /*
        AA給CC轉賬1000
        AA 2000
        CC 2000
    
            try{
               開(kāi)啟事務(wù)
               AA -= 1000
               System.out.println(1/0);
               CC += 1000
               提交(一旦提交數據不能再回滾(撤銷(xiāo)))
            }catch(Exception e){
            事務(wù)回滾(撤銷(xiāo))
            }
    
        CREATE TABLE account(
        NAME VARCHAR(20),
        balance INT
        )
    
     */
    public class AccountDemo {
    
        public static void main(String[] args) throws SQLException {
            //1.獲取數據庫連接對象
            Connection connection = JDBCUtils.getConnection();
            PreparedStatement ps = null;
            try {
                //2.開(kāi)啟事物--禁止自動(dòng)提交
                connection.setAutoCommit(false);
                //-------------------------------------------------------------------
                //3.做具體的操作---執行sql語(yǔ)句
                //預編譯
                String sql = "update account set balance=? where name=?";
                ps = connection.prepareStatement(sql);
    
                //給占位符賦值
                ps.setInt(1, 1000);
                ps.setString(2, "aa");
                //執行sql
                ps.executeUpdate();
    
                System.out.println(1 / 0);
    
                //給占位符賦值
                ps.setInt(1, 3000);
                ps.setString(2, "cc");
                //執行sql
                ps.executeUpdate();
                //-------------------------------------------------------------------
                //4.事務(wù)提交
                connection.commit();
            }catch (Exception e){
                e.printStackTrace();
                //5.事務(wù)回滾
                connection.rollback();
            }finally {
                //6.允許自動(dòng)提交
                connection.setAutoCommit(true);
                //7.關(guān)閉資源----最后關(guān)閉資源
                JDBCUtils.close(ps,connection);
    
            }
        }
    }
    

    二、數據庫連接池

    概述

    前面我們的示例代碼中,一直在調用我寫(xiě)的那個(gè)JDBCUtils類(lèi)來(lái)完成數據庫的連接,如果我們在別的工程中,就需要復制一下我的那個(gè)類(lèi),并且我寫(xiě)的那個(gè)也不是很?chē)乐?我前面實(shí)現的數據庫連接方式存在以下問(wèn)題:

    •  普通的JDBC數據庫連接使用 DriverManager 來(lái)獲取,每次向數據庫建立連接的時(shí)候都要將 Connection 加載到內存中,再驗證用戶(hù)名和密碼
    • 數據庫的連接資源并沒(méi)有得到很好的重復利用.若同時(shí)有幾百人甚至幾千人在線(xiàn),頻繁的進(jìn)行數據庫連接操作將占用很多的系統資源,嚴重的甚至會(huì )造成服務(wù)器的崩潰
    • 對于每一次數據庫連接,使用完后都得斷開(kāi)。否則,如果程序出現異常而未能關(guān)閉,將會(huì )導致數據庫系統中的內存泄漏,最終將導致重啟數據庫
    • 這種開(kāi)發(fā)不能控制被創(chuàng )建的連接對象數,系統資源會(huì )被毫無(wú)顧及的分配出去,如連接過(guò)多,也可能導致內存泄漏,服務(wù)器崩潰

    使用數據庫連接池

    • 數據庫連接池的基本思想就是為數據庫連接建立一個(gè)“緩沖池”。預先在緩沖池中放入一定數量的連接,當需要建立數據庫連接時(shí),只需從“緩沖池”中取出一個(gè),使用完畢之后再放回去
    • 數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個(gè)現有的數據庫連接,而不是重新建立一個(gè)
    • 數據庫連接池在初始化時(shí)將創(chuàng )建一定數量的數據庫連接放到連接池中,這些數據庫連接的數量是由最小數據庫連接數來(lái)設定的。無(wú)論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。連接池的最大數據庫連接數量限定了這個(gè)連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過(guò)最大連接數量時(shí),這些請求將被加入到等待隊列中

    2.1 數據庫連接池技術(shù)的優(yōu)點(diǎn)

    • 資源重用
    • 由于數據庫連接得以重用,避免了頻繁創(chuàng )建,釋放連接引起的大量性能開(kāi)銷(xiāo)。在減少系統消耗的基礎上,另一方面也增加了系統運行環(huán)境的平穩性。
    • 更快的系統反應速度
    • 數據庫連接池在初始化過(guò)程中,往往已經(jīng)創(chuàng )建了若干數據庫連接置于連接池中備用。此時(shí)連接的初始化工作均已完成。對于業(yè)務(wù)請求處理而言,直接利用現有可用連接,避免了數據庫連接初始化和釋放過(guò)程的時(shí)間開(kāi)銷(xiāo),從而減少了系統的響應時(shí)間
    • 新的資源分配手段
    • 對于多應用共享同一數據庫的系統而言,可在應用層通過(guò)數據庫連接池的配置,實(shí)現某一應用最大可用數據庫連接數的限制,避免某一應用獨占所有的數據庫資源
    • 統一的連接管理,避免數據庫連接泄露
    • 在較為完善的數據庫連接池實(shí)現中,可根據預先的占用超時(shí)設定,強制回收被占用連接,從而避免了常規數據庫連接操作中可能出現的資源泄露

    三、DRUID(德魯伊)

    • 了解了數據庫連接池以及優(yōu)勢,接下來(lái)我為大家帶來(lái)一個(gè)目前常用的一個(gè)數據庫連接池框架—>德魯伊
    • DRUID是阿里巴巴開(kāi)源平臺上一個(gè)數據庫連接池實(shí)現,它結合了C3P0、DBCP、PROXOOL等DB池的優(yōu)點(diǎn),同時(shí)加入了日志監控,可以很好的監控DB池連接和SQL的執行情況,可以說(shuō)是針對監控而生的DB連接池,據說(shuō)是目前最好的連接池

    3.1 德魯伊的使用

    阿里德魯伊連接池技術(shù)首先分為兩步:

    1.加入jar包

    例如:druid-1.1.10.jar

    2.代碼步驟

    第一步:建立一個(gè)數據庫連接池

    第二步:設置連接池的參數

    第三步:獲取連接

    使用德魯伊連接數據庫的方式一

    //1、創(chuàng  )建數據源(數據庫連接池)對象
    DruidDataSource ds =new DruidDataSource();
    //2、設置參數
    //(1)設置基本參數
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/test");
    ds.setUsername("root");
    ds.setPassword("mysql123");
    //3、獲取連接
    Connection conn = ds.getConnection();
    //如果這里沒(méi)有關(guān)閉,就相當于沒(méi)有還
    conn.close();
    

    使用德魯伊連接數據庫的方式二

    // 創(chuàng  )建配置文件druid.properties
    url=jdbc:mysql://localhost:3306/0319db ?rewriteBatchedStatements=true
    username=root
    password=123456
    driverClassName=com.mysql.jdbc.Driver
    
    代碼如下:
    Properties pro = new Properties();
    pro.load(TestDruid2.class.getClassLoader().getResourceAsStream("druid.properties"));
    DataSource ds=
    		DruidDataSourceFactory.createDataSource(pro);
    Connection conn = ds.getConnection();
    

    這里注意了,德魯伊配置文件中的key,必須跟我下面一樣,否則連接不成功哦

    // druid.properties內容
    url=jdbc:mysql://localhost:3306/demo
    username=root
    password=123321
    driverClassName=com.mysql.jdbc.Driver

    四、DBUtils工具類(lèi)

    • 既然數據庫連接有了數據庫連接池這么方便地操作,那么對數據的增刪改查有沒(méi)有相關(guān)的方法呢?當然有,它就是DBUtils
    • 將常用的操作數據庫的JDBC的類(lèi)和方法集合在一起,就是DBUtils.
    • 這個(gè)比較簡(jiǎn)單,我就介紹一下常用的API操作,具體的知識點(diǎn),可以查看Java的API文檔

    我就直接上操作了,這里還是使用我前面實(shí)現的那個(gè)JDBCUtils類(lèi)哈,偷個(gè)懶…

    package com.company.jdbc2;
    
    import com.company.jdbc.JDBCUtils;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.junit.Test;
    
    import java.sql.SQLException;
    import java.util.List;
    
    /*
        通過(guò)使用DBUtils工具類(lèi)實(shí)現增,刪,改,查的操作
     */
    public class DBUtilsDemo {
    
        @Test
        public void test() throws SQLException {
            //1.創(chuàng  )建操作對象
            QueryRunner queryRunner = new QueryRunner();
            //2.增,刪,改是一個(gè)方法
            /*
                update(Connection conn, String sql, Object param)
                conn : 連接對象
                sql : sql語(yǔ)句
                param : 給占位符賦值的內容
             */
            String sql = "insert into student(sid,sname,sage) values(?,?,?)";
            //返回值 :有幾條數據受到影響
            int i = queryRunner.update(JDBCUtils.getConnection(),
                    sql, 10, "kongkong", 18);
            System.out.println("有" + i + "條數據受到影響");
        }
    
        @Test
        public void test2() throws SQLException {
            QueryRunner queryRunner = new QueryRunner();
            /*
            query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
            conn : 連接對象
            sql : sql語(yǔ)句
    
             */
            String sql = "select sid a,sname,sage from student where sid=?";
            //注意:類(lèi)中的屬性名一定要和字段名相同。如果不相同則需要在sql語(yǔ)句中使用別名
    //        Student student = queryRunner.query(JDBCUtils.getConnection(), sql,
    //                new BeanHandler<Student>(Student.class), 10);
    
    
    
    
            sql = "select sid a,sname,sage from student";
            List<Student> list = queryRunner.query(JDBCUtils.getConnection(), sql,
                    new BeanListHandler<Student>(Student.class));
    
           for (Student s : list) {
               System.out.println(s);
           }
        }
    
    }
    

    使用批處理

    當我們需要對進(jìn)行大批量的數據操作時(shí),可以采用批處理技術(shù),很簡(jiǎn)單,在url中添加批處理的參數

    jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true

    示例代碼,(咳咳,依舊是我那個(gè)JDBCUtils實(shí)現連接的工具類(lèi)…)

    package com.company.jdbc3;
    
    import com.company.jdbc.JDBCUtils;
    import org.junit.Test;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    /*
        批處理:
     */
    public class BatchDemo {
    
        /*
            使用批處理:
                1.mysql驅動(dòng)包的版本必須為5.1.3x  才支持批處理
                2.在url連接中添加如下參數
                        jdbc:mysql://localhost:3306/Demo?rewriteBatchedStatements=true
                3.使用一些API:
                    //添加到批處理中
                    ps.addBatch();
                    //執行批處理
                    ps.executeBatch();
                    //清空批處理
                    ps.clearBatch();
         */
        @Test
        public void test2() throws SQLException {
            //1.獲取數據庫連接
            Connection connection = JDBCUtils.getConnection();
            //2.預編譯
            PreparedStatement ps = connection.prepareStatement(
                    "insert into student(sid,sname,sage) values(?,?,?)");
            //3.給占位符賦值
            for (int i = 1; i <= 100000 ; i++) {
                ps.setInt(1,i);
                ps.setString(2,"aaa"+i);
                ps.setInt(3,i);
                //添加到批處理中
                ps.addBatch();
    
                if (i % 1000 == 0){
                    //執行sql
                    ps.executeBatch();//執行批處理
                    //清空批處理
                    ps.clearBatch();
                }
    
            }
            //4.關(guān)資源
            JDBCUtils.close(ps,connection);
        }
    
        @Test
        public void test() throws SQLException {
            //1.獲取數據庫連接
            Connection connection = JDBCUtils.getConnection();
            //2.預編譯
            PreparedStatement ps = connection.prepareStatement(
                    "insert into student(sid,sname,sage) values(?,?,?)");
            //3.給占位符賦值
            for (int i = 1; i <= 100000 ; i++) {
                ps.setInt(1,i);
                ps.setString(2,"aaa"+i);
                ps.setInt(3,i);
                //執行sql
                ps.executeUpdate();
            }
            //4.關(guān)資源
            JDBCUtils.close(ps,connection);
        }
    }
    
    

    到此這篇關(guān)于JDBC的擴展知識點(diǎn)總結的文章就介紹到這了,更多相關(guān)JDBC知識點(diǎn)內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

    欧美综合自拍亚洲综合图| 天天爽亚洲中文字幕| 欧美综合婷婷欧美综合五月| 国产偷亚洲偷欧美偷精品| 少妇一晚三次一区二区三区| 卫生间被教官做好爽HH视频|