高级的JDBC外文翻译资料

 2022-08-22 10:08

Advanced JDBC
Chapter 3, provides all the JDBC you absolutely need to know to build database applications. If you understand all of it and then put this book away, you will probably never feel like anything is missing. That is exactly how JDBCs creators intended the API to feel. They wanted to provide a few simple interfaces to support the majority of what database programmers want to do. Extended and complex functionality appears in extra interfaces designed specifically to support that functionality.Advanced JDBC programming supports advanced needs. These advanced needs break down into two categories: optimizations and extended functionality. This chapter dives into all of the extended functionality included in the JDBC Core API.

4.1 Prepared SQL
Each SQL statement you send to the database needs to be parsed by the database engine before it can actually be executed. When the database parses a SQL statement, it reads the SQL to determine what you want the database to do, and then it formulates a plan for carrying out your instructions. This processing is called building a query plan.


In Chapter 3, each SQL statement you sent to the database required the database to treat the statement as a brand-new query and thus build a new query plan for it. This processing is necessary only if each statement requires a distinct query plan. If you are executing statements over and over again that have the same query plan, you are wasting processing power. If, for example, your banking application uses the SQL UPDATE ACCOUNT SET BALANCE = XXX WHERE ACCOUNT_ID =YYY, you would force the database to rebuild the same query plan each time you changed the balance for the account. Databases enable you to optimize repeated calls through prepared SQL.

Databases provide two kinds of prepared SQL: prepared statements and stored procedures. Prepared SQL provides an advantage over the simple SQL statements you have covered so far; a database can get the SQL ahead of time and create a query plan while you are doing other application logic. This means that your SQL should execute faster and that you can have a generic reference to a statement for later reuse rather than repeatedly create new SQL statements for each new access to the database.


The optimization factor comes from the database knowing what you are about to do. When you create a Java instance of a prepared statement or stored procedure, you notify the database of what kind of SQL call that object represents. The database can then create a query plan for that SQL call before you ever actually execute it. When it comes time for you to execute the SQL, the database is ready for you. If you execute the same prepared SQL more than once, the database remains ready for your SQL without having to rebuild the query plan.

You could get more performance benefits by pooling your prepared SQL resources. For example, if your code makes only a single call to a specific SQL statement, but that call appears in different places throughout the application, you could implement a prepared statement pool that holds the JDBC representation of your prepared SQL open for repeated use. This functionality may end up as a feature of JDBC 3.0.

4.1.1 Prepared Statements
The PreparedStatement interface extends the Statement interface you used in Chapter 3. It
enables a SQL statement to contain parameters like a function definition, and you can execute a single statement repeatedly with different values for those parameters. The act of assigning values to parameters is called binding parameters. You might want to use a prepared statement when updating a group of objects stored on the same table. For example, if you were updating many bank accounts at once, you might have a loop calling:


Statement statement = c.createStatement( );
int i;
for(i=0; ilt;accounts.length; i )
statement.executeUpdate('UPDATE account '
'SET balance = ' accounts[i].getBalance( )
'WHERE id = ' accounts[i].getId( ));
c.commit( );
statement.close( );
This statement creates the same query plan each time through the loop. Instead of calling this same statement repeatedly with different inputs, you can instead use a PreparedStatement:


PreparedStatement statement = c.prepareStatement(
'UPDATE account '
'SET balance = ? '
'WHERE id = ?');
int i;
for(i=0; ilt;accounts.length; i ) {
statement.setFloat(1, accounts[i].getBalance( ));
statement.setInt(2, accounts[i].getId( ));
statement.execute( );
statement.clearParameters( )
}
c.commit( );
statement.close( );
With a prepared statement, you send the actual SQL to the database when you get the
PreparedStatement object through the prepareStatement( ) method in java.sql.Connection.
Keep in mind that you have not yet actually executed any SQL. You execute that prepared SQL statement multiple times inside the for() loop, but you build the query plan only a single time.

