本节例示一个不带参数的简单存储过程。多数存储过程的功能比本例复杂多了,但这里主要说明存储过程的一些基本要点。如前面所述,不同DBMS定义存储过程的语法是不同的。例如,有些DBMS使用begin . . . end或其他关键字指明存储过程定义的开始和结束。在有些DBMS中,下面的SQL语句可创建一个存储过程:
create procedure SHOW_SUPPLIERS
as
select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME
from SUPPLIERS, COFFEES
where SUPPLIERS.SUP_ID = COFFEES.SUP_ID
order by SUP_NAME
下面的代码将SQL语句放到一个字符串中,然后赋给变量createProcedure以备后用:
String createProcedure = "create procedure SHOW_SUPPLIERS " +
"as " +
"select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME " +
"from SUPPLIERS, COFFEES " +
"where SUPPLIERS.SUP_ID = COFFEES.SUP_ID " +
"order by SUP_NAME";
下面的代码段使用Connection对象con来创建Statement对象,用于把创建存储过程的SQL语句发送给数据库:
Statement stmt = con.createStatement();
stmt.executeUpdate(createProcedure);
存储过程SHOW_SUPPLIERS将作为一个可调用的数据库对象在数据库中编译并存储,调用时就像调用其他方法一样。
从JDBC调用存储过程
JDBC允许在用Java编写的程序中调用存储过程。第一步是创建一个CallableStatement对象。就像Statement和PreparedStatement对象一样,利用一个打开的Connection对象即可完成创建。CallableStatement对象包含了存储过程的一个调用;但它不包含存储过程本身。下面的第一行代码使用连接con创建了存储过程SHOW_SUPPLIERS的一个调用。花括号内的那部分就是存储过程的转义语法。当驱动程序碰到“{call SHOW_SUPPLIERS}”时,它将把这个转义语法转换成数据库使用的本地SQL,以调用名为SHOW_SUPPLIERS的存储过程。
CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}");
ResultSet rs = cs.executeQuery();
执行后结果集rs的内容如下:
SUP_NAME COF_NAME
---------------- -----------------------
Acme, Inc. Colombian
Acme, Inc. Colombian_Decaf
Superior Coffee French_Roast
Superior Coffee French_Roast_Decaf
The High Ground Espresso
注意,用于执行cs的方法是executeQuery,因为cs调用的存储过程包含一个查询,执行后产生一个结果集。如果存储过程包含一条更新或一条DLL语句,那就要使用executeUpdate方法。但有时一个存储过程包含多条SQL语句,因而它产生的不只是一个结果集、不只是一个更新计数或产生一些结果集和更新计数的组合。这样就有多个结果集,这时就应该使用execute方法来执行CallableStatement。
CallableStatement类是PreparedStatement的子类,因此CallableStatement对象可与PreparedStatement对象一样带有输入参数。此外,CallableStatement对象还可带输出参数或输入/输出参数。INOUT参数和execute方法很少使用。要获取更详细信息,请参考“使用Java进行JDBC数据库访问”。
到目前为止您还只看到了一些代码段。稍后在本节您将看到一些可运行的、完整的示例应用程序。
第一个示例代码创建COFFEES表;第二个示例代码在表中插入一些数据并输出查询结果。第三个应用程序创建SUPPLIERS表,第四个应用程序在SUPPLIERS表中插入一些数据。在运行这些代码后,可试着将COFFEES表和SUPPLIERS表关联起来查询(如第五个代码例子所示)。第六个代码例子是一个演示事务处理的应用程序,它也展示了如何使用for循环设置PreparedStatement对象中的占位符参数。
因为它们是完整的应用程序,所以代码中包括了一些前面代码段中没有看到的Java程序设计语言元素。在这里简要解释一下这些元素。
将代码放入类定义
在Java程序设计语言中,想要执行的代码都要放在类定义中。您要将类定义输入一个文件,然后将文件取名为类的名称,并在文件名后加上扩展名.java。因此如果类名是MySQLStatement,它的类定义应该放在名为MySQLStatement.java的文件中。
导入类使它们可见
首先是导引入新类中将要用到的包或类。我们例子中的类都使用java.sql包(JDBC API),在类定义前放入如下代码就可使用这个包:
import java.sql.*;
星号(*)指出要导入java.sql包中的所有类。导入类使它可见了,这表明使用该类中的方法或字段时不必写出完全限定名称。如果代码中没有包括“import java.sql.*;”,那么每次使用JDBC字段或方法时就要在它们前面写上“java.sql.”及类名。可以有选择地导入个别类而不是整个包。Java并不要求导入类或包,但这样做使代码编写要方便得多。
导入类的代码行出现在所有代码例子的顶部,因为要使导入的类对于所定义的类可见就必须这样做。实际类定义在导入类的代码行下面。
使用main方法
类要执行就要包含一个static public main方法。该方法就在声明类的代码行后面,它调用类中的其他方法。关键字static指出该方法操作在类级别上而不是操作在类的个别实例上。关键字public表明任何类的成员可以访问该方法。由于我们不只是要定义让其他类使用的类,而是要运行的类,所以本章的示例程序都包括一个main方法。
使用try和catch块
所有示例程序都包含的其他部分就是try和catch块。这是Java程序设计语言处理异常的机制。Java要求在方法抛出异常时有某种机制来处理它。一般catch块可捕获异常并指定处理办法(可选择不处理)。在示例代码中使用了两个try块和两个catch块。第一个try块包含了java.lang包中的Class.forName方法。这个方法抛出ClassNotFoundException异常,因此其后的catch块就处理那个异常。第二个try块包含了JDBC方法,这些方法都抛出SQLExceptions异常,因此在程序结束处有一个catch块处理可能抛出的其他所有异常,因为它们都是SQLException对象。
检索异常
JDBC允许查看DBMS和Java编译器生成的警告和异常。为看到异常可用catch块输出它们。例如,示例代码中的如下两个catch块输出解释异常的消息:
try {
// Code that could generate an exception goes here.
// If an exception is generated, the catch block below
// will print out information about it.
} catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
try {
Class.forName("myDriverClassName");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
如果两次运行CreateCOFFEES.java将得到如下错误消息:
SQLException: There is already an object named 'COFFEES'
in the database.
Severity 16, State 1, Line 1
本例演示如何输出SQLException对象的消息部件,在多数场合这足以说明错误。
但该对象实际上有3个部件,为全面了解错误原因可将其全部输出。下面的代码段展示了以两种方式完成的catch块。首先是输出SQLException对象的所有3个部件:消息(一个描述错误的字符串)、SQL状态(根据X/Open SQLState规则指出错误的字符串)和供应商错误代码(指出驱动程序供应商错误代码的数字)。捕获了SQLException对象ex之后,就可通过方法getMessage、getSQLState和getErrorCode来访问它的3个部件。
完成下面代码段的第二种方式是取得所有已经抛出的异常。如果有第二个异常,它将与ex相连,可调用ex.getNextException查看是否有下一个异常。如果有,while循环将继续,并输出下一个异常的消息、SQLState和供应商错误代码。这个过程一直持续到没有异常为止。
try {
// Code that could generate an exception goes here.
// If an exception is generated, the catch block below
// will print out information about it.
} catch(SQLException ex) {
System.out.println("\n--- SQLException caught ---\n");
while (ex != null) {
System.out.println("Message: "
+ ex.getMessage ());
System.out.println("SQLState: "
+ ex.getSQLState ());
System.out.println("ErrorCode: "
+ ex.getErrorCode ());
ex = ex.getNextException();
System.out.println("");
}
}
如果将上面的catch块代入CreateCoffees.java中,那么在创建COFFEES表后运行会得到如下输出:
--- SQLException caught ---
Message: There is already an object named 'COFFEES' in the database.
Severity 16, State 1, Line 1
SQLState: 42501
ErrorCode: 2714
SQLState是X/Open和ANSI-92中定义的一个用于指出异常的代码。下面是SQLState代码编号及其含义的两个例子:
08001 -- No suitable driver
HY011 -- Operation invalid at this time
每个驱动程序的供应商错误代码都不一样,因此要得到错误代码及其含义的列表需要检查驱动程序文档。
检索警告
SQLWarning对象是SQLException的子类,用于处理数据库访问警告。就像异常一样,警告并不终止程序的执行;它们只是提醒用户——发生了一些未预料的事情。例如,一个警告可告诉您试图收回的特权并没有收回。或者一个警告可告诉您请求断开连接时发生了错误。
Connection对象、Statement对象(包括PreparedStatement和CallableStatement对象)或ResultSet对象都会报告警告。这些类都有getWarnings方法,为查看调用对象报告的第一个警告就必须调用该方法。如果getWarnings返回一个警告,就可在其上调用SQLWarning方法getNextWarning取得其他警告。自动执行一条语句会清除前一条语句的警告,因此警告不会迭加。但这也表明提取一条语句报告的警告必须在执行下一语句之前进行。
下面的代码段演示了如何获取Statement对象stmt及ResultSet对象rs上报告的警告的完整信息:
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select COF_NAME from COFFEES");
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
System.out.println("Coffees available at the Coffee Break: ");
System.out.println(" " + coffeeName);
SQLWarning warning = stmt.getWarnings();
if (warning != null) {
System.out.println("\n---Warning---\n");
while (warning != null) {
System.out.println("Message: "
+ warning.getMessage());
System.out.println("SQLState: "
+ warning.getSQLState());
System.out.print("Vendor error code: ");
System.out.println(warning.getErrorCode());
System.out.println("");
warning = warning.getNextWarning();
}
}
SQLWarning warn = rs.getWarnings();
if (warn != null) {
System.out.println("\n---Warning---\n");
while (warn != null) {
System.out.println("Message: "
+ warn.getMessage());
System.out.println("SQLState: "
+ warn.getSQLState());
System.out.print("Vendor error code: ");
System.out.println(warn.getErrorCode());
System.out.println("");
warn = warn.getNextWarning();
}
}
}
实际上警告很不常见。在报告的警告中,最常见的警告是DataTruncation警告——SQLWarning的一个子类。所有DataTruncation对象的SQLState都是01004,表示读写数据时出了问题。DataTruncation方法可用于查找截断了哪些列或参数的数据、是否在读/写操作上发生了截断,应传输字节数以及实际传输字节数。
相关推荐
七、JDBC配置和应用心得 * 在使用JDBC之前,需要加载驱动程序。 * 需要注意JDBC的使用步骤,避免资源泄露。 * 不同的数据库厂商有不同的驱动程序和连接URL。 JDBC是一种Java标准的数据库连接API,它提供了一种统一...
### JDBC基础教程之概述 #### 一、JDBC简介与概念理解 JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC的...
**JDBC 入门知识详解** ...综上所述,JDBC是Java与数据库交互的基础,理解其工作原理和最佳实践对于任何Java开发者来说都至关重要。通过深入学习,我们可以更有效地构建健壮且高效的数据库应用程序。
**JDBC基础应用详解** **一、JDBC概述** JDBC(Java Database Connectivity)是Java语言与各种数据库之间通信的标准接口,由Sun Microsystems公司开发并引入Java平台,它允许Java程序通过标准API来访问和操作...
### JDBC基础教程之PreparedStatement知识点详解 #### 一、概述 `PreparedStatement`是Java数据库连接(JDBC)API中的一种重要接口,它继承自`Statement`接口,并在其基础上进行了扩展和优化。`PreparedStatement`...
### JDBC基础教程之CallableStatement详解 #### 一、概述 在数据库编程中,为了提高代码的复用性和执行效率,通常会使用存储过程。存储过程是预编译并存储在数据库中的SQL语句集合,可以接受输入参数并返回输出...
**标题:“发个基础jdbc”** 在Java编程中,JDBC(Java Database Connectivity)是连接Java应用程序和数据库的标准接口。这个“基础jdbc”的主题涵盖了如何使用JDBC进行基本的数据库操作,包括数据库连接、SQL语句...
总的来说,《Java Database Programming with JDBC》是一本全面介绍Java数据库编程的书籍,涵盖了从基础的SQL语法到高级的JDBC应用,对于希望使用Java进行数据库开发的程序员来说,是一份宝贵的资源。
一、JDBC基础 1. JDBC驱动:在Java程序中使用JDBC之前,必须先安装并加载对应的JDBC驱动。根据驱动的实现方式,JDBC驱动分为四种类型:Type 1、Type 2、Type 3和Type 4,其中Type 4是纯Java实现,性能最优。 2. ...
1. **第一讲:JDBC基础** - JDBC API简介:了解JDBC的基本概念,如DriverManager、Connection、Statement和ResultSet等。 - 数据库连接:如何加载数据库驱动,建立数据库连接。 - SQL语句执行:使用Statement对象...
3. **易用性**:相比C语言为基础的ODBC,JDBC更易于理解和使用,尤其是在面向对象编程方面。 #### 五、JDBC的API接口 JDBC主要包括两个层面的接口: 1. **JDBC API**:面向开发者的API,包括`java.sql.Connection`...
这份"很详细的jdbc笔记 决定经典"显然是一个珍贵的学习资源,它涵盖了JDBC的基础和高级概念,对于想要深入理解数据库操作的Java开发者来说极具价值。下面我们将详细探讨JDBC的一些关键知识点。 1. **JDBC驱动程序**...
标签中的"sqlserverjdbc"是SQL Server JDBC驱动的简称,"mssqljdbc7"可能指的是这是驱动的第七个主要版本,"jdbc7.4.1"则表示这是JDBC 7.4.1版本,而".4.1.jre8.jar"再次强调了它是为Java 8设计的。这些标签有助于...
#### 三、JDBC基础 JDBC(Java Database Connectivity)是一个由Sun Microsystems开发的标准API,用于Java应用程序与各种数据库通信。它是Java访问数据库的基础,也是其他数据访问技术如JDO和Hibernate的基础。 - *...
综上所述,JDBC不仅是Java应用程序与数据库交互的基础,而且通过其丰富的功能和API,为开发者提供了强大的数据处理能力。理解并熟练掌握JDBC的使用,对于任何Java开发者而言都是至关重要的技能。
#### 七、JDBC与MySQL的结合 在实际开发中,JDBC常被用于连接MySQL数据库,通过Java应用程序来执行各种数据库操作。这种结合不仅充分利用了MySQL的高性能和灵活性,同时也发挥了Java的跨平台优势,使得开发者能够...
7.4.2版本确保了与多种SQL语法的兼容性,包括SELECT、INSERT、UPDATE、DELETE等基础语句,以及JOIN、GROUP BY、HAVING等复杂查询。这使得开发人员能够利用熟悉的SQL语法在Elasticsearch中进行数据操作,而无需学习新...
JDBC连接8种数据库 JDBC(Java Database Connectivity)是一种Java API,用于连接和操作数据库。下面将详细介绍八种常见数据库的JDBC连接方式。 一、Oracle数据库连接 ...了解这些差异性是使用JDBC连接数据库的基础。
根据给定的文件信息,我们可以将“数据库基础与JDBC编程技术”这一课程的主要知识点归纳如下: ### 一、数据库基础 #### 第一讲 数据库的基本概念及常用数据库介绍 - **1.1 什么是数据库** - 数据库是按照数据...
### Java基础:常用的JDBC连接数据库方法大全 在Java开发中,经常需要与各种关系型数据库进行交互。Java Database Connectivity (JDBC) 是一个用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由...