鍍金池/ 教程/ Java/ JDBC快速入門教程
JDBC Like子句實(shí)例
JDBC異常
JDBC排序數(shù)據(jù)實(shí)例
JDBC事務(wù)保存點(diǎn)(setSavepoint, releaseSavepoint )實(shí)例
JDBC結(jié)果集
JDBC Statement對(duì)象執(zhí)行批量處理實(shí)例
JDBC事務(wù)
JDBC SQL語法
JDBC快速入門教程
JDBC創(chuàng)建數(shù)據(jù)庫實(shí)例
JDBC流ASCII和二進(jìn)制數(shù)據(jù)
JDBC刪除表實(shí)例
JDBC Statements, PreparedStatement和CallableStatement語句
JDBC WHERE子句條件實(shí)例
JDBC插入數(shù)據(jù)實(shí)例
JDBC驅(qū)動(dòng)程序類型
JDBC環(huán)境配置
JDBC數(shù)據(jù)庫連接
JDBC刪除數(shù)據(jù)實(shí)例
JDBC PrepareStatement對(duì)象執(zhí)行批量處理實(shí)例
JDBC刪除數(shù)據(jù)庫實(shí)例
JDBC事務(wù)提交/回滾實(shí)例
JDBC更新數(shù)據(jù)實(shí)例
JDBC存儲(chǔ)過程調(diào)用
JDBC教程
JDBC批量處理
JDBC創(chuàng)建表實(shí)例
JDBC數(shù)據(jù)類型
JDBC是什么?
JDBC簡單示例代碼
JDBC選擇數(shù)據(jù)庫實(shí)例
JDBC查詢數(shù)據(jù)實(shí)例

JDBC快速入門教程

JDBC是什么?

JDBC API是一個(gè)Java API,可以訪問任何類型表列數(shù)據(jù),特別是存儲(chǔ)在關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)。JDBC代表Java數(shù)據(jù)庫連接。

JDBC庫中所包含的API通常與數(shù)據(jù)庫使用于:

  • 連接到數(shù)據(jù)庫
  • 創(chuàng)建SQL或MySQL語句
  • 在數(shù)據(jù)庫中執(zhí)行SQL或MySQL查詢
  • 查看和修改數(shù)據(jù)庫中的數(shù)據(jù)記錄

使用JDBC前提條件

在學(xué)習(xí)JDBC之前,需要對(duì)以下兩個(gè)編程知識(shí)有一定的了解:

  • JAVA核心編程
  • SQL語句或一種數(shù)據(jù)庫系統(tǒng)(如:MySQL,Oracle數(shù)據(jù)庫)

JDBC環(huán)境設(shè)置

請(qǐng)確認(rèn)您已完成以下設(shè)置:

  • JAVA(JDK)安裝
  • 數(shù)據(jù)庫系統(tǒng)的安裝(如:MySQL的安裝)

除上述者外環(huán)境配置外,還需要建立一個(gè)數(shù)據(jù)庫,為本程項(xiàng)目作為測試使用。假設(shè)創(chuàng)建一個(gè)數(shù)據(jù)庫:test,在這個(gè)數(shù)據(jù)庫上創(chuàng)建一張表:employees

創(chuàng)建JDBC應(yīng)用程序

建立一個(gè)JDBC應(yīng)用程序,本教程中以Java連接MySQL為一個(gè)示例,分六個(gè)步驟進(jìn)行:

1. 導(dǎo)入包

在程序中包含數(shù)據(jù)庫編程所需的JDBC類。大多數(shù)情況下,使用 import java.sql.* 就足夠了,如下所示:

//STEP 1. Import required packages
import java.sql.*;

2. 注冊JDBC驅(qū)動(dòng)程序

需要初始化驅(qū)動(dòng)程序,這樣就可以打開與數(shù)據(jù)庫的通信。以下是代碼片段實(shí)現(xiàn)這一目標(biāo):

//STEP 2: Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");

3. 打開一個(gè)連接

使用DriverManager.getConnection()方法來創(chuàng)建一個(gè)Connection對(duì)象,它代表一個(gè)數(shù)據(jù)庫的物理連接,如下所示:

//STEP 3: Open a connection
//  Database credentials
static final String USER = "root";
static final String PASS = "pwd123456";
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);

4. 執(zhí)行一個(gè)查詢

需要使用一個(gè)類型為StatementPreparedStatement的對(duì)象,并提交一個(gè)SQL語句到數(shù)據(jù)庫執(zhí)行查詢。如下:

//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, first, last, age FROM Employees";
ResultSet rs = stmt.executeQuery(sql);

如果要執(zhí)行一個(gè)SQL語句:UPDATE,INSERTDELETE語句,那么需要下面的代碼片段:

//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "DELETE FROM Employees";
ResultSet rs = stmt.executeUpdate(sql);

5. 從結(jié)果集中提取數(shù)據(jù)

這一步中演示如何從數(shù)據(jù)庫中獲取查詢結(jié)果的數(shù)據(jù)??梢允褂眠m當(dāng)?shù)?code>ResultSet.getXXX()方法來檢索的數(shù)據(jù)結(jié)果如下:

//STEP 5: Extract data from result set
while(rs.next()){
    //Retrieve by column name
    int id  = rs.getInt("id");
    int age = rs.getInt("age");
    String first = rs.getString("first");
    String last = rs.getString("last");

    //Display values
    System.out.print("ID: " + id);
    System.out.print(", Age: " + age);
    System.out.print(", First: " + first);
    System.out.println(", Last: " + last);
}

6. 清理環(huán)境資源

在使用JDBC與數(shù)據(jù)交互操作數(shù)據(jù)庫中的數(shù)據(jù)后,應(yīng)該明確地關(guān)閉所有的數(shù)據(jù)庫資源以減少資源的浪費(fèi),對(duì)依賴于JVM的垃圾收集如下:

//STEP 6: Clean-up environment
rs.close();
stmt.close();
conn.close();

第一個(gè)JDBC 程序?qū)嵗?/h2>

基于上面的步驟,我們可以綜合示例代碼,您可以使用以下代碼作為模板來編寫JDBC代碼。

注意:此示例代碼基于環(huán)境和數(shù)據(jù)庫環(huán)境設(shè)置完成的前提下使用。

//STEP 1. Import required packages
import java.sql.*;

public class FirstExample {
   // JDBC driver name and database URL
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql://localhost/test";

   //  Database credentials -- 數(shù)據(jù)庫名和密碼自己修改
   static final String USER = "username";
   static final String PASS = "password";

   public static void main(String[] args) {
   Connection conn = null;
   Statement stmt = null;
   try{
      //STEP 2: Register JDBC driver
      Class.forName("com.mysql.jdbc.Driver");

      //STEP 3: Open a connection
      System.out.println("Connecting to database...");
      conn = DriverManager.getConnection(DB_URL,USER,PASS);

      //STEP 4: Execute a query
      System.out.println("Creating statement...");
      stmt = conn.createStatement();
      String sql;
      sql = "SELECT id, first, last, age FROM Employees";
      ResultSet rs = stmt.executeQuery(sql);

      //STEP 5: Extract data from result set
      while(rs.next()){
         //Retrieve by column name
         int id  = rs.getInt("id");
         int age = rs.getInt("age");
         String first = rs.getString("first");
         String last = rs.getString("last");

         //Display values
         System.out.print("ID: " + id);
         System.out.print(", Age: " + age);
         System.out.print(", First: " + first);
         System.out.println(", Last: " + last);
      }
      //STEP 6: Clean-up environment
      rs.close();
      stmt.close();
      conn.close();
   }catch(SQLException se){
      //Handle errors for JDBC
      se.printStackTrace();
   }catch(Exception e){
      //Handle errors for Class.forName
      e.printStackTrace();
   }finally{
      //finally block used to close resources
      try{
         if(stmt!=null)
            stmt.close();
      }catch(SQLException se2){
      }// nothing we can do
      try{
         if(conn!=null)
            conn.close();
      }catch(SQLException se){
         se.printStackTrace();
      }//end finally try
   }//end try
   System.out.println("Goodbye!");
}//end main
}//end FirstExample - by www.yiibai.com

如果使用IDE,可將上面代碼可放在IDE(如:Eclipse/Netbeans)中加入mysql-connector-java-5.1.37-bin.jar 庫并執(zhí)行。

