數(shù)據(jù)庫層原理

JDBC數(shù)據(jù)庫連接

  • 導(dǎo)入JDBC包:使用Java語言的import語句在Java代碼開頭位置導(dǎo)入所需的類。

  • 注冊JDBC驅(qū)動程序:使JVM將所需的驅(qū)動程序?qū)崿F(xiàn)加載到內(nèi)存中产阱,從而可以滿足JDBC請求。

    • 方法I - Class.forName()
      注冊驅(qū)動程序最常見的方法是使用Java的Class.forName()方法,將驅(qū)動程序的類文件動態(tài)加載到內(nèi)存中义屏,并將其自動注冊。這個方法是推薦使用的方法蜂大,因為它使驅(qū)動程序注冊可配置和便攜闽铐。
    • 方法II - DriverManager.registerDriver()
      如果使用的是非JDK兼容的JVM(如Microsoft提供的),則應(yīng)使用registerDriver()方法县爬。
  • 數(shù)據(jù)庫URL配置:創(chuàng)建一個正確格式化的地址阳啥,指向要連接到的數(shù)據(jù)庫(如:MySQL,Oracle和MSSQL等等)。

  • 創(chuàng)建連接對象:最后财喳,調(diào)用DriverManager對象的getConnection()方法來建立實際的數(shù)據(jù)庫連接察迟。

JDBC Statements, PreparedStatement和CallableStatement語句

Statement對象

  • 創(chuàng)建Statement對象
    在使用Statement對象執(zhí)行SQL語句之前,需要使用Connection對象的createStatement()方法創(chuàng)建一個Statement對象
    在創(chuàng)建Statement對象后耳高,可以使用它來執(zhí)行一個SQL語句扎瓶,它有三個執(zhí)行方法可以執(zhí)行。它們分別是 :

    • boolean execute (String SQL) : 如果可以檢索到ResultSet對象泌枪,則返回一個布爾值true; 否則返回false概荷。使用此方法執(zhí)行SQLDDL語句或需要使用真正的動態(tài)SQL,可使用于執(zhí)行創(chuàng)建數(shù)據(jù)庫碌燕,創(chuàng)建表的SQL語句等等误证。
    • int executeUpdate (String SQL): 返回受SQL語句執(zhí)行影響的行數(shù)。使用此方法執(zhí)行預(yù)期會影響多行的SQL語句修壕,例如:INSERT愈捅,UPDATE或DELETE語句。
    • ResultSet executeQuery(String SQL):返回一個ResultSet對象慈鸠。 當您希望獲得結(jié)果集時蓝谨,請使用此方法,就像使用SELECT語句一樣。
  • 關(guān)閉Statement對象

tatement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   stmt.close();
}

PreparedStatement對象

PreparedStatement接口擴展了Statement接口譬巫,它添加了比Statement對象更好一些優(yōu)點的功能咖楣。此語句可以動態(tài)地提供/接受參數(shù)。

  • 創(chuàng)建PreparedStatement對象
    JDBC中的所有參數(shù)都由 ? 符號作為占位符芦昔,這被稱為參數(shù)標記诱贿。 在執(zhí)行SQL語句之前,必須為每個參數(shù)(占位符)提供值咕缎。
    setXXX()方法將值綁定到參數(shù)瘪松,其中XXX表示要綁定到輸入?yún)?shù)的值的Java數(shù)據(jù)類型。 如果忘記提供綁定值锨阿,則將會拋出一個SQLException宵睦。
    每個參數(shù)標記是它其順序位置引用。第一個標記表示位置1墅诡,下一個位置2等等壳嚎。 該方法與Java數(shù)組索引不同(它不從0開始)。
    所有Statement對象與數(shù)據(jù)庫交互的方法(a)execute()末早,(b)executeQuery()和(c)executeUpdate()也可以用于PreparedStatement對象烟馅。 但是,這些方法被修改為可以使用輸入?yún)?shù)的SQL語句然磷。

  • 關(guān)閉PreparedStatement對象

CallableStatement對象

類似Connection對象創(chuàng)建Statement和PreparedStatement對象一樣郑趁,它還可以使用同樣的方式創(chuàng)建CallableStatement對象,該對象將用于執(zhí)行對數(shù)據(jù)庫存儲過程的調(diào)用姿搜。

JDBC結(jié)果集

