JDBC - 快速指南


JDBC - 简介

什么是 JDBC?

JDBC代表Java数据库连接,它是一种标准Java API,用于 Java 编程语言和各种数据库之间的独立于数据库的连接

JDBC 库包含用于下面提到的通常与数据库使用相关的每项任务的 API。

  • 建立与数据库的连接。

  • 创建 SQL 或 MySQL 语句。

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

  • 查看和修改结果记录。

从根本上来说,JDBC 是一个提供一整套接口的规范,允许对底层数据库进行可移植的访问。Java 可用于编写不同类型的可执行文件,例如 -

  • Java应用程序

  • Java 小程序

  • Java Servlet

  • Java ServerPages (JSP)

  • 企业 JavaBean (EJB)。

所有这些不同的可执行文件都能够使用 JDBC 驱动程序访问数据库,并利用存储的数据。

JDBC 提供与 ODBC 相同的功能,允许 Java 程序包含与数据库无关的代码。

先决条件

在进一步进行之前,您需要很好地理解以下两个主题 -

JDBC架构

JDBC API 支持数据库访问的两层和三层处理模型,但一般来说,JDBC 架构由两层组成 -

  • JDBC API - 这提供了应用程序到 JDBC 管理器的连接。

  • JDBC 驱动程序 API - 这支持 JDBC 管理器到驱动程序的连接。

JDBC API 使用驱动程序管理器和特定于数据库的驱动程序来提供与异构数据库的透明连接。

JDBC 驱动程序管理器确保使用正确的驱动程序来访问每个数据源。驱动程序管理器能够支持连接到多个异构数据库的多个并发驱动程序。

以下是架构图,显示了驱动程序管理器相对于 JDBC 驱动程序和 Java 应用程序的位置 -

JDBC架构

通用 JDBC 组件

JDBC API 提供以下接口和类 -

  • DriverManager - 此类管理数据库驱动程序列表。使用通信子协议将来自 java 应用程序的连接请求与正确的数据库驱动程序相匹配。第一个识别 JDBC 下某个子协议的驱动程序将用于建立数据库连接。

  • 驱动程序- 该接口处理与数据库服务器的通信。您很少会直接与 Driver 对象交互。相反,您可以使用 DriverManager 对象来管理此类对象。它还抽象了与使用驱动程序对象相关的细节。

  • 连接- 该接口包含用于联系数据库的所有方法。连接对象代表通信上下文,即与数据库的所有通信仅通过连接对象进行。

  • 语句- 您使用从此接口创建的对象将 SQL 语句提交到数据库。一些派生接口除了执行存储过程之外还接受参数。

  • ResultSet - 这些对象保存使用 Statement 对象执行 SQL 查询后从数据库检索的数据。它充当迭代器,允许您移动其数据。

  • SQLException - 此类处理数据库应用程序中发生的任何错误。

JDBC 4.0 包

java.sql 和 javax.sql 是 JDBC 4.0 的主要包。这是撰写本教程时的最新 JDBC 版本。它提供了与数据源交互的主要类。

这些软件包中的新功能包括以下方面的变化 -

  • 自动数据库驱动程序加载。

  • 异常处理改进。

  • 增强的 BLOB/CLOB 功能。

  • 连接和语句接口增强。

  • 国家字符集支持。

  • SQL ROWID 访问。

  • SQL 2003 XML 数据类型支持。

  • 注释。

JDBC - SQL 语法

结构查询语言(SQL) 是一种标准化语言,允许您对数据库执行操作,例如创建条目、读取内容、更新内容和删除条目。

几乎所有您可能使用的数据库都支持 SQL,它允许您独立于底层数据库编写数据库代码。

本章概述了 SQL,这是理解 JDBC 概念的先决条件。学完本章后,您将能够从数据库中创建、创建读取更新删除(通常称为CRUD操作)数据。

要详细了解 SQL,您可以阅读我们的MySQL 教程

创建数据库

CREATE DATABASE 语句用于创建新数据库。语法是 -

SQL> CREATE DATABASE DATABASE_NAME;

例子

以下 SQL 语句创建一个名为 EMP 的数据库 -

SQL> CREATE DATABASE EMP;

删除数据库

DROP DATABASE 语句用于删除现有数据库。语法是 -

SQL> DROP DATABASE DATABASE_NAME;

注意- 要创建或删除数据库,您应该拥有数据库服务器的管理员权限。请注意,删除数据库会丢失数据库中存储的所有数据。

创建表

CREATE TABLE 语句用于创建新表。语法是 -

SQL> CREATE TABLE table_name
(
   column_name column_data_type,
   column_name column_data_type,
   column_name column_data_type
   ...
);

例子

以下 SQL 语句创建一个名为Employees 的表,其中包含四列 -

SQL> CREATE TABLE Employees
(
   id INT NOT NULL,
   age INT NOT NULL,
   first VARCHAR(255),
   last VARCHAR(255),
   PRIMARY KEY ( id )
);

掉落表

DROP TABLE 语句用于删除现有表。语法是 -

SQL> DROP TABLE table_name;

例子

以下 SQL 语句删除名为Employees 的表 -

SQL> DROP TABLE Employees;

插入数据

INSERT 的语法类似于以下内容,其中 column1、column2 等表示要出现在相应列中的新数据 -

SQL> INSERT INTO table_name VALUES (column1, column2, ...);

例子

以下 SQL INSERT 语句在之前创建的员工数据库中插入一个新行 -