Before each execution of the prepared statement, you tell JDBC which values to use as input for that execution of the statement. In order to bind the input parameters, PreparedStatement provides setXXX() methods (such as setFloat() and setInt()) that mirror the getXXX() methods you saw in java.sql.ResultSet. Just as the getXXX( ) methods read results according to the order in which you constructed your SQL, the setXXX() methods bind parameters from left to right in the order you placed them in the prepared statement. In the previous example, I bound parameter 1 as a float to the account balance that I retrieved from the account object. The first ? was thus associated with parameter 1.
4.1.2 Stored Procedures
While prepared sta

剩余内容已隐藏,支付完成后下载完整资料


高级的JDBC

第3章 提供了构建数据库应用程序绝对需要知道的所有JDBC。如果你理解了所有这些,然后把这本书收起来,你可能永远不会觉得有什么东西丢失了。这正是JDBC的创建者想要API(Application Programming Interface,应用程序接口)的感受。他们想提供一些简单的接口来支持大多数数据库程序员想做的事情。扩展和复杂的功能出现在专门为支持该功能而设计的额外接口中。高级JDBC编程支持高级需求。这些高级需求分为两类:优化功能和扩展功能。本章将深入讨论JDBC核心API中包含的所有扩展功能。

4.1 准备好SQL

发送到数据库的每个SQL语句在实际执行之前都需要由数据库引擎进行分析。当数据库解析一个SQL语句时,它读取SQL以确定您希望数据库做什么,然后它制定一个执行您的指令的计划。此处理称为生成查询计划。

在第3章中,发送到数据库的每个SQL语句都要求数据库将该语句视为一个全新的查询,从而为它构建一个新的查询计划。只有当每个语句都需要不同的查询计划时,才需要进行此处理。如果您一次又一次地执行具有相同查询计划的语句,则是在浪费处理能力。例如,如果您的银行应用程序使用SQL UPDATE ACCOUNT SET BALANCE=XXX,其中ACCOUNT_ID=YYY,则每次更改帐户的余额时,都会强制数据库重新生成相同的查询计划。数据库使您能够通过准备好的SQL优化重复调用。

数据库提供两种准备好的SQL:准备好的语句和存储过程。准备好的SQL提供了一个优于您目前所讨论的简单SQL语句的优势;当您执行其他应用程序逻辑时,数据库可以提前获取SQL并创建查询计划。这意味着您的SQL应该执行得更快,并且您可以对语句进行泛型引用以供以后重用,而不是为每次对数据库的新访问重复创建新的SQL语句。

优化因素来自数据库,知道您将要做什么。当您为准备好的语句或存储过程创建Java实例时,您将通知数据库该对象所表示的SQL调用类型。然后,数据库可以在实际执行该SQL调用之前为其创建查询计划。当您需要执行SQL时,数据库已经准备好了。如果多次执行同一个准备好的SQL,则数据库将为SQL做好准备,而不必重新生成查询计划。

通过共享准备好的SQL资源,您可以获得更多的性能优势。例如,如果您的代码只对特定的SQL语句进行一次调用,但该调用出现在整个应用程序的不同位置则可以实现一个prepared语句池,该语句池保存准备好的SQL的JDBC表示形式,以供重复使用。这个功能最终可能成为JDBC3.0的一个特性。

4.1.1预编译语句

PreparedStatement接口扩展了您在第3章中使用的语句接口。它使SQL语句能够包含函数定义之类的参数,并且您可以使用这些参数的不同值重复执行单个语句。将值赋给参数的行为称为绑定参数。更新存储在同一表中的一组对象时,可能需要使用准备好的语句。例如,如果同时更新多个银行帐户,则可能有一个循环调用:

Statement statement = c.createStatement( );
int i;
for(i=0; ilt;accounts.length; i )
statement.executeUpdate('UPDATE account '
'SET balance = ' accounts[i].getBalance( )
'WHERE id = ' accounts[i].getId( ));
c.commit( );
statement.close( );
此语句每次通过循环创建相同的查询计划。您可以使用PreparedStatement,而不是使用不同的输入重复调用同一语句:


PreparedStatement statement = c.prepareStatement(
'UPDATE account '
'SET balance = ? '
'WHERE id = ?');
int i;
for(i=0; ilt;accounts.length; i ) {
statement.setFloat(1, accounts[i].getBalance( ));
statement.setInt(2, accounts[i].getId( ));
statement.execute( );
statement.clearParameters( )
}
c.commit( );
statement.close( );
对于准备好的语句,当通过java.SQL.Connection中的prepareStatement()方法获取PreparedStatement对象时,将实际的SQL发送到数据库。请记住,您还没有实际执行任何SQL。在for()循环中多次执行准备好的SQL语句,但只构建一次查询计划。

在每次执行准备好的语句之前,都要告诉JDBC要将哪些值用作该语句执行的输入。为了绑定输入参数,PreparedStatement提供了setXXX()方法(如setFloat()和setInt()),这些方法镜像了在java.sql.ResultSet中看到的getXXX()方法。正如getXXX()方法根据构建SQL的顺序读取结果一样,setXXX()方法按照将参数放入准备好的语句的顺序从左到右绑定参数。在前面的示例中,我将参数1绑定为从account对象检索到的帐户余额的浮点值。第一个?因此与参数1相关。

4.1.2存储过程

虽然准备好的语句允许您通过一个PreparedStatement对象访问类似的数据库查询,但存储过程尝试将数据库访问的“黑盒”概念进一步深化。在运行应用程序之前,将在数据库中生成存储过程。在运行时按名称访问该存储过程。换句话说,存储过程几乎就像在数据库中调用的方法。存储过程具有以下优点:

bull;由于大多数数据库引擎的过程是在数据库中预编译的,因此它的执行速度比动态SQL快得多,每次发出动态SQL时都需要重新解释。即使数据库在程序运行之前没有编译它,它也会像准备好的语句一样被预编译以供后续运行。

bull;存储过程中的语法错误可以在编译时捕获,而不是在运行时捕获。

bull;Java开发人员只需要知道过程的名称及其输入和输出。过程的实现方式,它访问的表,这些表的结构等等,完全不重要。

存储过程是用变量作为参数占位符编写的,当通过列绑定调用该过程时,变量占位符被传递。列绑定是一种为存储过程指定参数的奇特方法。您将在以下示例中确切地看到这是如何完成的。Sybase存储过程可能如下所示:

DROP PROCEDURE sp_select_min_bal
GO
CREATE PROCEDURE sp_select_min_bal
@balance,
AS
SELECT account_id
FROM account
WHERE balance gt; @balance
GO

此存储过程的名称为sp_select_min_bal。它接受由@符号标识的单个参数。这一个论点是最小限度的平衡。存储过程生成一个结果集,其中包含余额大于最小余额的所有帐户。当此存储过程生成结果集时,也可以有返回输出参数的过程。下面是一个更复杂的存储过程,用Oracle的存储过程语言编写,它计算利息并返回新的余额:

CREATE OR REPLACE PROCEDURE sp_interest
(id IN INTEGER,
bal IN OUT FLOAT) IS
BEGIN
SELECT balance
INTO bal
FROM account
WHERE account_id = id;
bal := bal bal * 0.03;
JDBC and Java 2nd edition

UPDATE account
SET balance = bal
WHERE account_id = id;
END;

此存储过程接受两个参数(括号中的变量)并执行复杂的处理,这些处理不会(也不能)出现在您目前使用的嵌入式SQL中。它实际上在一个过程中执行两个SQL语句和一个计算。第一部分获取当前余额;第二部分获取余额并将其增加3%;第三部分更新余额。在Java应用程序中,您可以这样使用它:

try {
CallableStatement statement;
int i;
statement = c.prepareCall('{call sp_interest[(?,?)]}');
statement.registerOutParameter(2, java.sql.Types.FLOAT);
for(i=1; ilt;accounts.length; i ) {
statement.setInt(1, accounts[i].getId( ));
statement.execute( );
System.out.println('New balance: ' statement.getFloat(2));
}
c.commit( );
statement.close( );
c.close( );
}
CallableStatement类与PreparedStatement类非常相似。使用prepareCall()而不是prepareStatement(),指示要调用的过程初始化CallableStatement对象时。不幸的是,这是ANSI SQL2不足以实现可移植性的一次。不同的数据库引擎对这些调用使用不同的语法。然而,JDBC确实提供了一种独立于数据库的存储过程转义语法,其格式是{call procedureu name[(?, ?)]}. 对于具有返回值的存储过程,转义语法为:{?=调用过程名称[(?,?)]}. 在这个转义语法中,每个?表示过程输入或返回值的占位符。然后,JDBC驱动程序将此转义语法转换为驱动程序自己的存储过程语法。

使用什么样的语句?

这本书给你介绍了三种陈述类:陈述,

PreparedStatement和CallableStatement。使用与

要使用的SQL类型。但你如何确定哪一种最适合你呢?Statement类表示的普通SQL语句几乎从来都不是一个好主意。他们唯一的工作就是快速而肮脏的编码。虽然如果每次对数据库的调用都是唯一的,那么您确实不会获得性能上的好处,但是普通的SQL语句也更容易出错(例如,没有自动处理数据格式),而且读起来不像准备好的SQL那样干净。因此,在准备好的语句和存储过程之间做出更难的决定。这个决定的底线是可移植性与速度和优雅。因此,您在作出决定时应考虑以下因素:

bull;正如您在本文前面的Oracle和Sybase存储过程中看到的第章,不同的数据库对于其存储过程有着非常不同的语法。虽然JDBC确保Java代码保持可移植性,但是存储过程中的代码几乎永远不会。

bull;虽然存储过程通常比准备好的语句快,但是保证您将在存储过程中看到更好的性能。不同的数据库以不同的方式优化。一些预编译都准备好了语句和存储过程;其他的都不能预编译。你唯一知道的可以肯定的是,准备好的语句不太可能比存储的语句快过程对应项和存储过程对应项可能是略快于准备好的陈述。

bull;存储过程比准备好的语句更符合黑盒概念。JDBC程序员只需要知道存储过程的输入和输出-不是存储过程的底层表结构;程序员需要除了了解准备好的SQL。

bull;存储过程使您能够在数据库中执行复杂的逻辑。一些人们将此视为支持存储过程的参数。分为三层但是,分布式系统中不应该有任何处理逻辑数据库。因此,三层开发人员应该避免使用此功能。

如果存储过程有输出参数,则需要使用执行存储过程之前的registerOutParameter()。这个步骤告诉JDBC所讨论的参数将是的数据类型。前面的例子是这样的:

CallableStatement statement;
int i;
statement = c.prepareCall('{call sp_interest[(?,?)]}');
statement.registerOutParameter(2, java.sql.Types.FLOAT);

prepareCall()方法创建一个存储过程对象,该对象将调用指定的存储过程。此语法设置将在绑定参数中使用的顺序。通过调用registerOutParameter(),可以告诉CallableStatement实例期望第二个参数作为float类型的输出。设置好后,可以使用setInt()绑定ID,然后使用getFloat()获取结果。


4.2 批处理

复杂系统通常需要在线和批处理。每种加工都有非常不同的要求。因为在线处理涉及到等待应用程序处理顺序的用户,所以流程中每个语句执行的时间和性能非常重要。另一方面,批处理发生在需要独立于用户交互进行一系列不同事务时。银行

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[409460],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。