如果手動(dòng)編譯,需要把上面代碼存放到 F:\worksp\jdbc\FirstExample.java 文件中,并創(chuàng)建一個(gè)目錄:F:\worksp\jdbc\libs,把下載的mysql-connector-java-5.1.40-bin.jar庫(下載地址:http://downloads.mysql.com/archives/c-j/)放入到 F:\worksp\jdbc\libs 目錄中。

使用命令行編譯Java程序并加載指定目錄中的Jar包(mysql-connector-java-5.1.40-bin.jar),現(xiàn)在編譯上面的例子如下:

F:\worksp\jdbc> javac -Djava.ext.dirs=F:\worksp\jdbc\libs FirstExample.java
F:\worksp\jdbc>

當(dāng)運(yùn)行FirstExample后,它會(huì)產(chǎn)生類似以下結(jié)果:

F:\worksp\jdbc> java -Djava.ext.dirs=F:\worksp\jdbc\libs FirstExample
Connecting to database...
Creating statement...
ID: 100, Age: 18, First: Zara, Last: Ali
ID: 101, Age: 25, First: Mahnaz, Last: Fatma
ID: 102, Age: 30, First: Zaid, Last: Khan
ID: 103, Age: 28, First: Sumit, Last: Mittal
F:\worksp\jdbc>

SQLException中的方法

一個(gè)SQLException類既可以發(fā)生在驅(qū)動(dòng)程序和數(shù)據(jù)庫中。當(dāng)這樣的異常時(shí),SQLException類型的對(duì)象將被傳遞到catch子句。
通過SQLException對(duì)象有以下幾種方法可用于獲取更多的關(guān)于異常的信息:

方法 描述
getErrorCode() 獲取與異常關(guān)聯(lián)的錯(cuò)誤代碼
getMessage() 獲取JDBC驅(qū)動(dòng)程序的錯(cuò)誤處理錯(cuò)誤消息,或獲取Oracle錯(cuò)誤代碼和數(shù)據(jù)庫的錯(cuò)誤消息。
getSQLState() 獲取XOPEN SQLSTATE字符串。對(duì)于JDBC驅(qū)動(dòng)程序錯(cuò)誤,從該方法返回的可能是無用的信息。對(duì)于一個(gè)數(shù)據(jù)庫錯(cuò)誤,返回一個(gè)五位的XOPEN SQLSTATE代碼。這種方法可以返回null。
getNextException() 獲取異常鏈中的下一個(gè)Exception對(duì)象
printStackTrace() 打印當(dāng)前的異常,或也可以拋出,并回溯到標(biāo)準(zhǔn)錯(cuò)誤流
printStackTrace(PrintStream s) 打印此拋出對(duì)象及其回溯到指定的打印流
printStackTrace(PrintWriter w) 打印此拋出對(duì)象及其回溯到指定打印寫入流

通過利用從Exception對(duì)象提供的信息,可以捕獲一個(gè)異常,并適當(dāng)?shù)乩^續(xù)運(yùn)行程序。這是一個(gè)try塊中的一般形式:

try {
   // Your risky code goes between these curly braces!!!
}
catch(Exception ex) {
   // Your exception handling code goes between these 
   // curly braces, similar to the exception clause 
   // in a PL/SQL block.
}
finally {
   // Your must-always-be-executed code goes between these 
   // curly braces. Like closing database connection.
}

JDBC數(shù)據(jù)類型

下表列出了默認(rèn)的JDBC數(shù)據(jù)類型與Java數(shù)據(jù)類型轉(zhuǎn)換,當(dāng)使用PreparedStatementCallableStatement對(duì)象時(shí)可調(diào)用setXXX()方法或ResultSet.updateXXX()方法。

SQL JDBC/Java setXXX updateXXX
VARCHAR java.lang.String setString updateString
CHAR java.lang.String setString updateString
LONGVARCHAR java.lang.String setString updateString
BIT boolean setBoolean updateBoolean
NUMERIC java.math.BigDecimal setBigDecimal updateBigDecimal
TINYINT byte setByte updateByte
SMALLINT short setShort updateShort
INTEGER int setInt updateInt
BIGINT long setLong updateLong
REAL float setFloat updateFloat
FLOAT float setFloat updateFloat
DOUBLE double setDouble updateDouble
VARBINARY byte[ ] setBytes updateBytes
BINARY byte[ ] setBytes updateBytes
DATE java.sql.Date setDate updateDate
TIME java.sql.Time setTime updateTime
TIMESTAMP java.sql.Timestamp setTimestamp updateTimestamp
CLOB java.sql.Clob setClob updateClob
BLOB java.sql.Blob setBlob updateBlob
ARRAY java.sql.Array setARRAY updateARRAY
REF java.sql.Ref SetRef updateRef
STRUCT java.sql.Struct SetStruct updateStruct