SQL> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');

选择数据

SELECT 语句用于从数据库中检索数据。SELECT 的语法是 -

SQL> SELECT column_name, column_name, ...
     FROM table_name
     WHERE conditions;

WHERE 子句可以使用比较运算符,例如 =、!=、<、>、<= 和 >=,以及 BETWEEN 和 LIKE 运算符。

例子

以下 SQL 语句从员工表中选择年龄、第一列和最后一列,其中 id 列为 100 -

SQL> SELECT first, last, age 
     FROM Employees 
     WHERE id = 100;

以下 SQL 语句从员工表中选择年龄、第一列和最后一列,其中第一列包含Zara -

SQL> SELECT first, last, age 
     FROM Employees 
     WHERE first LIKE '%Zara%';

更新数据

UPDATE语句用于更新数据。UPDATE 的语法是 -

SQL> UPDATE table_name
     SET column_name = value, column_name = value, ...
     WHERE conditions;

WHERE 子句可以使用比较运算符,例如 =、!=、<、>、<= 和 >=,以及 BETWEEN 和 LIKE 运算符。

例子

以下 SQL UPDATE 语句更改 id 为 100 的员工的年龄列 -

SQL> UPDATE Employees SET age=20 WHERE id=100;

删除数据

DELETE 语句用于从表中删除数据。DELETE 的语法是 -

SQL> DELETE FROM table_name WHERE conditions;

WHERE 子句可以使用比较运算符,例如 =、!=、<、>、<= 和 >=,以及 BETWEEN 和 LIKE 运算符。

例子

以下 SQL DELETE 语句删除 id 为 100 的员工的记录 -

SQL> DELETE FROM Employees WHERE id=100;

JDBC - 环境

要开始使用 JDBC 进行开发,您应该按照下面所示的步骤设置 JDBC 环境。我们假设您正在 Windows 平台上工作。

安装Java

Java SE 可供免费下载。要下载,请单击此处,请下载与您的操作系统兼容的版本。

按照说明下载 Java,然后运行​​.exe以在您的计算机上安装 Java。在计算机上安装 Java 后,您需要设置环境变量以指向正确的安装目录。

设置 Windows 2000/XP 的路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -

  • 右键单击“我的电脑”并选择“属性”。

  • 单击“高级”选项卡下的“环境变量”按钮。

  • 现在,编辑“Path”变量并在其末尾添加 Java 可执行文件目录的路径。例如,如果路径当前设置为C:\Windows\System32,则按以下方式编辑它

C:\Windows\System32;c:\Program Files\java\jdk\bin

设置Windows 95/98/ME的路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录中 -

  • 编辑“C:\autoexec.bat”文件并在末尾添加以下行 -

SET PATH = %PATH%;C:\Program Files\java\jdk\bin

设置 Linux、UNIX、Solaris、FreeBSD 的路径

应将环境变量 PATH 设置为指向 Java 二进制文件的安装位置。如果您在执行此操作时遇到问题,请参阅您的 shell 文档。

例如,如果您使用 bash 作为 shell,那么您可以在.bashrc末尾添加以下行-

export PATH = /path/to/java:$PATH'

当您安装 J2SE 开发工具包时,您会自动获得 JDBC 包java.sqljavax.sql

安装数据库

当然,您需要的最重要的东西是一个实际运行的数据库,其中包含可以查询和修改的表。

安装最适合您的数据库。您可以有很多选择,最常见的是 -

  • MySQL DB - MySQL 是一个开源数据库。您可以从MySQL 官方网站下载它。我们建议下载完整的 Windows 安装。

    此外,下载并安装MySQL Administrator以及MySQL Query Browser。这些是基于 GUI 的工具,可以让您的开发变得更加容易。

    最后,下载MySQL Connector/J(MySQL JDBC 驱动程序)并将其解压到一个方便的目录中。出于本教程的目的,我们假设您已将驱动程序安装在 C:\Program Files\MySQL\mysql-connector-java-5.1.8 中。

    因此,将 CLASSPATH 变量设置为 C:\Program Files\MySQL\mysql-connector-java-5.1.8\mysql-connector-java-5.1.8-bin.jar。您的驱动程序版本可能会因您的安装而异。

设置数据库凭证

当我们安装 MySQL 数据库时,其管理员 ID 被设置为root,并且可以设置您选择的密码。

使用 root ID 和密码,您可以创建另一个用户 ID 和密码,也可以将 root ID 和密码用于 JDBC 应用程序。

有各种数据库操作,例如数据库创建和删除,需要管理员 ID 和密码。

对于 JDBC 教程的其余部分,我们将使用 MySQL 数据库,其中guest作为 ID,guest123作为密码。

如果您没有足够的权限来创建新用户,那么您可以要求数据库管理员 (DBA) 为您创建用户 ID 和密码。

创建数据库

要创建TUTORIALSPOINT数据库,请使用以下步骤 -

步骤1

打开命令提示符并更改为安装目录,如下所示 -

C:\>
C:\>cd Program Files\MySQL\bin
C:\Program Files\MySQL\bin>

注意- mysqld.exe的路径可能会有所不同,具体取决于系统上 MySQL 的安装位置。您还可以查看有关如何启动和停止数据库服务器的文档。

第2步

如果数据库服务器尚未运行,请执行以下命令来启动它。

C:\Program Files\MySQL\bin>mysqld
C:\Program Files\MySQL\bin>

步骤3

