20.JDBC開發(fā)(3)事務(wù)和池(我的JavaEE筆記)

主要內(nèi)容:

  • 事務(wù)
  • 使用數(shù)據(jù)庫連接池優(yōu)化程序性能

一蛋褥、事務(wù)的概念

事務(wù)指邏輯上的一組操作彼宠,組成這組操作的各個(gè)單元,要不全部成功诗力,要不全部不成功凰浮。數(shù)據(jù)庫開啟事務(wù)命令:

  • start transaction 開啟事務(wù)
  • rollback 回滾事務(wù)
  • commit 提交事務(wù)

當(dāng)我們開啟事務(wù)后,可輸入多條sql語句讓數(shù)據(jù)庫執(zhí)行苇本,但是如果我們在讓sql語句執(zhí)行之后最后沒有使用commit提交事務(wù)袜茧,則前面執(zhí)行的所有sql語句無效,這就相當(dāng)于回到了開啟事務(wù)之前的狀態(tài)瓣窄,當(dāng)然有時(shí)候這種方式并不太好惫周,我們可以自己設(shè)置回滾點(diǎn),當(dāng)我們sql語句出錯(cuò)時(shí)可以回到設(shè)置的那個(gè)點(diǎn)處的狀態(tài)康栈。而rollback可以每次回滾一條語句。

二喷橙、使用事務(wù)

  • 當(dāng)jdbc程序向數(shù)據(jù)庫獲得一個(gè)Connection對象時(shí)啥么,默認(rèn)情況下這個(gè)Connection對象會(huì)自動(dòng)向數(shù)據(jù)庫提交在它前面發(fā)送的sql語句。若向關(guān)閉這種默認(rèn)提交方式贰逾,讓多條sql在一個(gè)事務(wù)中執(zhí)行悬荣,可使用下列語句:
    jdbc控制事務(wù)語句
    connection.setAutoCommit(false); start transaction
    connection.rollback(); rollback
    connection.commit(); commit
    設(shè)置事務(wù)回滾點(diǎn)
    Savepoint sp = conn.setSavepoint();
    conn.rollback(sp);
    conn.commit(); //回滾后必須要提交

例:
創(chuàng)建數(shù)據(jù)庫:

create database day16;
CREATE TABLE account(
        id INT PRIMARY KEY AUTO_INCREMENT,
        NAME VARCHAR(40),
        money FLOAT
)CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO account(NAME,money) VALUES('aaa',1000);
INSERT INTO account(NAME,money) VALUES('bbb',1000);
INSERT INTO account(NAME,money) VALUES('ccc',1000);

Demo1.java

package cn.itcast.demo;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import cn.itcast.utils.JdbcUtils;

public class Demo1 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement  ps = null;
        ResultSet result = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql1 = "update account set money=money-100 where name='aaa'";
            String sql2 = "update account set money=money+100 where name='bbb'";
            conn.setAutoCommit(false);//開啟事務(wù)
            ps = conn.prepareStatement(sql1);
            ps.executeUpdate();
            //int x = 1/0;//模擬異常,sql語句不會(huì)執(zhí)行
            ps = conn.prepareStatement(sql2);
            ps.executeUpdate();
            System.out.println("ok");
        } catch (Exception e) {
            try {
                conn.rollback();//手動(dòng)通知數(shù)據(jù)庫手動(dòng)回滾
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally{
            JdbcUtils.release(conn, ps, result);
        }
    }
}

例:設(shè)置回滾點(diǎn)
Demo2.java

package cn.itcast.demo;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import cn.itcast.utils.JdbcUtils;