JDBC3.0中增強(qiáng)支持BLOB,CLOBARRAY,REF等數(shù)據(jù)類型。ResultSet對(duì)象可調(diào)用UPDATEBLOB(),updateCLOB(),updateArray()updateRef()方法,使您可以在數(shù)據(jù)庫服務(wù)器上直接操作相應(yīng)的數(shù)據(jù)。

對(duì)于setXXX()updateXXX()方法,可以轉(zhuǎn)換成特定的Java類型到特定的JDBC數(shù)據(jù)類型。而使用setObject()updateObject()方法,幾乎所有的Java類型映射到JDBC數(shù)據(jù)類型。

ResultSet對(duì)象提供相應(yīng)的getXXX()方法為每個(gè)數(shù)據(jù)類型來檢索列值。每一種類型方法,可以使用與列名或由列的序號(hào)位置來獲取列的數(shù)據(jù)。

SQL JDBC/Java setXXX getXXX
VARCHAR java.lang.String setString getString
CHAR java.lang.String setString getString
LONGVARCHAR java.lang.String setString getString
BIT boolean setBoolean getBoolean
NUMERIC java.math.BigDecimal setBigDecimal getBigDecimal
TINYINT byte setByte getByte
SMALLINT short setShort getShort
INTEGER int setInt getInt
BIGINT long setLong getLong
REAL float setFloat getFloat
FLOAT float setFloat getFloat
DOUBLE double setDouble getDouble
VARBINARY byte[ ] setBytes getBytes
BINARY byte[ ] setBytes getBytes
DATE java.sql.Date setDate getDate
TIME java.sql.Time setTime getTime
TIMESTAMP java.sql.Timestamp setTimestamp getTimestamp
CLOB java.sql.Clob setClob getClob
BLOB java.sql.Blob setBlob getBlob
ARRAY java.sql.Array setARRAY getARRAY
REF java.sql.Ref SetRef getRef
STRUCT java.sql.Struct SetStruct getStruct

JDBC批量處理

批處理允許執(zhí)行一個(gè)批處理組相關(guān)的SQL語句,并將其一次提交到數(shù)據(jù)庫中執(zhí)行。當(dāng)幾個(gè)SQL語句一次發(fā)送到數(shù)據(jù)庫中時(shí),可以減少通信開銷,從而提高性能。

  • JDBC驅(qū)動(dòng)程序不支持此功能。您應(yīng)該使用DatabaseMetaData.supportsBatchUpdates()方法來確定目標(biāo)數(shù)據(jù)庫支持批量更新處理。如果JDBC驅(qū)動(dòng)程序支持此功能,則該方法返回true。
  • addBatch()方法是PreparedStatementCallableStatementis類中用于添加單個(gè)語句的批處理的聲明。 executeBatch()將開始將所有語句組合到一起并執(zhí)行。

  • executeBatch()將返回一個(gè)整數(shù)數(shù)組,每個(gè)數(shù)組元素的表示為相應(yīng)的更新語句的更新計(jì)數(shù)。

  • 添加語句進(jìn)行批處理時(shí),可以使用clearBatch()方法刪除它們。此方法將刪除addBatch()方法添加的所有語句。但是不能有選擇性地選擇某個(gè)語句來刪除。

JDBC數(shù)據(jù)流

PreparedStatement對(duì)象有能力使用提供參數(shù)數(shù)據(jù)的輸入和輸出流。這使您可以將整個(gè)文件到數(shù)據(jù)庫中,可容納較大的值,如CLOBBLOB數(shù)據(jù)類型的列。

有下列方法可用于流數(shù)據(jù):

  1. setAsciiStream(): 此方法用于提供大的ASCII數(shù)據(jù)值。
  2. setCharacterStream(): 此方法用于提供大的UNICODE數(shù)據(jù)值。
  3. setBinaryStream(): 使用此方法用于提供大的二進(jìn)制數(shù)據(jù)值。

setXXXStream()方法需要一個(gè)額外的參數(shù),文件大小(除了參數(shù)占位符)。此參數(shù)通知應(yīng)發(fā)送多少數(shù)據(jù)到數(shù)據(jù)庫來使用流的驅(qū)動(dòng)程序。

對(duì)于一個(gè)詳細(xì)的關(guān)于所有這些概念,這里只是一個(gè)簡單的入門教程,還需要讀者去學(xué)習(xí)完整的教程,有關(guān)JDBC的后續(xù)教程,可以從左側(cè)文章中了解和學(xué)習(xí)。