簡(jiǎn)說(shuō) JDBC (小白入門(mén)必備)

導(dǎo)語(yǔ):

最近一直在忙著自己的一個(gè)小項(xiàng)目,沒(méi)來(lái)得及寫(xiě)點(diǎn)東西,很是慚愧。本人也是接觸 Java
沒(méi)多久喳魏,也看過(guò)很多關(guān)于 JDBC 的文章,而本人希望以一個(gè)初學(xué)者的角度通過(guò)本篇文章把其他關(guān)于 JDBC 文章中精華的部分提取出來(lái)怀薛,并加上自己的理解來(lái)談一談 JDBC刺彩,并盡量做到淺顯易懂,希望能對(duì)各位有所幫助。

JDBC 是什么

JDBC 代表 Java 數(shù)據(jù)庫(kù)連接(Java Database Connectivity)创倔,它是用于Java編程語(yǔ)言和數(shù)據(jù)庫(kù)之間的數(shù)據(jù)庫(kù)無(wú)關(guān)連接的標(biāo)準(zhǔn) Java API嗡害,換句話說(shuō):JDBC 是用于在 Java 語(yǔ)言編程中與數(shù)據(jù)庫(kù)連接的 API。

JDBC API 支持用于數(shù)據(jù)庫(kù)訪問(wèn)的兩層和三層處理模型畦攘,但通常霸妹,JDBC 體系結(jié)構(gòu)由兩層組成:

  • JDBC API:提供應(yīng)用程序到 JDBC 管理器連接。
  • JDBC 驅(qū)動(dòng)程序 API:支持 JDBC 管理器到驅(qū)動(dòng)程序連接知押。

JDBC API 使用驅(qū)動(dòng)程序管理器(JDBC Driver Manager)并指定數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序來(lái)提供與數(shù)據(jù)庫(kù)的連接叹螟。

JDBC 驅(qū)動(dòng)程序管理器(JDBC Driver Manager)確保使用正確的驅(qū)動(dòng)程序來(lái)訪問(wèn)每個(gè)數(shù)據(jù)源。 驅(qū)動(dòng)程序管理器(JDBC Driver Manager)能夠支持連接到多個(gè)數(shù)據(jù)庫(kù)的多個(gè)驅(qū)動(dòng)程序台盯。

下圖是我看到的一個(gè)比較好的 JDBC 架構(gòu)模型圖(后面會(huì)對(duì)這張圖做出詳細(xì)的解釋?zhuān)?/p>

JDBC 架構(gòu)

我個(gè)人把使用 JDBC 劃分為了以下六個(gè)步驟:

  • 加載驅(qū)動(dòng)
  • 創(chuàng)建鏈接對(duì)象
  • 創(chuàng)建 sql 命令對(duì)象
  • 執(zhí)行 sql 命令
  • 判斷執(zhí)行結(jié)果
  • 關(guān)閉資源

以上步驟就好比是打電話讓朋友幫忙辦件事兒首妖,首先你得有個(gè)手機(jī)(加載驅(qū)動(dòng)),然后利用手機(jī)給朋友打電話(創(chuàng)建鏈接對(duì)象)爷恳,朋友接到電話(創(chuàng)建 sql 命令對(duì)象)然后執(zhí)行你的要求(執(zhí)行 sql 命令),執(zhí)行命令之后朋友給你一個(gè)反饋澳迫,你來(lái)對(duì)這個(gè)反饋進(jìn)行處理(判斷執(zhí)行結(jié)果)捶牢,最后掛斷電話(關(guān)閉資源)询吴。

常見(jiàn)的 JDBC 組件

