JDBC的誕生

姓名:盼厶В康 ?學號:17101223416

轉(zhuǎn)載自:https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513438&idx=1&sn=2967d595bb7d4ffdd2dacd3ab7501bbd&chksm=80d6799db7a1f08b27dc97650434fb2fc0e2570628945db99d9300a99e52828fd05c42fdb441&scene=38#wechat_redirect

【嵌牛導讀】:隨著 Oracle, Sybase, SQL Server ,DB2, ?Mysql 等人陸陸續(xù)續(xù)住進數(shù)據(jù)庫村, 這里呈現(xiàn)出一片興旺發(fā)達的景象摧茴, 無數(shù)的程序在村里忙忙碌碌哄褒, 讀寫數(shù)據(jù)庫稀蟋, 實際上一個村落已經(jīng)容不下這么多人了, 數(shù)據(jù)庫村變成了數(shù)據(jù)鎮(zhèn)呐赡。

【嵌牛鼻子】:JDBC

【嵌牛提問】:JDBC是怎么解決數(shù)據(jù)庫底層連接問題的呢退客?

【嵌牛正文】:

一、網(wǎng)絡(luò)訪問

這一天链嘀, 數(shù)據(jù)庫鎮(zhèn)發(fā)生了一件大事: 它連上了網(wǎng)絡(luò)萌狂!

外部的花花世界一下全部打開, ?很多程序開始離開這個擁擠的城鎮(zhèn)怀泊, 住到更加宜居的地方去茫藏。

可是他們的工作還是要讀寫數(shù)據(jù)庫, 大家都在想辦法能不能通過網(wǎng)絡(luò)來訪問數(shù)據(jù)庫鎮(zhèn)的數(shù)據(jù)庫包个。

其中移居到Tomcat村的Java 最為活躍刷允, 這小子先去拜訪了一下Mysql , ? ?相對于Oracle, Sybase 等大佬, Mysql 還很弱小碧囊, 也許容易搞定树灶。

Java 說: “Mysql 先生, 現(xiàn)在已經(jīng)網(wǎng)絡(luò)時代了糯而, 您也得與時俱進啊天通, 給我們開放下網(wǎng)絡(luò)接口吧。 ”

Mysql ?說: “還網(wǎng)絡(luò)時代, 你們這些家伙越來越懶了谴蔑, 都不愿意到我們家里來了! 說說吧胆敞, 你想怎么開放诺祸? ?”

Java 說: “很簡單携悯, 您聽說過TCP/IP還有Socket 沒有? ? 沒有嗎筷笨?憔鬼! ?沒關(guān)系, 您的操作系統(tǒng)肯定知道胃夏, 它內(nèi)置實現(xiàn)了TCP/IP和socket, ? 您只需要和他商量一下轴或, 需要申請一個ip , 確定一個端口仰禀, 然后您在這個端口監(jiān)聽照雁, ?我每次想訪問數(shù)據(jù)了, 就會創(chuàng)建一個socket 答恶,向你發(fā)起連接請求饺蚊, 你接受了就行了。 ”

“這么麻煩靶ぁ卸勺?”

“其實也簡單, 您的操作系統(tǒng)會幫忙的烫扼, 他非常熟悉曙求, ?再說只需要做一次就行, 把這個網(wǎng)絡(luò)訪問建立起來映企, 到時候很多程序都會來訪問您悟狱, 您會發(fā)財?shù)摹?”

“不會這么簡單吧, 假設(shè)說堰氓, 我是說假設(shè)啊挤渐, ?通過socket我們建立了連接, 通過這個連接双絮, 你給我發(fā)送什么東西浴麻? ?我又給你發(fā)什么東西?” ?Mysql非常老練囤攀, 直擊命門软免。

“呃, 這個.... ?”

Java 其實心里其實非常明白焚挠, 這需要和Mysql定義一個應用層的協(xié)議膏萧, 就是所謂的你發(fā)什么請求, 我給你什么響應

例如:

客戶端程序先給Mysql 打個招呼榛泛, ?Mysql也回應一下蝌蹂, 俗稱握手。

怎么做認證曹锨、授權(quán)孤个, 數(shù)據(jù)加密, 數(shù)據(jù)包分組沛简。

用什么格式發(fā)送查詢語句硼身, ? 用什么格式來發(fā)送結(jié)果。

如果結(jié)果集很大覆享, 要一下子全發(fā)過來嗎?

怎么做數(shù)據(jù)緩沖营袜?

......

等等一系列讓人頭痛的問題撒顿。

本來Java是想獨自定義, 這樣自己也許能占點便宜荚板, 沒想到Mysql ?直接提出來了凤壁。

“這樣吧 ” Java 說 “我們先把這個應用層的協(xié)議定義下來, 然后您去找操作系統(tǒng)來搞定socket如何跪另? ”

“這還差不多 ” 拧抖。 Mysql 同意了。