SQL語句執(zhí)行后從數(shù)據(jù)庫查詢讀取數(shù)據(jù)寡润,返回的數(shù)據(jù)放在結(jié)果集中。 SELECT語句用于從數(shù)據(jù)庫中選擇行并在結(jié)果集中查看它們的標準方法舅柜。 java.sql.ResultSet接口表示數(shù)據(jù)庫查詢的結(jié)果集梭纹。

ResultSet對象維護指向結(jié)果集中當前行的游標。 術(shù)語“結(jié)果集”是指包含在ResultSet對象中的行和列數(shù)據(jù)致份。

ResultSet接口的方法可以分為三類:

  • 瀏覽方法:用于移動光標变抽。
  • 獲取方法:用于查看光標指向的當前行的列中的數(shù)據(jù)。
  • 更新方法:用于更新當前行的列中的數(shù)據(jù)氮块。 然后在基礎(chǔ)數(shù)據(jù)庫中更新數(shù)據(jù)绍载。
    光標可以基于ResultSet的屬性移動。當創(chuàng)建生成ResultSet的相應(yīng)Statement時滔蝉,將指定這些屬性击儡。

JDBC提供以下連接方法來創(chuàng)建具有所需ResultSet的語句

  • createStatement(int RSType, int RSConcurrency);
  • prepareStatement(String SQL, int RSType, int RSConcurrency);
  • prepareCall(String sql, int RSType, int RSConcurrency);
    第一個參數(shù)表示ResultSet對象的類型,第二個參數(shù)是兩個ResultSet常量之一锰提,用于指定結(jié)果集是只讀還是可更新曙痘。

JDBC事務(wù)

如果JDBC連接處于自動提交模式,默認情況下立肘,則每個SQL語句在完成后都會提交到數(shù)據(jù)庫边坤。

對于簡單的應(yīng)用程序可能沒有問題,但是有三個原因需要考慮是否關(guān)閉自動提交并管理自己的事務(wù) :

  • 提高性能
  • 保持業(yè)務(wù)流程的完整性
  • 使用分布式事務(wù)
    事務(wù)能夠控制何時更改提交并應(yīng)用于數(shù)據(jù)庫谅年。 它將單個SQL語句或一組SQL語句視為一個邏輯單元茧痒,如果任何語句失敗,整個事務(wù)將失敗融蹂。

要啟用手動事務(wù)支持旺订,而不是使用JDBC驅(qū)動程序默認使用的自動提交模式,請調(diào)用Connection對象的setAutoCommit()方法超燃。 如果將布爾的false傳遞給setAutoCommit()区拳,則關(guān)閉自動提交。 也可以傳遞一個布爾值true來重新打開它意乓。

例如樱调,如果有一個名為conn的Connection對象,請將以下代碼關(guān)閉自動提交 -

conn.setAutoCommit(false);

提交和回滾

try{
   //Assume a valid connection object conn
   conn.setAutoCommit(false);
   Statement stmt = conn.createStatement();

   String SQL = "INSERT INTO Employees  " +
                "VALUES (106, 20, 'Rita', 'Tez')";
   stmt.executeUpdate(SQL);  
   //Submit a malformed SQL statement that breaks
   String SQL = "INSERTED IN Employees  " +
                "VALUES (107, 22, 'Sita', 'Singh')";
   stmt.executeUpdate(SQL);
   // If there is no error.
   conn.commit();
}catch(SQLException se){
   // If there is any error.
   conn.rollback();
}

使用保存點

設(shè)置保存點(Savepoint)時届良,可以在事務(wù)中定義邏輯回滾點笆凌。
如果通過保存點(Savepoint)發(fā)生錯誤時,則可以使用回滾方法來撤消所有更改或僅保存保存點之后所做的更改士葫。
有一個rollback (String savepointName)方法乞而,它將使用事務(wù)回滾到指定的保存點。

JDBC批量處理

批量處理允許將相關(guān)的SQL語句分組到批處理中慢显,并通過對數(shù)據(jù)庫的一次調(diào)用來提交它們爪模,一次執(zhí)行完成與數(shù)據(jù)庫之間的交互。一次向數(shù)據(jù)庫發(fā)送多個SQL語句時荚藻,可以減少通信開銷呻右,從而提高性能。不需要JDBC驅(qū)動程序來支持此功能鞋喇。應(yīng)該使用DatabaseMetaData.supportsBatchUpdates()
方法來確定目標數(shù)據(jù)庫是否支持批量更新處理声滥。如果JDBC驅(qū)動程序支持此功能,該方法將返回true侦香。