JDBC API 提供以下接口和類(lèi):

  • DriverManager:此類(lèi)管理數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序(也就是 Driver)。使用某種協(xié)議(無(wú)需糾結(jié)是什么協(xié)議)將來(lái)自 java 應(yīng)用程序的連接請(qǐng)求與適當(dāng)?shù)臄?shù)據(jù)庫(kù)驅(qū)動(dòng)程序進(jìn)行匹配栈虚,然后進(jìn)行一系列操作連接到數(shù)據(jù)庫(kù)。
  • Driver:此接口處理與數(shù)據(jù)庫(kù)服務(wù)器的通信史隆,我們很少會(huì)直接與 Driver 對(duì)象進(jìn)行交互魂务,但會(huì)使用上面提到的 DriverManager 對(duì)象來(lái)管理這種類(lèi)型的對(duì)象。
  • Connection:此接口具有用于聯(lián)系數(shù)據(jù)庫(kù)的所有方法泌射,與數(shù)據(jù)庫(kù)的所有通信都是通過(guò)該對(duì)象完成的粘姜。
  • Statement:使用此接口創(chuàng)建的對(duì)象將 sql 語(yǔ)句提交到數(shù)據(jù)庫(kù),執(zhí)行 sql 命令熔酷。
  • PreparedStatement:此接口和 Statement 接口類(lèi)似孤紧,用此接口創(chuàng)建的對(duì)象執(zhí)行 sql 命令。
  • ** ResultSet**:執(zhí)行 sql 語(yǔ)句查詢后拒秘,將返回后的數(shù)據(jù)存放在該對(duì)象中号显。

具體 JDBC 應(yīng)用程序

1、向數(shù)據(jù)庫(kù)插入數(shù)據(jù)

//導(dǎo)入需要的包躺酒,大多數(shù)情況下押蚤,使用 import java.sql.*  應(yīng)該就足夠了
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException{
        //1、加載 JDBC 驅(qū)動(dòng)
        Class.forName("oracle.jdbc.OracleDriver");
        //2羹应、利用驅(qū)動(dòng)創(chuàng)建鏈接對(duì)象
        Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","(數(shù)據(jù)庫(kù)賬戶名)","(密碼)");
        //3揽碘、創(chuàng)建 sql 命令對(duì)象并創(chuàng)建 sql 語(yǔ)句
        String sql="insert into tdept values('x','xxx','x')";//往數(shù)據(jù)庫(kù)插入數(shù)據(jù)
        Statement stmt =conn.createStatement();
        //4、執(zhí)行 sql 命令并獲取處理結(jié)果(是否插入成功)
        int i=stmt.executeUpdate(sql);
        //5、處理結(jié)果
        if(i>0){
            System.out.println("插入成功");
        }else{
            System.out.println("插入失敗");
        }
        //6钾菊、關(guān)閉資源
        stmt.close();
        conn.close();
    }
}

這段代碼屬于向數(shù)據(jù)庫(kù)中插入數(shù)據(jù)帅矗,所以不用 ResultSet 對(duì)象,對(duì)于數(shù)據(jù)的增煞烫、刪浑此、改一般返回值都是一個(gè) int 型數(shù)值(此處命名為 i),當(dāng)對(duì)數(shù)據(jù)操作成功后返回值 i 為1滞详,否則凛俱,返回值為 -1。

而對(duì)于數(shù)據(jù)的查詢一般都是需要用 ResultSet 對(duì)象來(lái)接住返回結(jié)果的料饥。

2蒲犬、查詢數(shù)據(jù)庫(kù)中的數(shù)據(jù)(加入異常處理)