通过执行以下命令创建TUTORIALSPOINT数据库 -

C:\Program Files\MySQL\bin> mysqladmin create TUTORIALSPOINT -u guest -p
Enter password: ********
C:\Program Files\MySQL\bin>

创建表

要在 TUTORIALSPOINT 数据库中创建员工表,请使用以下步骤 -

步骤1

打开命令提示符并更改为安装目录,如下所示 -

C:\>
C:\>cd Program Files\MySQL\bin
C:\Program Files\MySQL\bin>

第2步

登录数据库如下 -

C:\Program Files\MySQL\bin>mysql -u guest -p
Enter password: ********
mysql>

步骤3

创建表Employees如下 -

mysql> use TUTORIALSPOINT;
mysql> create table Employees
    -> (
    -> id int not null,
    -> age int not null,
    -> first varchar (255),
    -> last varchar (255)
    -> );
Query OK, 0 rows affected (0.08 sec)
mysql>

创建数据记录

最后,您在 Employee 表中创建几条记录,如下所示 -

mysql> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');
Query OK, 1 row affected (0.05 sec)

mysql> INSERT INTO Employees VALUES (101, 25, 'Mahnaz', 'Fatma');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Employees VALUES (102, 30, 'Zaid', 'Khan');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Employees VALUES (103, 28, 'Sumit', 'Mittal');
Query OK, 1 row affected (0.00 sec)

mysql>

要完整了解 MySQL 数据库,请学习MySQL 教程

现在您已准备好开始尝试 JDBC。下一章为您提供了有关 JDBC 编程的示例。

JDBC - 示例代码

本章提供了如何创建简单的 JDBC 应用程序的示例。这将向您展示如何打开数据库连接、执行 SQL 查询并显示结果。

此模板示例中提到的所有步骤将在本教程的后续章节中进行解释。

创建 JDBC 应用程序

构建 JDBC 应用程序涉及以下六个步骤 -

  • 导入包- 要求您包含包含数据库编程所需的 JDBC 类的包。大多数情况下,使用import java.sql.*就足够了。

  • 打开连接- 需要使用DriverManager.getConnection()方法创建一个 Connection 对象,该对象表示与数据库的物理连接。

  • 执行查询- 需要使用 Statement 类型的对象来构建 SQL 语句并将其提交到数据库。

  • 从结果集中提取数据- 要求您使用适当的ResultSet.getXXX()方法从结果集中检索数据。

  • 清理环境- 需要显式关闭所有数据库资源,而不是依赖 JVM 的垃圾收集。

示例代码

当您将来需要创建自己的 JDBC 应用程序时,此示例示例可以用作模板

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

将以下示例复制并粘贴到 FirstExample.java 中,编译并运行如下 -

import java.sql.*;

public class FirstExample {
   static final String DB_URL = "jdbc:mysql://localhost/TUTORIALSPOINT";
   static final String USER = "guest";
   static final String PASS = "guest123";
   static final String QUERY = "SELECT id, first, last, age FROM Employees";

   public static void main(String[] args) {
      // Open a connection
      try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(QUERY);) {
         // Extract data from result set
         while (rs.next()) {
            // Retrieve by column name
            System.out.print("ID: " + rs.getInt("id"));
            System.out.print(", Age: " + rs.getInt("age"));
            System.out.print(", First: " + rs.getString("first"));
            System.out.println(", Last: " + rs.getString("last"));
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } 
   }
}

现在让我们按如下方式编译上面的示例 -

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

JDBC - 驱动程序类型

什么是 JDBC 驱动程序?

JDBC 驱动程序实现 JDBC API 中定义的接口,用于与数据库服务器交互。

例如,使用 JDBC 驱动程序使您能够打开数据库连接并通过发送 SQL 或数据库命令然后使用 Java 接收结果来与之交互。

JDK 附带的Java.sql包包含各种已定义Behave类,并且它们的实际实现是在第三方驱动程序中完成的。第三方供应商在其数据库驱动程序中实现java.sql.Driver接口。

JDBC 驱动程序类型

由于 Java 运行的操作系统和硬件平台多种多样,因此 JDBC 驱动程序的实现也各不相同。Sun 将实现类型分为四类:类型 1、类型 2、类型 3 和类型 4,解释如下 -

类型 1 - JDBC-ODBC 桥驱动程序

在类型 1 驱动程序中,使用 JDBC 桥来访问安装在每台客户端计算机上的 ODBC 驱动程序。使用 ODBC 需要在系统上配置代表目标数据库的数据源名称 (DSN)。

当 Java 首次出现时,这是一个有用的驱动程序,因为大多数数据库仅支持 ODBC 访问,但现在仅建议在实验使用或没有其他替代方案时使用这种类型的驱动程序。

DBMS 驱动程序类型 1

JDK 1.2 附带的 JDBC-ODBC Bridge 就是此类驱动程序的一个很好的例子。

类型 2 - JDBC 本机 API

在 Type 2 驱动程序中,JDBC API 调用将转换为本机 C/C++ API 调用,这对于数据库是唯一的。这些驱动程序通常由数据库供应商提供,并以与 JDBC-ODBC 桥相同的方式使用。供应商特定的驱动程序必须安装在每台客户端计算机上。

如果我们更改数据库,则必须更改本机 API,因为它特定于数据库,并且它们现在大多已过时,但您可能会意识到使用 2 型驱动程序可以提高速度,因为它消除了 ODBC 的开销。

DBMS 驱动程序类型 2