public class Demo2 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        Savepoint point = null;
        try{
            conn = JdbcUtils.getConnection();
            String sql1 = "update account set money = money - 100 where name = 'aaa'";
            String sql2 = "update account set money = money + 100 where name = 'bbb'";
            String sql3 = "update account set money = money + 100 where name = 'ccc'";
            conn.setAutoCommit(false);
            ps = conn.prepareStatement(sql1);
            ps.executeUpdate();
            
            point = conn.setSavepoint();//設(shè)置回滾點(diǎn)
            
            ps = conn.prepareStatement(sql2);
            ps.executeUpdate();
            
            //int x = 1/0;
            
            ps = conn.prepareStatement(sql3);
            ps.executeUpdate();
            
            conn.commit();
        }catch(Exception e){
            try {
                conn.rollback(point);//手動(dòng)通知回滾疙剑,同時(shí)指定回滾點(diǎn)
                //回滾之后記得提交氯迂,上面我們回滾了践叠,就表明最后的提交語句沒有執(zhí)行,那此時(shí)如果不提交
                //嚼蚀,數(shù)據(jù)庫在沒有收到提交的情況下禁灼,會(huì)自動(dòng)回滾所有的sql語句
                conn.commit();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally{
            JdbcUtils.release(conn, ps, result);
        }   
    }
}

說明:這里如果中間出現(xiàn)異常,則只有第一條語句生效轿曙。

三弄捕、事務(wù)的特性(ACID)

  • 原子性(Atomicity)
    原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都是執(zhí)行成功导帝,要么都失敗守谓。

  • 一致性(Consistency)
    事務(wù)必須使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。比如您单,在轉(zhuǎn)賬中賬戶的總額是不變的斋荞。

  • 隔離性(Isolation)
    事務(wù)的隔離性是多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫時(shí),數(shù)據(jù)庫為每一個(gè)用戶開啟的事務(wù)虐秦,不能被其他事務(wù)的操作數(shù)據(jù)所干擾平酿,多個(gè)并發(fā)事務(wù)之間要相互隔離。

  • 持久性(Durability)
    持久性是指一個(gè)事務(wù)一旦被提交羡疗,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的染服,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響。

四叨恨、 事務(wù)的隔離級別

多個(gè)線程開啟各自事務(wù)操作數(shù)據(jù)庫中數(shù)據(jù)時(shí)柳刮,數(shù)據(jù)庫系統(tǒng)要負(fù)責(zé)隔離操作,以保證各個(gè)線程在獲取數(shù)據(jù)時(shí)的準(zhǔn)確性痒钝。

如果不考慮隔離性秉颗,可能會(huì)引發(fā)如下問題:

  • 臟讀
    指一個(gè)事務(wù)讀取了另外一個(gè)事務(wù)未提交的數(shù)據(jù)。
    例如:a花錢讓b給辦點(diǎn)事送矩,a向b轉(zhuǎn)賬之后但未提交蚕甥,但是b此時(shí)會(huì)發(fā)現(xiàn)賬戶多了錢,然后將事辦完之后a卻不提交栋荸,此時(shí)b的賬戶的錢就會(huì)變回原來的數(shù)目菇怀,相當(dāng)于白干活了。

  • 不可重復(fù)讀
    在一個(gè)事務(wù)內(nèi)讀取表中的某一行數(shù)據(jù)晌块,多次讀取的結(jié)果不同爱沟。
    如a開啟一個(gè)事務(wù)后,查詢余額為200匆背,此時(shí)b轉(zhuǎn)賬100呼伸,那么a此時(shí)查詢就是300,兩次結(jié)果不一致钝尸。當(dāng)然有些時(shí)候這樣是正確的括享,但是有時(shí)候卻不是搂根,如在統(tǒng)計(jì)時(shí)我們不能讓多次的統(tǒng)計(jì)結(jié)果不一致。
    和臟讀的區(qū)別:臟讀是讀取前一事務(wù)未提交的數(shù)據(jù)铃辖,不可重復(fù)讀是重新讀取了前一事務(wù)已經(jīng)提交的數(shù)據(jù)剩愧。

  • 虛讀(幻讀)
    是指在一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致澳叉。
    比如一個(gè)表第一次查詢有2條數(shù)據(jù)隙咸,此時(shí)另外一個(gè)事務(wù)插入了一條數(shù)據(jù),此時(shí)再次查詢就變成了3條數(shù)據(jù)成洗,兩次查詢結(jié)果不一致五督。
    和不可重復(fù)讀的區(qū)別:不可重復(fù)讀是讀取到的數(shù)據(jù)結(jié)果不同,而虛讀是指讀取到多個(gè)事務(wù)導(dǎo)致結(jié)果不一致瓶殃。

