📜  JDBC-快速指南

📅  最后修改于: 2020-11-13 04:43:53             🧑  作者: Mango


什么是JDBC?

JDBC代表的J ava d ATA b ASEÇonnectivity,其是用于以Java编程语言和广泛的数据库之间独立于数据库的连接的标准Java API。

JDBC库包括用于通常与数据库使用相关联的每个任务的API:

  • 与数据库建立连接

  • 创建SQL或MySQL语句

  • 在数据库中执行SQL或MySQL查询

  • 查看和修改结果记录

先决条件:

您需要对以下两个主题有充分的了解以学习JDBC:

JDBC-环境设置:

确保已完成以下设置:

  • JAVA核心安装

  • SQL或MySQL数据库安装

除上述内容外,您还需要设置一个数据库,该数据库将用于您的项目。假设这是EMP,并且您已在同一数据库内的表employees上创建。

创建JDBC应用程序:

构建JDBC应用程序涉及六个步骤,我将在本教程中对此进行简要介绍:

导入软件包:

这要求您包括包含数据库编程所需的JDBC类的软件包。通常,使用import java.sql。*可以满足以下要求:

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

注册JDBC驱动程序:

这要求您初始化驱动程序,以便可以打开与数据库的通信通道。以下是实现此目的的代码段:

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

打开一个连接:

这需要使用DriverManager.getConnection()方法创建一个Connection对象,该对象表示与数据库的物理连接,如下所示:

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

执行查询:

这需要使用Statement或PreparedStatement类型的对象来生成SQL语句并将其提交到数据库,如下所示:

//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);

如果需要一个SQL UPDATE,INSERT或DELETE语句,那么将需要以下代码片段:

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

从结果集中提取数据:

如果您要从数据库中获取数据,则需要执行此步骤。您可以使用适当的ResultSet.getXXX()方法从结果集中检索数据,如下所示:

//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);
}

清理环境:

您应该显式关闭所有数据库资源,而不是依赖JVM的垃圾回收,如下所示:

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

第一个JDBC程序:

基于上述步骤,我们可以得到以下合并的示例代码,可以在编写JDBC代码时将其用作模板:

本示例代码是根据环境和在环境一章中完成的数据库设置编写的。

//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/EMP";

   //  Database credentials
   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

现在让我们编译上面的示例,如下所示:

C:\>javac FirstExample.java
C:\>

当您运行FirstExample时,它将产生以下结果:

C:\>java 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
C:\>

SQLException方法:

在驱动程序和数据库中都可能发生SQLException。发生此类异常时,会将SQLException类型的对象传递给catch子句。

传递的SQLException对象具有以下可用于检索有关异常的其他信息的方法:

Method Description
getErrorCode( ) Gets the error number associated with the exception.
getMessage( ) Gets the JDBC driver’s error message for an error handled by the driver or gets the Oracle error number and message for a database error.
getSQLState( ) Gets the XOPEN SQLstate string. For a JDBC driver error, no useful information is returned from this method. For a database error, the five-digit XOPEN SQLstate code is returned. This method can return null.
getNextException( ) Gets the next Exception object in the exception chain.
printStackTrace( ) Prints the current exception, or throwable, and its backtrace to a standard error stream.
printStackTrace(PrintStream s) Prints this throwable and its backtrace to the print stream you specify.
printStackTrace(PrintWriter w) Prints this throwable and its backtrace to the print writer you specify.

通过利用Exception对象提供的信息,您可以捕获异常并适当地继续执行程序。这是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-数据类型:

下表总结了当您调用PreparedStatement或CallableStatement对象的setXXX()方法或ResultSet.updateXXX()方法时,Java数据类型转换为的默认JDBC数据类型。

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

JDBC 3.0增强了对BLOB,CLOB,ARRAY和REF数据类型的支持。 ResultSet对象现在具有updateBLOB(),updateCLOB(),updateArray()和updateRef()方法,使您可以直接操作服务器上的相应数据。

使用setXXX()和updateXXX()方法可以将特定的Java类型转换为特定的JDBC数据类型。使用setObject()和updateObject()方法,您可以将几乎所有Java类型映射到JDBC数据类型。

ResultSet对象为每种数据类型提供相应的getXXX()方法以检索列值。每种方法都可以与列名或按其顺序位置一起使用。

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-批处理:

批处理允许您将相关的SQL语句分组为一个批处理,并通过一次调用将其提交给数据库。

当您一次将多个SQL语句发送到数据库时,可以减少通信开销,从而提高性能。

  • 不需要JDBC驱动程序即可支持此功能。您应该使用DatabaseMetaData.supportsBatchUpdates()方法来确定目标数据库是否支持批量更新处理。如果您的JDBC驱动程序支持此功能,则该方法返回true。

  • Statement,PreparedStatementCallableStatementaddBatch()方法用于将单个语句添加到批处理中。 executeBatch()用于开始执行分组在一起的所有语句。

  • executeBatch()返回一个整数数组,该数组的每个元素代表相应更新语句的更新计数。

  • 正如可以将语句添加到批处理中一样,可以使用clearBatch()方法将其删除。此方法删除使用addBatch()方法添加的所有语句。但是,您不能有选择地选择要删除的语句。

JDBC-流数据:

PreparedStatement对象具有使用输入和输出流提供参数数据的能力。这使您可以将整个文件放入可以容纳较大值的数据库列中,例如CLOB和BLOB数据类型。

有以下几种可用于流数据的方法:

  • setAsciiStream():此方法用于提供较大的ASCII值。

  • setCharacterStream():此方法用于提供较大的UNICODE值。

  • setBinaryStream():此方法用于提供较大的二进制值。

setXXXStream()方法除了参数占位符外,还需要一个额外的参数,即文件大小。此参数通知驱动程序应使用流将多少数据发送到数据库。

有关所有这些概念的详细信息,您需要阅读完整的教程。