//導(dǎo)入需要的包
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestSelect {
    public static void main(String[] args){
        //聲明鏈接參數(shù)
        String url="jdbc:oracle:thin:@localhost:1521:orcl";
        String user="scott";
        String pwd="123";
        String driver="oracle.jdbc.OracleDriver";
        
        //聲明jdbc變量
        Connection conn=null;
        Statement stmt =null;
        ResultSet rs=null;
        
        try {   
            //加載驅(qū)動(dòng)      
            Class.forName(driver);
            //創(chuàng)建鏈接對(duì)象
            conn=DriverManager.getConnection(url,user,pwd);
            //創(chuàng)建 sql 命令對(duì)象并執(zhí)行 sql 命令
            String sql="select * from emp";
            stmt=conn.createStatement();
            //獲取結(jié)果
            rs=stmt.executeQuery(sql);
            //處理結(jié)果 
            System.out.println("學(xué)號(hào)\t姓名\t班級(jí)");
            while(rs.next()){
                 System.out.println(rs.getInt("deptno")+"\t"+rs.getString("daname")+"\t"+rs.getString("loc"));
            }   
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //關(guān)閉資源
             try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

這段代碼可以看成是用 JDBC 的正常步驟,先聲明鏈接對(duì)象岸啡、聲明 jdbc 對(duì)象原叮,然后執(zhí)行上面的六個(gè)步驟。

也許你會(huì)問(wèn)巡蘸,為啥是這幾個(gè)步驟呢奋隶,因?yàn)?.. ... 沒(méi)有原因,就這么來(lái)用的悦荒,別在沒(méi)必要的地方糾結(jié)唯欣。

到這里可能會(huì)有人對(duì) ResultSet 有疑問(wèn),ResultSet 到底是個(gè)什么東東搬味?其實(shí)可以把 ResultSet 看成一個(gè)迭代器:

Resultset 示意圖

最開(kāi)始的時(shí)候境氢,指針處于黑色線條處,當(dāng) sql 語(yǔ)句被執(zhí)行之后碰纬,返回的數(shù)據(jù)儲(chǔ)存在 Resultset 中(如果有的話)萍聊,然后當(dāng)程序執(zhí)行到 rs.next() 的時(shí)候,指針下移悦析,指向返回的第一條數(shù)據(jù)脐区,如果這條數(shù)據(jù)不為空(也就是說(shuō)有返回的數(shù)據(jù))時(shí),rs.next() 為 true她按,然后進(jìn)入 while 循環(huán)對(duì)返回的數(shù)據(jù)進(jìn)行操作牛隅。

PreparedStatement 對(duì)象與 Statement 對(duì)象

在這里需要對(duì)這兩個(gè)對(duì)象進(jìn)行一定的解釋但不深究,其實(shí)也沒(méi)必要深究酌泰,自從我用 jdbc 以來(lái)媒佣,基本上都是用的 PreparedStatement對(duì)象,很少用 Statement陵刹,在此處就不深入探討了還請(qǐng)見(jiàn)諒默伍。

  • 使用 PreparedStatement可以防止 sql 注入(有興趣的同學(xué)可以參考 sql 注入原理講解),因?yàn)樵趧?chuàng)建此對(duì)象的時(shí)候已經(jīng)將SQL傳入,這樣可以針對(duì)性的進(jìn)行賦值.
  • PreparedStatement 的執(zhí)行效率比 Statement 高

且看以下代碼:

//導(dǎo)入包
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class TestPreparedStatement {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //創(chuàng)建鏈接參數(shù)
        //聲明jdbc變量
        //加載驅(qū)動(dòng)
        Class.forName("oracle.jdbc.OracleDriver");
        //創(chuàng)建鏈接對(duì)象
        Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "(數(shù)據(jù)庫(kù)賬戶)","(數(shù)據(jù)庫(kù)密碼)");
        //創(chuàng)建 sql 命令對(duì)象并發(fā)送 sql 命令
        String sql="insert into t_user values(?,?,?)";
&      PreparedStatement ps=conn.prepareStatement(sql);
        //PreparedStatement 可以給字段針對(duì)性的進(jìn)行賦值
        ps.setInt(1,6);
        ps.setString(2,"李四");
        ps.setString(3,"123");
&&    int i=ps.executeUpdate(); 

        //使用 Statement 的寫(xiě)法
        String sql2="insert into t_user values(5,'張三','123')";
&      Statement st=conn.createStatement();
&&    int j=st.executeUpdate(sql2);
            
        //獲取結(jié)果
        //處理結(jié)果
        //關(guān)閉資源
    }
}

從上面的代碼可以看出(為了方便大家對(duì)比也糊,不產(chǎn)生冗余炼蹦,獲取結(jié)果之后的代碼在這里就不寫(xiě)出來(lái)了),創(chuàng)建 sql 命令對(duì)象的方式不同(標(biāo)&處)狸剃,另外執(zhí)行 sql 命令的方式也不相同(標(biāo)&&處)掐隐,而且** PreparedStatement 可以給字段針對(duì)性的進(jìn)行賦值**,這點(diǎn)是這是 Statement 所不具備的钞馁,一般使用過(guò)程中使用 PreparedStatement 較多虑省。