五充包、事務(wù)隔離性的設(shè)置語句

  • 數(shù)據(jù)庫共定義了四種隔離級別:
    Serializable:可避免臟讀、不可重復(fù)讀遥椿、虛讀情況的發(fā)生基矮。(串行化)
    Repeatable read:可避免臟讀、不可重復(fù)讀情況的發(fā)生冠场。(可重復(fù)讀)
    Read committed:可避免臟讀情況發(fā)生(讀已提交)家浇。
    Read uncommitted:最低級別,以上情況均無法保證碴裙。(讀未提交)

  • set transaction isolation level設(shè)置事務(wù)隔離級別(數(shù)據(jù)庫操作)

  • select @@tx_isolation查詢當(dāng)前事務(wù)隔離級別(數(shù)據(jù)庫操作)

例:設(shè)置隔離級別

Demo3.java

package cn.itcast.demo;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import cn.itcast.utils.JdbcUtils;

public class Demo3 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        try {
            conn = JdbcUtils.getConnection();
            //查詢程序肯定至少要到這個(gè)級別
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            conn.setAutoCommit(false);
            String sql = "select * from account where name='aaa'";
            ps = conn.prepareStatement(sql);
            result = ps.executeQuery();
            if(result.next()){
                System.out.println(result.getFloat("money"));
            }
            Thread.sleep(1000*10);
            result = ps.executeQuery();
            if(result.next()){
                System.out.println(result.getFloat("money"));
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.release(conn, ps, result);
        }
    }

}

六钢悲、使用數(shù)據(jù)庫連接池優(yōu)化程序性能

應(yīng)用程序直接獲取連接的缺點(diǎn):用戶每次都需要向數(shù)據(jù)庫獲得鏈接,而數(shù)據(jù)庫創(chuàng)建連接通常需要消耗相對較大的資源舔株,創(chuàng)建時(shí)間也較長莺琳。


1.png

這時(shí)我們可以使用數(shù)據(jù)庫連接池優(yōu)化程序性能:


2.png
  • 編寫連接池需要實(shí)現(xiàn)java.sql.DataSource接口。DataSource接口中定義了兩個(gè)重載的getConnection方法:
    Connection getConnection()
    Connection getConnection(String username,String password)

  • 實(shí)現(xiàn)DataSource接口载慈,并實(shí)現(xiàn)連接池功能的步驟:
    1.在DataSource構(gòu)造函數(shù)中批量創(chuàng)建與數(shù)據(jù)庫的連接惭等,并把創(chuàng)建的連接加入LinkedList對象中。
    2.實(shí)現(xiàn)getConnection方法办铡,讓getConnection方法每次調(diào)用時(shí)辞做,從LinkedList中取一個(gè)Connection返回給用戶。
    3.當(dāng)用戶使用完Connection寡具,調(diào)用Connection.close()方法時(shí)秤茅,Collection對象應(yīng)保證將自己返回到LinkedList中,而不要把Collection還給數(shù)據(jù)庫。
    Collection保證將自己返回到LinkedList中是此處編程的難點(diǎn)晒杈。

示例:模擬數(shù)據(jù)庫連接池
JdbcPool.java

package junit.test;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;
import javax.sql.DataSource;

public class JdbcPool implements DataSource {
    
    //后面涉及到大量的增刪改查,所以使用LinkedList類
    private static LinkedList<Connection> list = new LinkedList<Connection>();
    