Oracle 调用接口 (OCI) 驱动程序是类型 2 驱动程序的一个示例。

类型 3 - JDBC-Net 纯 Java

在类型 3 驱动程序中,使用三层方法来访问数据库。JDBC 客户端使用标准网络套接字与中间件应用程序服务器进行通信。然后中间件应用服务器将套接字信息翻译成DBMS所需的调用格式,并转发给数据库服务器。

这种驱动程序非常灵活,因为它不需要在客户端安装任何代码,并且单个驱动程序实际上可以提供对多个数据库的访问。

DBMS 驱动程序类型 3

您可以将应用程序服务器视为 JDBC“代理”,这意味着它对客户端应用程序进行调用。因此,您需要了解应用程序服务器的配置才能有效地使用此驱动程序类型。

您的应用程序服务器可能使用类型 1、类型 2 或类型 4 驱动程序与数据库进行通信,了解其中的细微差别将会有所帮助。

类型 4 - 100% 纯 Java

在 Type 4 驱动程序中,纯基于 Java 的驱动程序通过套接字连接直接与供应商的数据库进行通信。这是数据库可用的最高性能驱动程序,通常由供应商本身提供。

这种驱动程序非常灵活,您不需要在客户端或服务器上安装特殊的软件。此外,这些驱动程序可以动态下载。

DBMS 驱动程序类型 4

MySQL 的 Connector/J 驱动程序是 Type 4 驱动程序。由于其网络协议的专有性质,数据库供应商通常提供类型 4 驱动程序。

应该使用哪个驱动程序?

如果您要访问一种类型的数据库,例如 Oracle、Sybase 或 IBM,则首选驱动程序类型为 4。

如果您的 Java 应用程序同时访问多种类型的数据库,则类型 3 是首选驱动程序。

在类型 3 或类型 4 驱动程序尚不可用于数据库的情况下,类型 2 驱动程序非常有用。

类型 1 驱动程序不被视为部署级驱动程序,通常仅用于开发和测试目的。

JDBC - 连接

安装适当的驱动程序后,就可以使用 JDBC 建立数据库连接了。

建立 JDBC 连接所涉及的编程相当简单。以下是这四个简单的步骤 -

  • 导入 JDBC 包- 将导入语句添加到 Java 程序中,以导入 Java 代码中所需的类。

  • 注册 JDBC 驱动程序- 此步骤使 JVM 将所需的驱动程序实现加载到内存中,以便它可以满足您的 JDBC 请求。

  • 数据库 URL 公式- 这是为了创建一个格式正确的地址,指向您想要连接的数据库。

  • 创建连接对象- 最后,编写对DriverManager对象的getConnection()方法的调用来建立实际的数据库连接。

导入 JDBC 包

Import语句告诉 Java 编译器在哪里可以找到您在代码中引用的类,并且这些语句被放置在源代码的最开头

要使用标准 JDBC 包(允许您选择、插入、更新和删除 SQL 表中的数据),请将以下导入添加到源代码中 -

import java.sql.* ;  // for standard JDBC programs
import java.math.* ; // for BigDecimal and BigInteger support

注册 JDBC 驱动程序

在使用该驱动程序之前,您必须在程序中注册该驱动程序。注册驱动程序是将Oracle驱动程序的类文件加载到内存中的过程,因此可以将其用作JDBC接口的实现。

您只需在程序中进行一次此注册。您可以通过两种方式之一注册驱动程序。

方法一 - Class.forName()

注册驱动程序最常见的方法是使用 Java 的Class.forName()方法,将驱动程序的类文件动态加载到内存中,内存会自动注册它。此方法更可取,因为它允许您使驱动程序注册可配置且可移植。

以下示例使用 Class.forName( ) 注册 Oracle 驱动程序 -

try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ex) {
   System.out.println("Error: unable to load driver class!");
   System.exit(1);
}

您可以使用getInstance()方法来解决不兼容的 JVM,但是您必须为两个额外的异常编写代码,如下所示 -