兩人忙活了一星期免绿, 才把這個應用層協(xié)議給定義好唧席。

然后又忙了一星期, 才把Mysql 這里的socket搞定嘲驾。

Java 趕緊回到Tomcat村淌哟, ?做了一個實驗: ?通過socket和mysql 建立連接, ?然后通過socket 發(fā)送約定好的應用層協(xié)議辽故, ? ?還真不錯徒仓, 一次都調(diào)通了, ? 看來準備工作很重要啊誊垢。

二掉弛、統(tǒng)一接口

搞定了Mysql , ?Java 很得意, 這是一個很好的起點喂走, 以后和Oracle, SQL Server, Db2等大佬談判也有底氣了殃饿。

尤其是和mysql 商量出的應用層協(xié)議, ? mysql 也大度的公開了芋肠, 這樣一來壁晒, 不管是什么語言寫的程序,管你是java, pyhton, ruby , php...... ? 只要能使用socket, ? 就可以遵照mysql 的應用層協(xié)議進行訪問, ?mysql 的顧客呈指數(shù)級增長秒咐, 財源滾滾谬晕。 ?尤其是一個叫PHP的家伙, 簡直和mysql 成了死黨携取。

Oracle, Db2那幫大佬一看攒钳, 立刻就紅了眼, 不到Java 去談判雷滋, 也迫不及待的定義了一套屬于自己的應用層訪問協(xié)議不撑。

令人抓狂的是, 他們的網(wǎng)絡(luò)訪問協(xié)議和Msyql 的完全不一樣 晤斩! ?這就意味著之前寫的針對mysql 的程序無法針對Oracle , Db2通用焕檬, ?如果想切換數(shù)據(jù)庫, 每個程序都得另起爐灶寫一套代碼澳泵!

更讓人惡心的是实愚, 每套代碼都得處理非常多的協(xié)議細節(jié), ? 每個使用Java進行數(shù)據(jù)庫訪問的程序都在喋喋不休的抱怨: 我就想通過網(wǎng)絡(luò)給數(shù)據(jù)庫發(fā)送SQL語句, 怎么搞的這么麻煩兔辅?

原因很簡單腊敲, 就是直接使用socket編程, 太low 了 维苔, ?必須得有一個抽象層屏蔽這些細節(jié)碰辅!

Java 開始苦苦思索, 做出一個好的抽象不是那么容易的介时。

首先得有一個叫連接(Connection)的東西没宾, 用來代表和數(shù)據(jù)庫的連接。

想執(zhí)行SQL怎么辦沸柔? 用一個Statement來 表示吧榕吼。 ? SQL返回的結(jié)果也得有個抽象的概念: ResultSet 。

他們之間的關(guān)系如圖所示:

從Connection 可以創(chuàng)建Statement, ? ?Statement 執(zhí)行查詢可以得到ResultSet勉失。

ResultSet提供了對數(shù)據(jù)進行遍歷的方法羹蚣, 就是rs.next() , rs.getXXXX .... ? ? ?完美乱凿!

對了顽素, 無論是Connection, 還是Statement, ResultSet , ?他們都應該是接口徒蟆,而不能是具體實現(xiàn)胁出。

具體的實現(xiàn)需要由各個數(shù)據(jù)庫或者第三方來提供, 毫無疑問段审, 具體的實現(xiàn)代碼中就需要處理那些煩人的細節(jié)了全蝶!

Java 把這個東西叫做JDBC, ?想著自己定義了一個標準接口, 把包袱都甩給你別人抑淫, 他非常得意绷落。

三、面向接口編程

第一個使用JDBC始苇, 叫做學生信息管理的程序很快發(fā)現(xiàn)了問題砌烁, ? 跑來質(zhì)問Java: “你這個Connection 接口設(shè)計的有問題!”

Java 說: “不可能催式, 我的設(shè)計多完善昂怼!”

“看來你這個規(guī)范的制定者沒有真正使用啊荣月, ?你看看管呵, 我想連接Mysql, 把Mysql 提供的jdbc實現(xiàn)(mysql-connector-java-4.1.jar)拿了過來, ? 建立一個Connection : ”

“這不是挺正常的嗎哺窄? 你要連接Mysql , 肯定要提供ip地址捐下, 端口號,數(shù)據(jù)庫名啊” Java 問到堂氯。

“問題不在這里, 昨天我遇到mysql了牌废, 他給了我一個號稱性能更強勁的升級版mysql-connector-java-5.0.jar咽白, ?我升級以后, 發(fā)現(xiàn)我的代碼編譯都通不過了鸟缕, ?原來mysql 把MysqlConnectionImpl 這個類名改成了 MysqlConnectionJDBC4Impl ?晶框, 你看看, 你整天吹噓著要面向接口編程懂从, 不要面向?qū)崿F(xiàn)編程授段, 但是你自己設(shè)計的東西都做不到啊”