    static {
        try {
            InputStream in = JdbcPool.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            
            Class.forName(driver);
            
            for(int i = 0; i < 10; i++){
                Connection conn = DriverManager.getConnection(url, username, password);
                list.add(conn);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    @Override
    public Connection getConnection() throws SQLException {
        if(list.size() > 0){
            //如果連接池中還有Connection連接則從池中刪除并返回給調(diào)用者
            Connection conn = list.removeFirst();
            return conn;
        }else{
            throw new RuntimeException("數(shù)據(jù)庫正忙");
        }
    }

    其他需要實(shí)現(xiàn)的方法我們并不關(guān)心孔厉,這里省略
}

說明:

  • 這里有個(gè)問題是如果調(diào)用者使用完Connection鏈接之后調(diào)用方法conn.close();那么此鏈接將不會(huì)返回給數(shù)據(jù)庫連接池拯钻,而是直接返回給了數(shù)據(jù)庫帖努,這樣鏈接會(huì)用一個(gè)少一個(gè),顯然不行粪般。也就是說不能這樣拼余,或者說close方法不夠用,我們需要增強(qiáng)一下亩歹,讓其不要返還給數(shù)據(jù)庫匙监,而是返還給連接池。

  • 對于類的某個(gè)方法不能達(dá)到我們的要求時(shí)需要對其進(jìn)行增強(qiáng)小作,而增強(qiáng)的方式有三種:1.寫一個(gè)子類亭姥,覆蓋其close方法;2.寫一個(gè)Connection的包裝類顾稀,增強(qiáng)close方法达罗;3.使用動(dòng)態(tài)代理,返回一個(gè)代理對象出去静秆,攔截close方法的調(diào)用粮揉,達(dá)到對close方法增強(qiáng)的功能。

  • 第一種不行抚笔,因?yàn)槲覀冊谝祷谻onnection的時(shí)候?qū)ο笾幸呀?jīng)封裝了相關(guān)信息扶认,即使我們寫一個(gè)子類也僅僅表明此子類有和父類相同的功能,但是卻沒有父類中已經(jīng)封裝好了的信息殊橙,不能對數(shù)據(jù)庫進(jìn)行操作辐宾。

  • 第二種:寫一個(gè)包裝類。

/*
 * 用包裝設(shè)計(jì)模式對某個(gè)對象進(jìn)行增強(qiáng)步驟:
 * 1蛀柴、寫一個(gè)類螃概,實(shí)現(xiàn)與被增強(qiáng)對象(這里要增強(qiáng)的對象是mysql的連接對象connection)相同的接口(這里的接口是Connection)
 * 2.定義一個(gè)變量,指向被增強(qiáng)對象
 * 3鸽疾、定義一個(gè)構(gòu)造方法吊洼,接收被增強(qiáng)對象(也就是將我們要增強(qiáng)的對象傳遞進(jìn)來進(jìn)行增強(qiáng))
 * 4、覆蓋想增強(qiáng)的方法(這里是close方法)制肮、
 * 5冒窍、對于不想增強(qiáng)的方法,直接調(diào)用被增強(qiáng)對象的方法豺鼻,如this.conn.unwrap(iface)
 * */
class MyConnection implements Connection{
    
    private Connection conn ;
    private List pool;//這里我們需要將數(shù)據(jù)庫連接池傳遞進(jìn)來综液,因?yàn)橹笪覀兪褂玫逆溄佣际窃鰪?qiáng)之后的鏈接
    
    public MyConnection() {
    }
    public MyConnection(Connection conn , List pool){
        this.conn = conn;
        this.pool = pool;
    }
    
    //這里我們只是需要增強(qiáng)close方法,其他方法直接調(diào)用父類的方法即可
    @Override
    public void close() throws SQLException {
        pool.add(conn);
    }
    
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return this.conn.unwrap(iface);
    }
其他方法和上面這個(gè)方法類似儒飒,此處省略
}

說明:之后返回就不是返回Connection對象了谬莹,而是return new MyConnection(conn, list);,但是顯然我們可以看到這種方式太麻煩,因?yàn)槠渲械姆椒ㄌ唷?/p>

  • 第三種:使用動(dòng)態(tài)代理
@Override
    public Connection getConnection() throws SQLException {
        if(list.size() > 0){
            //如果連接池中還有Connection連接則從池中刪除并返回給調(diào)用者
            final Connection conn = list.removeFirst();
            //第一個(gè)參數(shù)指的是使用哪個(gè)類裝載器附帽,第二個(gè)參數(shù)指明我們要對那個(gè)對象進(jìn)行增前埠戳,第三個(gè)參數(shù)指明增強(qiáng)對象完成什么功能
            return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), 
                    new InvocationHandler() {
                //使用動(dòng)態(tài)代理之后其實(shí)不管之后我們調(diào)用Connection的什么方法(commit、rollback...)其實(shí)都是調(diào)用下面的invoke方法
                @Override
                public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
                    //如果調(diào)用的方法不是close方法蕉扮,那么我們使用原來Connection的方法
                    if(!method.getName().equals("close")){
                        return method.invoke(conn, args);
                    }else{
                        //如果調(diào)用close方法整胃,我們將鏈接返還給數(shù)據(jù)庫連接池
                        return list.add(conn);
                    }
                }
            });
        }else{
            throw new RuntimeException("數(shù)據(jù)庫正忙");
        }
    }