以上這些是兩者使用方式的不同,個(gè)人覺(jué)得不需要深究僧凰,如果不理解探颈,敲代碼,敲代碼训措,敲代碼N苯凇!绩鸣!學(xué)習(xí)一門(mén)技術(shù)如果只是紙上談兵怀大,永遠(yuǎn)也學(xué)不好,看完之后更重要的是要實(shí)踐全闷,畢竟實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),而且你親自多敲幾遍代碼會(huì)對(duì)知識(shí)有更深的理解萍启。

以上只是個(gè)人的愚見(jiàn)总珠,如有不妥之處,還請(qǐng)指出勘纯,一定改進(jìn)局服!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市驳遵,隨后出現(xiàn)的幾起案子淫奔,更是在濱河造成了極大的恐慌,老刑警劉巖堤结,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唆迁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡竞穷,警方通過(guò)查閱死者的電腦和手機(jī)唐责,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瘾带,“玉大人鼠哥,你說(shuō)我怎么就攤上這事。” “怎么了朴恳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵抄罕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我于颖,道長(zhǎng)呆贿,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任恍飘,我火速辦了婚禮榨崩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘章母。我一直安慰自己母蛛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布乳怎。 她就那樣靜靜地躺著彩郊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚪缀。 梳的紋絲不亂的頭發(fā)上秫逝,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音询枚,去河邊找鬼违帆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛金蜀,可吹牛的內(nèi)容都是我干的刷后。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼渊抄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尝胆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起护桦,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤含衔,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后二庵,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贪染,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年催享,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抑进。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡睡陪,死狀恐怖寺渗,靈堂內(nèi)的尸體忽然破棺而出匿情,到底是詐尸還是另有隱情,我是刑警寧澤信殊,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布炬称,位于F島的核電站,受9級(jí)特大地震影響涡拘,放射性物質(zhì)發(fā)生泄漏玲躯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一鳄乏、第九天 我趴在偏房一處隱蔽的房頂上張望跷车。 院中可真熱鬧,春花似錦橱野、人聲如沸朽缴。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)密强。三九已至,卻和暖如春蜗元,著一層夾襖步出監(jiān)牢的瞬間或渤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工奕扣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留薪鹦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓惯豆,卻偏偏與公主長(zhǎng)得像池磁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子循帐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • JDBC基礎(chǔ)知識(shí) 一框仔、采用JDBC訪問(wèn)數(shù)據(jù)庫(kù)的基本步驟: A.載入JDBC驅(qū)動(dòng)程序 B.定義連接URL ...
    java日記閱讀 3,850評(píng)論 0 20
  • JDBC概述 在Java中舀武,數(shù)據(jù)庫(kù)存取技術(shù)可分為如下幾類(lèi):JDBC直接訪問(wèn)數(shù)據(jù)庫(kù)拄养、JDO技術(shù)、第三方O/R工具银舱,如...
    usopp閱讀 3,538評(píng)論 3 75
  • 春分者 陰陽(yáng)相半也 故 晝夜均 而寒暑平 一候 元鳥(niǎo)至 二候 雷乃發(fā)聲 三候 始電 — 春分 ???【摘自男神...
    大悅兒兒閱讀 206評(píng)論 0 1
  • 那時(shí)為何不珍惜 要到此時(shí)來(lái)回憶 在幻想里流淚 在幻滅中交集
    一元真人閱讀 114評(píng)論 2 8
  • 她是一個(gè)不感性的文科生瘪匿,我認(rèn)識(shí)的文科生中基本上感性的居多,張口就來(lái)詩(shī)詞歌賦寻馏,遇事難免得發(fā)條朋友圈感慨一番棋弥,遇到什么...
    七搖光閱讀 334評(píng)論 0 2