Java覺得背上開始出汗, ?那個程序說的沒錯番甩, ?設(shè)計上出了漏洞侵贵, 趕緊彌補吧。

既然不能直接去 new 一個Connection 的實現(xiàn)缘薛, 肯定要通過一個新的抽象層來做窍育, 這個中間層叫做什么?

Java 想到了電腦上的驅(qū)動程序宴胧, 很多硬件沒法直接使用漱抓, 除非安裝了驅(qū)動。 ? 那我也模擬一下再做一個抽象層吧:Driver恕齐。

每個數(shù)據(jù)庫都需要實現(xiàn)Driver 接口乞娄, ? 通過Driver 可以獲得數(shù)據(jù)庫連接Connection , ?但是這個Driver 怎么才能new 出來呢? ?肯定不能直接new , ? ?Java似乎陷入了雞生蛋仪或、蛋生雞的無限循環(huán)中了确镊。

最后, 還是Java的反射機制救了他溶其, 不要直接new 了骚腥, ?每個數(shù)據(jù)庫的Driver 都用一個文本字符串來表示, 運行時動態(tài)的去裝載瓶逃, 例如mysql 的Driver 是這樣的:

Oracle是這樣的:

只要這個Driver Class不改動束铭, 其他具體的實現(xiàn)像Connection, ?Statement, ResultSet想怎么改就怎么改。

接下來的問題是同一個程序可能訪問不同的數(shù)據(jù)庫厢绝, 可能有多個不同Driver 都被動態(tài)裝載進來契沫, 如何來管理?

那就搞一個DriverManager吧昔汉, ?Mysql 的Driver, Oracle的Driver 在類初始化的時候懈万, 一定得注冊到DriverManager中來, 這樣DriverManager才能管理鞍胁 :

注意: 關(guān)鍵點是static 的代碼塊会通, 在一個類被裝載后就會執(zhí)行。

DriverManager 可以提供一個getConnection的方法娄周, 用于建立數(shù)據(jù)庫Connection 涕侈。

DriverManager會把這些信息傳遞給每個Driver , 讓每個Driver去創(chuàng)建Connection 煤辨。

慢著裳涛! ?如果DriverManager ?里既有MysqlDriver, 又有OracleDriver , ?這里到底該連接哪一個數(shù)據(jù)庫呢? ? 難道讓兩個Driver 都嘗試一下众辨? 那樣太費勁了吧端三, 還得區(qū)分開,沒法子只好讓那些程序在數(shù)據(jù)庫連接url中來指定吧:

url中指明了這是一個什么數(shù)據(jù)庫鹃彻, 每個Driver 都需要判斷下是不是屬于自己支持的類型郊闯, 是的話就開始連接, 不是的話直接放棄蛛株。

(劉欣注: 每個Driver接口的實現(xiàn)類都需要實現(xiàn)一個acceptsURL(Sting url)方法虚婿, 判斷這個url是不是自己能支持的。 )

唉泳挥,真是不容易啊然痊, Java想, 這下整個體系就完備了吧屉符, 為了獲得一個Connection , 綜合起來其實就這么幾行代碼:

無論是任何數(shù)據(jù)庫剧浸, 只要正確實現(xiàn)了Driver锹引, Connection 等接口, 就可以輕松的納入到JDBC框架下了唆香。

Java終于可以高興的宣布: “JDBC正式誕生了嫌变!”

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市躬它,隨后出現(xiàn)的幾起案子腾啥,更是在濱河造成了極大的恐慌,老刑警劉巖冯吓,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倘待,死亡現(xiàn)場離奇詭異,居然都是意外死亡组贺,警方通過查閱死者的電腦和手機凸舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來失尖,“玉大人啊奄,你說我怎么就攤上這事∠瞥保” “怎么了菇夸?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仪吧。 經(jīng)常有香客問我庄新,道長,這世上最難降的妖魔是什么邑商? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任摄咆,我火速辦了婚禮凡蚜,結(jié)果婚禮上人断,老公的妹妹穿的比我還像新娘。我一直安慰自己朝蜘,他們只是感情好恶迈,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谱醇,像睡著了一般暇仲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上副渴,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天奈附,我揣著相機與錄音,去河邊找鬼煮剧。 笑死斥滤,一個胖子當著我的面吹牛将鸵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佑颇,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼顶掉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挑胸?” 一聲冷哼從身側(cè)響起痒筒,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茬贵,沒想到半個月后簿透,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡闷沥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年萎战,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舆逃。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚂维,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出路狮,到底是詐尸還是另有隱情虫啥,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布奄妨,位于F島的核電站涂籽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏砸抛。R本人自食惡果不足惜评雌,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望直焙。 院中可真熱鬧景东,春花似錦、人聲如沸奔誓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厨喂。三九已至和措,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜕煌,已是汗流浹背派阱。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留斜纪,地道東北人贫母。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓故响,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颁独。 傳聞我的和親對象是個殘疾皇子彩届,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

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