說明:其實(shí)動(dòng)態(tài)代理是使用的攔截技術(shù),這里我們不詳細(xì)講喳钟,在后面將過濾器會(huì)詳細(xì)說明屁使。

那么我們可以對之前的數(shù)據(jù)庫工具類做一些改進(jìn):
JdbcUtils.java

package junit.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcUtils {

    private static JdbcPool pool = new JdbcPool();
    public static Connection getConnection() throws SQLException{
        return pool.getConnection();
    }
    
    public static void release(Connection conn, Statement ps , ResultSet result){
        if(result != null){
            try {
                result.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            result = null;
        }
        if(ps != null){
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            ps = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奔则,隨后出現(xiàn)的幾起案子蛮寂,更是在濱河造成了極大的恐慌,老刑警劉巖应狱,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件共郭,死亡現(xiàn)場離奇詭異,居然都是意外死亡疾呻,警方通過查閱死者的電腦和手機(jī)除嘹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岸蜗,“玉大人尉咕,你說我怎么就攤上這事×г溃” “怎么了年缎?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铃慷。 經(jīng)常有香客問我单芜,道長,這世上最難降的妖魔是什么犁柜? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任洲鸠,我火速辦了婚禮,結(jié)果婚禮上馋缅,老公的妹妹穿的比我還像新娘扒腕。我一直安慰自己,他們只是感情好萤悴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布瘾腰。 她就那樣靜靜地躺著,像睡著了一般覆履。 火紅的嫁衣襯著肌膚如雪蹋盆。 梳的紋絲不亂的頭發(fā)上费薄,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音栖雾,去河邊找鬼义锥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛岩灭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赂鲤,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼噪径,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了数初?” 一聲冷哼從身側(cè)響起找爱,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泡孩,沒想到半個(gè)月后车摄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仑鸥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年吮播,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眼俊。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡意狠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疮胖,到底是詐尸還是另有隱情环戈,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布澎灸,位于F島的核電站院塞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏性昭。R本人自食惡果不足惜拦止,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巩梢。 院中可真熱鬧创泄,春花似錦、人聲如沸括蝠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忌警。三九已至搁拙,卻和暖如春秒梳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箕速。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工酪碘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盐茎。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓兴垦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親字柠。 傳聞我的和親對象是個(gè)殘疾皇子探越,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • JDBC概述 在Java中,數(shù)據(jù)庫存取技術(shù)可分為如下幾類:JDBC直接訪問數(shù)據(jù)庫窑业、JDO技術(shù)钦幔、第三方O/R工具,如...
    usopp閱讀 3,538評論 3 75
  • JDBC簡介 SUN公司為了簡化常柄、統(tǒng)一對數(shù)據(jù)庫的操作鲤氢,定義了一套Java操作數(shù)據(jù)庫的規(guī)范,稱之為JDBC西潘。JDBC...
    奮斗的老王閱讀 1,518評論 0 51
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法卷玉,類相關(guān)的語法,內(nèi)部類的語法喷市,繼承相關(guān)的語法揍庄,異常的語法,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 本文包括傳統(tǒng)JDBC的缺點(diǎn)連接池原理自定義連接池開源數(shù)據(jù)庫連接池DBCP連接池C3P0連接池Tomcat內(nèi)置連接池...
    廖少少閱讀 16,750評論 0 37
  • 提起了的筆總是會(huì)放下,我怕把你寫進(jìn)我的故事里缭黔。 多年后也許我還會(huì)想起食茎,曾經(jīng)有那么一個(gè)人,無關(guān)風(fēng)花雪月馏谨,只是我...
    好人壞人閱讀 388評論 0 2