Statement落塑,PreparedStatement和CallableStatement的addBatch()方法用于將單個語句添加到批處理。 executeBatch()用于執(zhí)行組成批量的所有語句罐韩。
executeBatch()返回一個整數(shù)數(shù)組憾赁,數(shù)組的每個元素表示相應(yīng)更新語句的更新計數(shù)。就像將批處理語句添加到處理中一樣散吵,可以使用clearBatch()方法刪除它們龙考。此方法將刪除所有使用addBatch()方法添加的語句蟆肆。 但是,無法指定選擇某個要刪除的語句晦款。

使用Statement對象進行批處理

以下是使用Statement對象的批處理的典型步驟序列:

  • 使用createStatement()方法創(chuàng)建Statement對象炎功。
  • 使用setAutoCommit()將自動提交設(shè)置為false。
  • 使用addBatch()方法在創(chuàng)建的Statement對象上添加SQL語句到批處理中缓溅。
  • 在創(chuàng)建的Statement對象上使用executeBatch()方法執(zhí)行所有SQL語句蛇损。
  • 最后,使用commit()方法提交所有更改坛怪。

實例:


// Create statement object
Statement stmt = conn.createStatement();

// Set auto-commit to false
conn.setAutoCommit(false);

// Create SQL statement
String SQL = "INSERT INTO Employees (id, first, last, age) " +
             "VALUES(200,'Ruby', 'Yang', 30)";
// Add above SQL statement in the batch.
stmt.addBatch(SQL);

// Create one more SQL statement
String SQL = "INSERT INTO Employees (id, first, last, age) " +
             "VALUES(201,'Java', 'Lee', 35)";
// Add above SQL statement in the batch.
stmt.addBatch(SQL);

// Create an int[] to hold returned values
int[] count = stmt.executeBatch();

//Explicitly commit statements to apply changes
conn.commit();

使用PrepareStatement對象進行批處理

// Create SQL statement
String SQL = "INSERT INTO Employees (id, first, last, age) " +
             "VALUES(?, ?, ?, ?)";

// Create PrepareStatement object
PreparedStatemen pstmt = conn.prepareStatement(SQL);

//Set auto-commit to false
conn.setAutoCommit(false);

// Set the variables
pstmt.setInt( 1, 400 );
pstmt.setString( 2, "JDBC" );
pstmt.setString( 3, "Li" );
pstmt.setInt( 4, 33 );
// Add it to the batch
pstmt.addBatch();

// Set the variables
pstmt.setInt( 1, 401 );
pstmt.setString( 2, "CSharp" );
pstmt.setString( 3, "Liang" );
pstmt.setInt( 4, 31 );
// Add it to the batch
pstmt.addBatch();

//add more batches

//Create an int[] to hold returned values
int[] count = stmt.executeBatch();

//Explicitly commit statements to apply changes
conn.commit();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淤齐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袜匿,更是在濱河造成了極大的恐慌更啄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件居灯,死亡現(xiàn)場離奇詭異锈死,居然都是意外死亡,警方通過查閱死者的電腦和手機穆壕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門待牵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喇勋,你說我怎么就攤上這事缨该。” “怎么了川背?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵贰拿,是天一觀的道長。 經(jīng)常有香客問我熄云,道長膨更,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任缴允,我火速辦了婚禮荚守,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘练般。我一直安慰自己矗漾,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布薄料。 她就那樣靜靜地躺著敞贡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摄职。 梳的紋絲不亂的頭發(fā)上誊役,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天获列,我揣著相機與錄音,去河邊找鬼蛔垢。 笑死击孩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的啦桌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼及皂,長吁一口氣:“原來是場噩夢啊……” “哼甫男!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起验烧,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤板驳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碍拆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體若治,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年感混,在試婚紗的時候發(fā)現(xiàn)自己被綠了端幼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弧满,死狀恐怖婆跑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庭呜,我是刑警寧澤滑进,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站募谎,受9級特大地震影響扶关,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜数冬,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一节槐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拐纱,春花似錦疯淫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咕宿,卻和暖如春币绩,著一層夾襖步出監(jiān)牢的瞬間蜡秽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工缆镣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芽突,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓董瞻,卻偏偏與公主長得像寞蚌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钠糊,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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