try {
   Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch(ClassNotFoundException ex) {
   System.out.println("Error: unable to load driver class!");
   System.exit(1);
catch(IllegalAccessException ex) {
   System.out.println("Error: access problem while loading!");
   System.exit(2);
catch(InstantiationException ex) {
   System.out.println("Error: unable to instantiate driver!");
   System.exit(3);
}

方法二 - DriverManager.registerDriver()

注册驱动程序的第二种方法是使用静态DriverManager.registerDriver()方法。

如果您使用的是不兼容 JDK 的 JVM(例如 Microsoft 提供的 JVM),则应该使用registerDriver()方法。

以下示例使用 registerDriver() 注册 Oracle 驱动程序 -

try {
   Driver myDriver = new oracle.jdbc.driver.OracleDriver();
   DriverManager.registerDriver( myDriver );
}
catch(ClassNotFoundException ex) {
   System.out.println("Error: unable to load driver class!");
   System.exit(1);
}

数据库 URL 制定

加载驱动程序后,您可以使用DriverManager.getConnection()方法建立连接。为了便于参考,让我列出三个重载的 DriverManager.getConnection() 方法 -

  • 获取连接(字符串网址)

  • getConnection(字符串 url, 属性 prop)

  • getConnection(字符串 url, 字符串用户, 字符串密码)

这里每个表单都需要一个数据库URL。数据库 URL 是指向您的数据库的地址。

大多数与建立连接相关的问题都发生在制定数据库 URL 的地方。

下表列出了流行的 JDBC 驱动程序名称和数据库 URL。

关系型数据库管理系统 JDBC 驱动程序名称 网址格式
MySQL com.mysql.jdbc.驱动程序 jdbc:mysql://主机名/ 数据库名
甲骨文公司 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@主机名:端口号:数据库名称
数据库2 COM.ibm.db2.jdbc.net.DB2Driver jdbc:db2:主机名:端口号/数据库名称
赛贝斯 com.sybase.jdbc.SybDriver jdbc:sybase:Tds:主机名: 端口号/数据库名称

URL 格式中所有突出显示的部分都是静态的,您只需根据数据库设置更改其余部分。

创建连接对象

我们列出了三种形式的DriverManager.getConnection()方法来创建连接对象。

使用带有用户名和密码的数据库 URL

getConnection() 最常用的形式要求您传递数据库 URL、用户名密码-

假设您使用 Oracle 的驱动程序,您将为 URL 的数据库部分指定 host:port:databaseName 值。

如果您有一个 TCP/IP 地址为 192.0.0.1、主机名为 amrood 的主机,并且您的 Oracle 侦听器配置为侦听端口 1521,并且您的数据库名称为 EMP,则完整的数据库 URL 将是 -

jdbc:oracle:thin:@amrood:1521:EMP

现在您必须使用适当的用户名和密码调用 getConnection() 方法来获取Connection对象,如下所示 -

String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);

仅使用数据库 URL

DriverManager.getConnection() 方法的第二种形式只需要一个数据库 URL -

DriverManager.getConnection(String url);

然而,在这种情况下,数据库 URL 包括用户名和密码,并具有以下一般形式 -

jdbc:oracle:driver:username/password@database

因此,可以按如下方式创建上述连接 -

String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP";
Connection conn = DriverManager.getConnection(URL);

使用数据库 URL 和属性对象

DriverManager.getConnection() 方法的第三种形式需要数据库 URL 和 Properties 对象 -

DriverManager.getConnection(String url, Properties info);

Properties 对象保存一组关键字-值对。它用于在调用 getConnection() 方法期间将驱动程序属性传递给驱动程序。

要建立与前面示例相同的连接,请使用以下代码 -

import java.util.*;

String URL = "jdbc:oracle:thin:@amrood:1521:EMP";
Properties info = new Properties( );
info.put( "user", "username" );
info.put( "password", "password" );

Connection conn = DriverManager.getConnection(URL, info);

关闭 JDBC 连接

在 JDBC 程序结束时,需要显式关闭与数据库的所有连接以结束每个数据库会话。但是,如果您忘记了,Java 的垃圾收集器将在清理陈旧对象时关闭连接。

依赖垃圾收集,尤其是在数据库编程中,是一种非常糟糕的编程实践。您应该养成始终使用与连接对象关联的 close() 方法关闭连接的习惯。

为了确保连接关闭,您可以在代码中提供“finally”块。无论是否发生异常,finally块都会执行。

要关闭上面打开的连接,您应该调用 close() 方法,如下所示 -

conn.close();

显式关闭连接可以节省 DBMS 资源,这会让数据库管理员感到高兴。

为了更好地理解,我们建议您学习我们的JDBC - 示例代码教程

JDBC - 语句

一旦获得连接,我们就可以与数据库进行交互。JDBC Statement、CallableStatementPreparedStatement接口定义了使您能够发送SQL 或PL/SQL 命令以及从数据库接收数据的方法和属性。

它们还定义了有助于弥合数据库中使用的 Java 和 SQL 数据类型之间的数据类型差异的方法。

下表提供了每个接口用途的摘要,以决定要使用的接口。

接口 推荐用途
陈述 使用它来对数据库进行通用访问。当您在运行时使用静态 SQL 语句时很有用。Statement 接口不能接受参数。
准备好的声明 当您打算多次使用 SQL 语句时,请使用此选项。PreparedStatement 接口在运行时接受输入参数。
可调用语句 当您想要访问数据库存储过程时可以使用它。CallableStatement 接口还可以接受运行时输入参数。

声明对象

创建语句对象

在使用Statement对象执行SQL语句之前,您需要使用Connection对象的createStatement()方法创建一个Statement对象,如下例所示:

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

创建 Statement 对象后,您可以使用它的三个执行方法之一来执行 SQL 语句。

  • boolean execute (String SQL):如果可以检索 ResultSet 对象,则返回布尔值 true;否则,返回 false。使用此方法执行 SQL DDL 语句或需要使用真正的动态 SQL 时。

  • intexecuteUpdate(String SQL) - 返回受 SQL 语句执行影响的行数。使用此方法执行您希望受影响的行数的 SQL 语句 - 例如 INSERT、UPDATE 或 DELETE 语句。

  • ResultSetexecuteQuery(String SQL) - 返回一个 ResultSet 对象。当您希望获得结果集时,请使用此方法,就像使用 SELECT 语句一样。

结束语对象

正如关闭 Connection 对象以节省数据库资源一样,出于同样的原因,您也应该关闭 Statement 对象。

简单地调用 close() 方法即可完成这项工作。如果先关闭 Connection 对象,它也会关闭 Statement 对象。但是,您应该始终显式关闭 Statement 对象以确保正确清理。

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

为了更好地理解,我们建议您学习语句 - 示例教程

ReadyStatement 对象

PreparedStatement接口扩展了Statement 接口,它为您提供了附加功能并且与通用Statement 对象相比具有一些优势。

该语句使您能够灵活地动态提供参数。

创建PreparedStatement对象

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

JDBC 中的所有参数均由?表示 符号,称为参数标记。在执行 SQL 语句之前,您必须为每个参数提供值。

setXXX ()方法将值绑定到参数,其中XXX表示您希望绑定到输入参数的值的 Java 数据类型。如果忘记提供值,您将收到 SQLException。

每个参数标记都由其顺序位置引用。第一个标记表示位置 1,下一个标记表示位置 2,依此类推。此方法与 Java 数组索引不同,Java 数组索引从 0 开始。

所有与数据库交互的Statement对象方法(a)execute()、(b)executeQuery()和(c)executeUpdate()也适用于PreparedStatement对象。然而,这些方法被修改为使用可以输入参数的SQL语句。

关闭PreparedStatement对象

正如您关闭 Statement 对象一样,出于同样的原因,您也应该关闭PreparedStatement 对象。

简单地调用 close() 方法即可完成这项工作。如果您先关闭 Connection 对象,它也会关闭PreparedStatement 对象。但是,您应该始终显式关闭PreparedStatement 对象以确保正确的清理。

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   pstmt.close();
}

为了更好地理解,让我们研究一下准备 - 示例代码

CallableStatement 对象

正如Connection 对象创建Statement 和PreparedStatement 对象一样,它也创建CallableStatement 对象,该对象将用于执行对数据库存储过程的调用。

创建 CallableStatement 对象

假设您需要执行以下 Oracle 存储过程 -

CREATE OR REPLACE PROCEDURE getEmpName 
   (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END;

注意- 上面的存储过程是为 Oracle 编写的,但我们正在使用 MySQL 数据库,因此,让我们为 MySQL 编写相同的存储过程,如下所示,以在 EMP 数据库中创建它 -

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
   (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END $$

DELIMITER ;

存在三种类型的参数:IN、OUT 和 INOUT。PreparedStatement 对象仅使用 IN 参数。CallableStatement 对象可以使用所有这三个。

以下是每个的定义 -

范围 描述
创建 SQL 语句时其值未知的参数。您可以使用 setXXX() 方法将值绑定到 IN 参数。
出去 其值由它返回的 SQL 语句提供的参数。您可以使用 getXXX() 方法从 OUT 参数中检索值。
进出 提供输入值和输出值的参数。您可以使用 setXXX() 方法绑定变量,并使用 getXXX() 方法检索值。

以下代码片段显示了如何使用Connection.prepareCall()方法基于前面的存储过程实例化CallableStatement对象 -

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

字符串变量 SQL,表示带有参数占位符的存储过程。

使用CallableStatement 对象与使用PreparedStatement 对象非常相似。在执行语句之前,您必须将值绑定到所有参数,否则您将收到 SQLException。

如果您有 IN 参数,只需遵循适用于PreparedStatement 对象的相同规则和技术即可;使用与您要绑定的 Java 数据类型相对应的 setXXX() 方法。

当您使用 OUT 和 INOUT 参数时,您必须使用附加的 CallableStatement 方法,registerOutParameter()。registerOutParameter() 方法将 JDBC 数据类型绑定到存储过程预期返回的数据类型。

调用存储过程后,您可以使用适当的 getXXX() 方法从 OUT 参数中检索值。此方法将 SQL 类型的检索值转换为 Java 数据类型。

关闭 CallableStatement 对象

正如您关闭其他 Statement 对象一样,出于同样的原因,您也应该关闭 CallableStatement 对象。

简单地调用 close() 方法即可完成这项工作。如果先关闭 Connection 对象,它也会关闭 CallableStatement 对象。但是,您应该始终显式关闭 CallableStatement 对象以确保正确的清理。

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}

为了更好地理解,我建议学习Callable - Examples Code

JDBC - 结果集

从数据库查询读取数据的 SQL 语句,返回结果集中的数据。SELECT 语句是从数据库中选择行并在结果集中查看它们的标准方法。java.sql.ResultSet接口表示数据库查询的结果集

ResultSet 对象维护一个指向结果集中当前行的游标。术语“结果集”是指 ResultSet 对象中包含的行和列数据。

ResultSet 接口的方法可以分为三类 -

  • 导航方法- 用于移动光标。

  • 获取方法- 用于查看光标指向的当前行的列中的数据。

  • 更新方法- 用于更新当前行列中的数据。然后,这些更新也可以在底层数据库中进行更新。

光标可以根据 ResultSet 的属性进行移动。这些属性是在创建生成 ResultSet 的相应语句时指定的。

JDBC 提供以下连接方法来创建具有所需结果集的语句 -

  • createStatement(int RSType, int RSConcurrency);

  • 准备语句(字符串SQL,int RSType,int RSConcurrency);

  • 准备调用(字符串sql,int RSType,int RSConcurrency);

第一个参数指示 ResultSet 对象的类型,第二个参数是两个 ResultSet 常量之一,用于指定结果集是只读还是可更新。

结果集类型

下面给出了可能的 RSType。如果您未指定任何 ResultSet 类型,您将自动获得 TYPE_FORWARD_ONLY 类型。

类型 描述
结果集.TYPE_FORWARD_ONLY 光标只能在结果集中向前移动。
结果集.TYPE_SCROLL_INSENSITIVE 游标可以向前和向后滚动,结果集对创建结果集后其他人对数据库所做的更改不敏感。
结果集.TYPE_SCROLL_SENSITIVE。 游标可以向前和向后滚动,结果集对创建结果集后其他人对数据库所做的更改很敏感。

结果集的并发

下面给出了可能的 RSConcurrency。如果您未指定任何并发类型,您将自动获得 CONCUR_READ_ONLY 并发类型。

并发性 描述
结果集.CONCUR_READ_ONLY 创建只读结果集。这是默认设置
结果集.CONCUR_UPDATABLE 创建可更新的结果集。

到目前为止我们编写的所有示例都可以写成如下,它初始化一个 Statement 对象来创建一个只进、只读的 ResultSet 对象 -

try {
   Statement stmt = conn.createStatement(
                           ResultSet.TYPE_FORWARD_ONLY,
                           ResultSet.CONCUR_READ_ONLY);
}
catch(Exception ex) {
   ....
}
finally {
   ....
}

导航结果集

ResultSet 接口中有多种涉及移动光标的方法,包括 -

序列号 方法与说明
1 public void beforeFirst() 抛出 SQLException

将光标移动到第一行之前。

2 public void afterLast() 抛出 SQLException

将光标移动到最后一行之后。

3 public boolean first() 抛出 SQLException

将光标移至第一行。

4 public void last() 抛出 SQLException

将光标移动到最后一行。

5 public boolean Absolute(int row) 抛出 SQLException

将光标移动到指定行。

6 public booleanrelative(int row) 抛出 SQLException

将光标从当前指向的位置向前或向后移动给定的行数。

7 public boolean previous() 抛出 SQLException

将光标移动到上一行。如果前一行不在结果集中,则此方法返回 false。

8 public boolean next() 抛出 SQLException

将光标移动到下一行。如果结果集中没有更多行,则此方法返回 false。

9 public int getRow() 抛出 SQLException

返回光标指向的行号。

10 public void moveToInsertRow() 抛出 SQLException

将游标移动到结果集中的特殊行,可用于将新行插入数据库。当前光标位置被记住。

11 public void moveToCurrentRow() 抛出 SQLException

如果光标当前位于插入行,则将光标移回当前行;否则,这个方法什么也不做

为了更好地理解,让我们研究Navigate - 示例代码

查看结果集

ResultSet 接口包含数十种获取当前行数据的方法。

每种可能的数据类型都有一个 get 方法,每个 get 方法都有两个版本 -

  • 一个接受列名的列。

  • 接受列索引的一个。

例如,如果您有兴趣查看的列包含 int,则需要使用 ResultSet 的 getInt() 方法之一 -

序列号 方法与说明
1 public int getInt(String columnName) 抛出 SQLException

返回名为columnName 的列中当前行的int。

2 public int getInt(int columnIndex) 抛出 SQLException

返回当前行中指定列索引的 int。列索引从 1 开始,表示行的第一列为 1,行的第二列为 2,依此类推。

类似地,ResultSet 接口中对于八种 Java 基本类型以及 java.lang.String、java.lang.Object 和 java.net.URL 等常见类型中的每一种都有 get 方法。

还有一些获取 SQL 数据类型 java.sql.Date、java.sql.Time、java.sql.TimeStamp、java.sql.Clob 和 java.sql.Blob 的方法。有关使用这些 SQL 数据类型的更多信息,请查看文档。

为了更好地理解,让我们研究查看 - 示例代码

更新结果集

ResultSet 接口包含用于更新结果集数据的更新方法的集合。

与 get 方法一样,每种数据类型都有两种更新方法 -

  • 一个接受列名的列。

  • 接受列索引的一个。

例如,要更新结果集当前行的字符串列,您可以使用以下 updateString() 方法之一 -

序列号方法与说明
1public void updateString(int columnIndex, String s) 抛出 SQLException

将指定列中的 String 更改为 s 的值。

2 public void updateString(String columnName, String s) 抛出 SQLException

与前面的方法类似,不同之处在于列是通过其名称而不是索引来指定的。

java.sql 包中提供了八种基本数据类型以及 String、Object、URL 和 SQL 数据类型的更新方法。

更新结果集中的行会更改 ResultSet 对象中当前行的列,但不会更改基础数据库中的列。要更新对数据库中行的更改,您需要调用以下方法之一。

序列号 方法与说明
1 公共无效更新行()

通过更新数据库中的相应行来更新当前行。

2 公共无效删除行()

从数据库中删除当前行

3 公共无效刷新行()

刷新结果集中的数据以反映数据库中的任何最新更改。

4 公共无效取消行更新()

取消对当前行所做的任何更新。

5 公共无效插入行()

将一行插入数据库。仅当光标指向插入行时才能调用此方法。

为了更好地理解,让我们研究一下更新示例代码

JDBC - 数据类型

JDBC 驱动程序将 Java 数据类型转换为适当的 JDBC 类型,然后再将其发送到数据库。它对大多数数据类型使用默认映射。例如,Java int 转换为 SQL INTEGER。创建默认映射是为了提供驱动程序之间的一致性。

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

SQL JDBC/Java 设置XXX 更新XXX
VARCHAR java.lang.String 设置字符串 更新字符串
字符 java.lang.String 设置字符串 更新字符串
长VARCHAR java.lang.String 设置字符串 更新字符串
少量 布尔值 设置布尔值 更新布尔值
数字 java.math.BigDecimal 设置大十进制 更新大十进制
天音 字节 设置字节 更新字节
小智 短的 设置短 更新短
整数 整数 设置整数 更新整数
BIGINT 长的 设定长 更新长
真实的 漂浮 设置浮动 更新浮动
漂浮 漂浮 设置浮动 更新浮动
双倍的 双倍的 设置双精度 更新双倍
二进制 字节[ ] 设置字节数 更新字节数
二进制 字节[ ] 设置字节数 更新字节数
日期 java.sql.日期 设置日期 更新日期
时间 java.sql.时间 设置时间 更新时间
时间戳 java.sql.时间戳 设置时间戳 更新时间戳
CLOB java.sql.Clob 设置Clob 更新Clob
BLOB java.sql.Blob 设置Blob 更新Blob
大批 java.sql.Array 设置数组 更新数组
参考文献 java.sql.Ref 设置引用 更新参考
结构体 java.sql.Struct 设置结构体 更新结构体

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 设置XXX 获取XXX
VARCHAR java.lang.String 设置字符串 获取字符串
字符 java.lang.String 设置字符串 获取字符串
长VARCHAR java.lang.String 设置字符串 获取字符串
少量 布尔值 设置布尔值 获取布尔值
数字 java.math.BigDecimal 设置大十进制 获取大十进制
天音 字节 设置字节 获取字节
小智 短的 设置短 做空
整数 整数 设置整数 获取整数
BIGINT 长的 设定长
真实的 漂浮 设置浮动 获取浮动
漂浮 漂浮 设置浮动 获取浮动
双倍的 双倍的 设置双精度 获取双倍
二进制 字节[ ] 设置字节数 获取字节数
二进制 字节[ ] 设置字节数 获取字节数
日期 java.sql.日期 设置日期 获取日期
时间 java.sql.时间 设置时间 获取时间
时间戳 java.sql.时间戳 设置时间戳 获取时间戳
CLOB java.sql.Clob 设置Clob 获取Clob
BLOB java.sql.Blob 设置Blob 获取Blob
大批 java.sql.Array 设置数组 获取数组
参考文献 java.sql.Ref 设置引用 获取引用
结构体 java.sql.Struct 设置结构体 获取结构体

日期和时间数据类型

java.sql.Date 类映射到 SQL DATE 类型,而 java.sql.Time 和 java.sql.Timestamp 类分别映射到 SQL TIME 和 SQL TIMESTAMP 数据类型。

以下示例显示日期和时间类如何格式化标准 Java 日期和时间值以匹配 SQL 数据类型要求。

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

public class SqlDateTime {
   public static void main(String[] args) {
      //Get standard date and time
      java.util.Date javaDate = new java.util.Date();
      long javaTime = javaDate.getTime();
      System.out.println("The Java Date is:" + 
             javaDate.toString());

      //Get and display SQL DATE
      java.sql.Date sqlDate = new java.sql.Date(javaTime);
      System.out.println("The SQL DATE is: " + 
             sqlDate.toString());

      //Get and display SQL TIME
      java.sql.Time sqlTime = new java.sql.Time(javaTime);
      System.out.println("The SQL TIME is: " + 
             sqlTime.toString());
      //Get and display SQL TIMESTAMP
      java.sql.Timestamp sqlTimestamp =
      new java.sql.Timestamp(javaTime);
      System.out.println("The SQL TIMESTAMP is: " + 
             sqlTimestamp.toString());
     }//end main
}//end SqlDateTime

现在让我们按如下方式编译上面的示例 -

C:\>javac SqlDateTime.java
C:\>

当您运行JDBCExample时,它​​会产生以下结果 -

C:\>java SqlDateTime
The Java Date is:Tue Aug 18 13:46:02 GMT+04:00 2009
The SQL DATE is: 2009-08-18
The SQL TIME is: 13:46:02
The SQL TIMESTAMP is: 2009-08-18 13:46:02.828
C:\>

处理 NULL 值

SQL 对 NULL 值的使用和 Java 对 null 的使用是不同的概念。因此,要在 Java 中处理 SQL NULL 值,您可以使用三种策略 -

  • 避免使用返回原始数据类型的 getXXX() 方法。

  • 对基本数据类型使用包装类,并使用 ResultSet 对象的 wasNull() 方法来测试接收 getXXX() 方法返回值的包装类变量是否应设置为 null。

  • 使用基本数据类型和 ResultSet 对象的 wasNull( ) 方法来测试接收 getXXX( ) 方法返回值的基本变量是否应设置为您选择表示 NULL 的可接受值。

下面是一个处理 NULL 值的示例 -

Statement stmt = conn.createStatement( );
String sql = "SELECT id, first, last, age FROM Employees";
ResultSet rs = stmt.executeQuery(sql);

int id = rs.getInt(1);
if( rs.wasNull( ) ) {
   id = 0;
}

JDBC - 事务

如果您的 JDBC 连接处于自动提交模式(默认情况下),则每个 SQL 语句在完成后都会提交到数据库。

对于简单的应用程序来说这可能没问题,但是您可能想要关闭自动提交并管理自己的事务有以下三个原因 -

  • 提高性能。

  • 保持业务流程的完整性。

  • 使用分布式事务。

事务使您能够控制是否以及何时将更改应用于数据库。它将单个 SQL 语句或一组 SQL 语句视为一个逻辑单元,如果任何语句失败,则整个事务失败。

要启用手动事务支持而不是JDBC 驱动程序默认使用的自动提交模式,请使用 Connection 对象的setAutoCommit()