1. Trang chủ
  2. » Công Nghệ Thông Tin

Chapter 33: Advanced Object-Oriented Concepts s sThe object table itself is not mentioned in the pps

102 450 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Advanced Object-Oriented Concepts
Tác giả Loney, Koch
Trường học Unknown
Chuyên ngành Database Systems
Thể loại Textbook Chapter
Năm xuất bản 2002
Thành phố Unknown
Định dạng
Số trang 102
Dung lượng 1,52 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The DEREF showed the full structure of the abstract datatype used by the ANIMAL object table: select DEREFK.AnimalKept from KEEPER K where KeeperName = 'CATHERINE WEILZ'; DEREFK.ANIMALKE

Trang 1

■ The object table itself is not mentioned in the query The only table listed in the query is

KEEPER You do not need to know the name of the object table to DEREF its values.

■ The entire referenced row object was returned, not just part of the row

These are significant differences that separate object queries from relational queries Thus,when querying your tables, you need to know the way in which their relationships are established

Are the relationships based on foreign keys and primary keys, or on object tables and REF

datatypes? To help smooth the transition between relational and object-oriented approaches,

Oracle allows you to create object views that contain REFs superimposed on existing relational

tables See “Object Views with REFs,” later in this chapter

The VALUE Function

The DEREF function was applied to the relational table—the KEEPER table, in this case The DEREF

function returns the value of the reference that goes from the relational table to the object table

What about querying from the object table? Can you select from ANIMAL?

select * from ANIMAL;

BREED NAME BIRTHDATE

- -

-MULE FRANCES 01-APR-02

DOG BENJI 03-SEP-01

Even though ANIMAL is an object table, you can select from it as if it were a relational table

This is consistent with the examples of inserts and selects shown earlier in this chapter However,

that is not what was shown via the DEREF The DEREF showed the full structure of the abstract

datatype used by the ANIMAL object table:

select DEREF(K.AnimalKept)

from KEEPER K

where KeeperName = 'CATHERINE WEILZ';

DEREF(K.ANIMALKEPT)(BREED, NAME, BIRTHDATE)

-ANIMAL_TY('DOG', 'BENJI', '03-SEP-01')

To see the same structures from a query of the ANIMAL object table, use the VALUE function.

As shown in the following listing, VALUE shows you the data in the same format that DEREF will

use The parameter for the VALUE function is the table alias.

select VALUE(A)

from ANIMAL A

where Name = 'BENJI';

Trang 2

616 Part IV: Object-Relational Databases

VALUE(A)(BREED, NAME, BIRTHDATE)

-ANIMAL_TY('DOG', 'BENJI', '03-SEP-01')

ANIMAL_TY('DOG', 'BENJI', '03-SEP-01')

The VALUE function is useful when debugging references and within PL/SQL, as shown in

“Object PL/SQL,” later in this chapter Since it allows you to query the formatted values directly

from the object table, you can select those values without using the DEREF query of KEEPER’s

AnimalKept column

Invalid References

You can delete the object to which a reference points For example, you can delete a row from

the ANIMAL object table to which a KEEPER record points:

delete from ANIMAL

where Name = 'BENJI';

The record in KEEPER that references this ANIMAL record will now have what is called a

dangling REF If you insert a new ANIMAL row for the animal named BENJI, it won’t be recognized

as being part of the same reference established earlier The reason is that the first time you inserted

a BENJI row, Oracle generated an OID for the row object, and that is what the KEEPER column

referenced When you deleted the row object, the OID went away—and Oracle does not reuse

OID numbers Therefore, when the new BENJI record is entered, it is given anew OID value—

and the KEEPER record still points to the old value

This is a critical difference between relational and OOP systems In a relational system, thejoin between two tables is dependent only on the current data In an OOP system, the join is

between objects—and just because two objects have the same data, that doesn’t mean they are

the same

Object Views with REFs

You can use object views to superimpose OOP structures on existing relational tables (refer to

Chapter 30) For example, you can create abstract datatypes and use them within the object view

of an existing table Using object views allows you to access the table via either relational command

syntax or abstract datatype syntax As a result, object views provide an important technological

bridge from existing relational applications to object-relational applications

A Quick Review of Object Views

This example from Chapter 30 will serve as part of the basis for the advanced object views in this

chapter First, a CUSTOMER table is created, with the Customer_ID column as its primary key:

create table CUSTOMER

(Customer_ID NUMBER constraint CUSTOMER_PK primary key,

Name VARCHAR2(25),

Street VARCHAR2(50),

Trang 3

an Address attribute that uses the ADDRESS_TY datatype, as shown in the following listing:

create or replace type ADDRESS_TY as object

accesses (such as methods) You can create an object view that specifies the abstract datatypes that

apply to the CUSTOMER table In the following listing, the CUSTOMER_OV object view is created:

create view CUSTOMER_OV (Customer_ID, Person) as

select Customer_ID,

PERSON_TY(Name, ADDRESS_TY(Street, City, State, Zip)) from CUSTOMER;

In the creation of the CUSTOMER_OV object view, the constructor methods for the two abstractdatatypes (ADDRESS_TY and PERSON_TY) are specified You can now access the CUSTOMER table

directly (as a relational table) or via the constructor methods for the abstract datatypes

The CUSTOMER table will be used in the next set of examples in this chapter

Object Views Involving References

If the CUSTOMER table shown in the previous section is related to another table, you can use

object views to create a reference between the tables That is, Oracle will use the existing primary

key/foreign key relationships to simulate OIDs for use by REFs between the tables You will thus

be able to access the tables either as relational tables or as objects When you treat the tables as

objects, you will be able to use the REFs to automatically perform joins of the tables (refer to

“Using the DEREF Function,” earlier in this chapter, for examples).

The CUSTOMER table has a primary key of Customer_ID Let’s create a small table that willcontain a foreign key reference to the Customer_ID column In the following listing, the CUSTOMER_

CALL table is created The primary key of the CUSTOMER_CALL table is the combination

of Customer_ID and Call_Number The Customer_ID column of CUSTOMER_CALL is a foreign

Trang 4

key back to CUSTOMER—you cannot record a call for a customer who does not already have a

record in CUSTOMER A single nonkey attribute, Call_Date, is created within the CUSTOMER_

For example, you could have the following CUSTOMER and CUSTOMER_CALL entries:

insert into CUSTOMER values

(123,'SIGMUND','47 HAFFNER RD','LEWISTON','NJ',22222);

insert into CUSTOMER values

(234,'EVELYN','555 HIGH ST','LOWLANDS PARK','NE',33333);

insert into CUSTOMER_CALL values

CUSTOMER Therefore, we must find a way to assign OID values to the records in CUSTOMER

and generate references in CUSTOMER_CALL

How to Generate OIDs

First, use an object view to assign OIDs to the records in CUSTOMER Remember that OIDs

are assigned to records in an object table—and an object table, in turn, is based on an abstract

datatype Therefore, we first need to create an abstract datatype that has the same structure as the

Now, create an object view based on the CUSTOMER_TY type, while assigning OID values

to the records in CUSTOMER:

create or replace view CUSTOMER_OV of CUSTOMER_TY

with object identifier (Customer_ID) as

618 Part IV: Object-Relational Databases

Trang 5

select Customer_ID, Name, Street, City, State, Zip

from CUSTOMER;

The first part of this create view command gives the view its name (CUSTOMER_OV) and tells

Oracle that the view’s structure is based on the CUSTOMER_TY datatype:

create or replace view CUSTOMER_OV of CUSTOMER_TY

The next part of the create view command tells the database how to construct OID values for the rows in CUSTOMER The with object identifier clause is followed by the column to use for the

OID—in this case, the Customer_ID value This will allow you to address the rows within the

CUSTOMER table as if they were referenceable row objects within an object table

with object identifier (Customer_ID) as

NOTE The with object identifier clause replaces the with object OID clause used in earlier versions of Oracle The with object OID syntax is still

supported for backward compatibility

The final part of the create view command gives the query on which the view’s data access

will be based The columns in the query must match the columns in the view’s base datatype

select Customer_ID, Name, Street, City, State, Zip

from CUSTOMER;

The rows of CUSTOMER are now accessible as row objects via the CUSTOMER_OV view

The OID values generated for the CUSTOMER_OV rows are calledpkOIDs, because they are

based on CUSTOMER’s primary key values Relational tables can be accessed as row objects if

you create object views for them

How to Generate References

The rows of CUSTOMER_CALL reference rows in CUSTOMER From a relational perspective, the

relationship is determined by the foreign key pointing from the CUSTOMER_CALL.Customer_ID

column to the CUSTOMER.Customer_ID column Now that the CUSTOMER_OV object view has

been created, and the rows in CUSTOMER can be accessed via OIDs, you need to create reference

values in CUSTOMER_CALL that reference CUSTOMER Once the REFs are in place, you will be

able to use the DEREF function (shown earlier in this chapter) to access the CUSTOMER data from

within CUSTOMER_CALL

The create view command for the object view of CUSTOMER_CALL is shown in the following listing It uses a new function, MAKE_REF, which is described following the listing.

create view CUSTOMER_CALL_OV as

select MAKE_REF(CUSTOMER_OV, Customer_ID) Customer_ID,

Call_Number, Call_Date from CUSTOMER_CALL;

Trang 6

620 Part IV: Object-Relational Databases

With the exception of the MAKE_REF operation, this create view command looks like a normal create view command The MAKE_REF operation is shown in this line:

select MAKE_REF(CUSTOMER_OV, Customer_ID) Customer_ID,

The MAKE_REF function takes as arguments the name of the object view being referenced and

the name of the column (or columns) that form the foreign key in the local table In this case, the

Customer_ID column of the CUSTOMER_CALL table references the column that is used as the basis

of OID generation in the CUSTOMER_OV object view Therefore, two parameters are passed to

MAKE_REF: CUSTOMER_OV and Customer_ID The result of the MAKE_REF operation is given the

column alias Customer_ID Since this command creates a view, the result of an operation must be

given a column alias

What does MAKE_REF do? It creates references (calledpkREFs, since they are based on primarykeys) from the CUSTOMER_CALL_OV view to the CUSTOMER_OV view You can now query the

two views as if CUSTOMER_OV were an object table and CUSTOMER_CALL_OV were a table

that contains a REF datatype that references CUSTOMER_OV

Querying the Object Views

The queries of the object views with REFs mirror the structure of the queries of table REFs You

use the DEREF function to select the value of the referenced data, as shown earlier in this chapter.

Applied to the object views, the query will be

select DEREF(CCOV.Customer_ID)

from CUSTOMER_CALL_OV CCOV

where Call_Date = TRUNC(SysDate);

DEREF(CCOV.CUSTOMER_ID)(CUSTOMER_ID, NAME, STREET, CITY, STATE,ZIP)

-CUSTOMER_TY(123, 'SIGMUND', '47 HAFFNER RD', 'LEWISTON','NJ',22222)

The query found the record in CUSTOMER_CALL for which the Call_Date value was thecurrent system date It then took the Customer_ID value from that record and evaluated its

reference That Customer_ID value, from the MAKE_REF function, pointed to a pkOID value in

the CUSTOMER_OV object view The CUSTOMER_OV object view returned the record whose

pkOID matched the referenced value The DEREF function then returned the value of the

referenced row The query thus returned rows from CUSTOMER even though the user only

queried CUSTOMER_CALL

Object views of column objects enable you to work with tables as if they were both relationaltables and object-relational tables When extended to row objects, object views enable you to

generate OID values based on established foreign key/primary key relationships Object views

allow you to continue to use the existing constraints and standard insert, update, delete, and

select commands They also allow you to use OOP features such as references against the object

tables Object views thus provide an important technological bridge for migrating to an OOP

database architecture

As described earlier in this chapter, Oracle performs joins that resolve the references defined

in the database When the referenced data is retrieved, it brings back the entire row object that

Trang 7

was referenced To reference the data, you need to establish pkOIDs in the table that is the

“primary key” table in the relationship, and use MAKE_REF to generate references in the table

that is the “foreign key” table in the relationship You can then work with the data as if it were

stored in object tables

Object PL/SQL

PL/SQL programs can use the abstract datatypes you have created Whereas earlier versions of PL/SQL

could only use the Oracle-provided datatypes (such as DATE, NUMBER, and VARCHAR2), you can

now use your own user-defined datatypes as well The result is the merging of SQL, procedural logic,

and OOP extensions—a combination referred to asobject PL/SQL

The following anonymous PL/SQL block uses object PL/SQL concepts The CUSTOMER_TYabstract datatype is used as the datatype for theCust1 variable, and its value is populated by a

query of the CUSTOMER_OV object view

TheCust1 variable value is selected from the CUSTOMER_OV object view (created in the

previous section of this chapter) The VALUE function is used to retrieve the data in the structure

of the abstract datatype Since the data will be selected in the format of the abstract datatype, you

need to use the CUSTOMER_OV object view created on the CUSTOMER table

begin

select VALUE(COV) into Cust1 from CUSTOMER_OV COV

where Customer_ID = 123;

Trang 8

622 Part IV: Object-Relational Databases

The Cust1.Name and Cust1.Street values are then retrieved from the attributes of theCust1variable and displayed You cannot pass the entireCust1 variable to the PUT_LINE procedure

Oracle-provided datatypes, and may more accurately reflect the objects in your database In this

example, an object view was queried to illustrate that the queries can access either column objects

or row objects You can then select the attributes of the abstract datatype and manipulate or display

them If you have defined methods for the abstract datatype, you can apply them as well

For example, you can call the datatype’s constructor methods within your PL/SQL blocks In thefollowing example, a variable namedNewCust is defined using the CUSTOMER_TY datatype The

NewCust variable is then set equal to a set of values using the CUSTOMER_TY constructor method

TheNewCust variable’s set of values is then inserted via the CUSTOMER_OV object view.

You can see the result of the insert by querying CUSTOMER_OV:

select Customer_ID, Name from CUSTOMER_OV;

datatypes, you will need to define map or order methods for the datatypes This capability allows

you to further extend object PL/SQL—you define the datatypes and the functions at the database

level, and they are callable within any of your PL/SQL programs Object PL/SQL represents a

significant enhancement over traditional PL/SQL

Trang 9

Objects in the Database

The features available in Oracle—column objects, row objects, and object extensions to PL/SQL—

enable you to implement objects in your database without sacrificing the investment you have

already made in analysis and design You can continue to create systems based on relational

design techniques and tune them based on relational access methods The tools that Oracle

provides allow you to create an OOP layer above your relational tables Once you have that

layer in place, you can access the relational data as if it were stored in a fully OOP database

Having an OOP layer allows you to realize some of the benefits of an OOP system, such

as abstraction and encapsulation You can apply the methods for each abstract datatype

across a set of consistently implemented objects, and benefit from object reuse and standards

enforcement At the same time, you can benefit from Oracle’s relational features The ability

to use both relational and object technology within an application lets you use the proper tool

for the proper job within the database

When implementing the object portion of an object-relational database, start by defining theabstract datatypes that are the core components of your business Every object-relational feature,

whether it relates to column objects or row objects, is based on an abstract datatype The better

you have defined your datatypes and their methods, the better you will be able to implement

objects If necessary, nest objects so that you can have multiple variations of the same core datatype

The result will be a database that is properly designed to take advantage of the relational and

OOP features Oracle provides now, and will provide in versions to come

Trang 11

V

Java in Oracle

Trang 13

34

An Introduction to Java

Trang 14

I n this chapter, you will see an overview of Java as it relates to Oracle databaseapplications There are numerous uses of Java beyond Oracle applications, and there

are many features of the language that will not be used by most Oracle developers

The goal of this chapter is to provide developers who have a background in SQL andPL/SQL with an understanding of the Java language structures This is not an exhaustivereview of Java (there are numerous books that accomplish that goal) but rather a short overview

of the Java language components most commonly used by Oracle developers

Although there are many cases in which PL/SQL and Java correlate well to each other, thereare significant differences in terminology and usage That shouldn’t be surprising, since the two

programming languages were developed independently Furthermore, PL/SQL’s object-oriented

capabilities were not part of its initial implementation, whereas Java has been object-oriented

since its inception To use Java effectively, you need to take a different approach than the one

you may have taken in the past with PL/SQL

Chapter 27 presented an introduction to the PL/SQL language structures and flow control Thischapter mirrors that approach: You will see the structures used by Java and the basic flow-control

methods provided Where applicable, you will also see the matching PL/SQL structures You

should be familiar with PL/SQL (Chapter 27); packages, functions, and procedures (Chapter 29);

and abstract datatypes and methods (Chapter 30) before reading this chapter

Java vs PL/SQL: An Overview

In comparing PL/SQL to Java, you get no further than the basic PL/SQL structure—a block—

before you encounter a significant difference in terminology between the two languages In

PL/SQL, ablock is a structured piece of code that has a Declarations section, an Executable

Commands section, and an Exception Handling section For a PL/SQL block, the structure may

In Java, the termblock refers to a much smaller subset of code In Java, a block is a collection

of statements enclosed by curly braces, { and } For example, the following pseudocode contains

two Java blocks:

Trang 15

Within PL/SQL, that entire code section would be merely one part of a larger block; withinJava, it contains two separate blocks Throughout this chapter, all references to “blocks” refer to

Java blocks unless otherwise specified

A second major difference between PL/SQL and Java is in the declaration of variables In aPL/SQL block, you define your variables before you begin the Executable Commands section

In a Java program, you can define variables where they are needed within the program A Java

program has no Declarations section comparable to the one used in PL/SQL blocks

Throughout this chapter, you will see a number of other differences between PL/SQL andJava It’s important to remember that Java does not replace PL/SQL within your applications—you

can continue to use PL/SQL for Oracle applications For data-retrieval operations, you should test

the performance of PL/SQL and Java before deciding on a technical direction to follow

Getting Started

To use the examples in this section, you need a copy of the Java Development Kit (JDK), which is

available for free download from http://java.sun.com You need to install the JDK on the server

on which you will be running the Java programs As of the time of this writing, JDK 1.4 is the

most recent production release; most development efforts use JDK 1.3.1 At a minimum, you

should use JDK 1.2.2

Declarations

Within Java, you can declare variables as needed A variable has a name and a datatype, and is

used to store a data value during the program’s execution A variable also has a scope, allowing

it to be publicly accessible or private—similar to the manner in which procedures within packages

can have private variables

Examples of Java variable declarations include:

char aCharVariable = 'J';

boolean aBooleanVariable = false;

By convention, Java variables always start with a lowercase letter, as shown in this example

In the example, the datatypes are CHAR and BOOLEAN, and each variable is assigned an initial

value Note that the assignment character in Java is =, as opposed to := or => in PL/SQL Each

declaration is terminated with a semicolon

The available primitive datatypes in Java are listed in Table 34-1

Datatype Description

byte Byte-length integer

short Short integer

TABLE 34-1. Primitive Java Datatypes

Trang 16

In addition to the primitive datatypes listed in Table 34-1, you can use reference datatypes,which are based on the contents of variables You may note that there is no primitive datatype

for variable-length character strings—Java provides a String class for that purpose Classes are

discussed later in this chapter

Executable Commands

You can assign values to variables via the use of expressions and statements The arithmetic

operators supported by Java include:

float Single-precision floating-point real number

double Double-precision floating-point real number

char A single Unicode character

boolean A Boolean value, true or false

TABLE 34-1. Primitive Java Datatypes (continued)

Trang 17

In PL/SQL, that would have been written:

aLoopCounter := aLoopCounter +1;

If the ++ operator is placed in front of the variable name, then it is apreincrement operatorrather than apostincrement operator:

int anotherCounter = ++aLoopCounter;

In this example, the variableanotherCounter is set to the incremented value of aLoopCounter

By contrast,

int anotherCounter = aLoopCounter++;

setsanotherCounter to the value of aLoopCounter before it is incremented You can decrement a

variable’s value, via the unary operator:

You can perform similar combinations using /=, %=, +=, and -=

If you perform multiple arithmetic operations, you should use parentheses to clearly indicatethe order in which the operations should be evaluated, as shown in the following example

aNumberVariable = (aNumberVariable*2) +2;

Terminating these operations with semicolons makes themstatements—complete units

of execution

Conditional Logic

You can evaluate variables by using expressions and statements To do so, you may use one or

more of the fundamental classes provided as part of Java A full listing of those methods is beyond

the scope of this book; see Sun’s Java documentation site or one of the many Java books available

for the functionality currently provided

NOTE

The number of supplied classes changes dramatically with eachrelease of Java

Trang 18

In the following listing, the Character.isUpperCase method is used to evaluate theaCharVariabledeclared earlier:

if (Character.isUpperCase(aCharVariable)) {

some commands to execute

}

If theaCharVariable value is uppercase, the commands in the following block will be executed;

otherwise, flow will continue to the next part of the program

The following is the general syntax for if clauses:

In addition to supporting if clauses for conditional logic, Java features a switch clause Used

in conjunction with its break clause and statement labels, the switch clause can approximate the

functionality of goto clauses (which Java does not support) First, let’s look at a simple switch

example Using the case statement, multiple values of theaMonth variable are evaluated Depending

on theaMonth value, the text name for the month is displayed, and the processing leaves the

switch block by means of a break.

Trang 19

value If the value matches a case value, then the System.out.println method is called to print the

month’s name, and processing control leaves the switch block by means of a break If the value

does not match one of the case clauses, then the default option is executed.

Where does control go? By default, it goes to the next section of the program However, youhave the option of creating labels for sections of your code, and passing the name of those labels

to the break clause The following listing shows an example of a label and a break clause:

assigned a value of 2, so the program will display the word “February” and will then branch over

to the section of code identified by the someotherlabel label If theaMonth value had been 1, the

if clause at the beginning of the code listing would have been reexecuted.

Trang 20

Java also supports aternary operator—an operator that takes three operands and whose function

is similar to that of DECODE Acting as an inline if-else combination, the ternary operator evaluates

an expression If the expression evaluates to true, then the second operand is returned, else the

third is returned The syntax is as follows:

expression ? operand1 : operand2

The following listing shows a sample ternary operation:

aStatusVariable = (aCharVariable == 'V') ? "OK" : "Invalid";

In this example, the expression

(aCharVariable == 'V')

is evaluated If it is true, “OK” is returned; otherwise, “Invalid” is returned

You can use the ternary operator to simulate the use of a GREATEST function:

double greatest = (a > b) ? a : b;

In this example, the expression (a>b) is evaluated, wherea and b are the names of variables If that

expression is true,a’s value is returned; otherwise, b’s value is returned

NOTE

Java has a “greatest” method for numeric values—theMax method within the java.lang.Math class The ternaryexample in the preceding listing can be rewritten as

double greatest = Math.max(a, b);

You can combine multiple logic checks via the use of AND and OR operations In Java, an

AND operation is represented by the && operator:

if (aCharVariable == 'V' && aMonth == 3) {

AND operator, if the first value is false, then the evaluation ends at that point and the Boolean

value false is returned In the case of the OR operator, if the first expression is false, the second

expression will still be evaluated because only one of the test conditions needs to be true for the

634 Part V: Java in Oracle

Trang 21

Boolean value true to be returned If the first value of the OR operator were true, then subsequent

expressions would not need to be evaluated and true would be returned

The & and | operators are bitwise AND and OR; they are not short-circuited as && and || are.

All expressions will always be evaluated This functionality can be important if you are testing the

return values of method calls and you need to make sure the methods are executed

Loops

Java supports three main types of loops: WHILE loops, DO-WHILE loops, and FOR loops In this

section, you will see examples of each type of loop Since Java is not written as an extension of

SQL, it does not support cursor FOR loops as PL/SQL does

WHILE Loops and DO-WHILE Loops

A while clause evaluates a condition; if the condition is true, the associated block of statements is

executed The syntax for a WHILE loop is of the following form:

In this example, a counter variable (aNumberVariable) is created and initialized The variable’s

value is then evaluated via the while clause If the value is less than 7, the associated statement

block is executed As part of that block, the variable is incremented When the block completes,

the variable is again evaluated and the loop continues

NOTE

For examples of WHILE loop processing, see “Classes”

later in this chapter

You could also write this as a DO-WHILE loop:

Trang 22

In a DO-WHILE loop, the expression’s value is not evaluated until the block has beenprocessed at least one time.

FOR Loops

You can use a FOR loop to repeatedly execute a block of code In a FOR loop, you specify an

initial value, a termination value, and an increment for the loop counter The loop counter will

be incremented each time through the loop by the increment you specify until the termination

value is reached The following is the syntax for a FOR loop:

for (initialization; termination; increment) {

The for clause version for this example is much shorter than the while version In this example,

theaNumberVariable variable is declared and initialized within the FOR loop As long as the

variable’s value does not exceed 7, the block will be executed For each pass through the loop,

the variable’s value is incremented by 1 via the ++ unary operator.

Within a loop, you can use the continue clause to jump to another statement within the loop.

If you just use the continue clause by itself, the process flow will jump to the end of the loop body

and evaluate the loop’s termination test If you use continue with a label (as shown previously in

the section on the switch clause), processing will continue at the next iteration of the labeled loop.

Cursors and Loops

Within PL/SQL, you can use cursor FOR loops to iterate through the results of a query You can

use Java’s WHILE and FOR loops to simulate the functionality of a PL/SQL cursor FOR loop The

examples provided with Oracle9i show how this can be accomplished Java examples are found

in the /jdbc/demo directory under the Oracle software home directory The Employee.java file

found there creates the Employee class within Java As part of that class, the example issues the

following commands:

Statement stmt conn.createStatement();

ResultSet rset = stmt.executeQuery ("select ENAME from EMP");

//iterate through the result set and print the employee names

while (rset.next ())

System.out.println (rset.getString (1));

This example assumes that a connection to the database has already been established Thefirst line of the example creates a variable calledstmt, based on a connection variable called

conn (not shown in this partial listing) The second line of the example creates a variable called

rset, based on the result set that the query stmt will return Following a comment (prefixed by //),

636 Part V: Java in Oracle

Trang 23

a while clause fetches each row in the result set If the fetch retrieves a row from the result set,

the ENAME from that EMP row is printed; otherwise, the loop will end

From a programming perspective, you should be specific in the data returned The exampleprovided by Oracle can be modified to use the column name returned, instead of an absolute

column number, as shown in the following listing:

Statement stmt conn.createStatement();

ResultSet rset = stmt.executeQuery ("select ENAME from EMP");

//iterate through the result set and print the employee names

while (rset.next()) {

System.out.println (rset.getString ("ENAME"));

}

The JDBC (Java Database Connectivity; see Chapter 35) demos provided by Oracle show samples

of queries involving procedure calls, LOBs, and DML In most cases, your Java code will be

performing in a similar manner to the previous example: Write the process flow-control language

in Java and pass it a statement to execute Based on the outcome of that statement, you can direct

different actions to occur via the use of while, for, if, break, continue, and switch clauses, as shown

earlier in this chapter

Exception Handling

Java provides a robust set of error-handling routines and enables you to create complex error-handling

procedures In PL/SQL, you raise an exception; in Java, you throw exceptions If an exception is

thrown, you need to use the Java catch clause to capture and properly process the exception.

Java’s exception-handling syntax is based on three blocks: try, catch, and finally The try block includes the statements that might throw an exception The catch block immediately

following the try block associates exception handlers with the exceptions that may be thrown by

the try block The finally block cleans up any system resources not properly cleaned up during the

catch block processing The general structure is as follows:

Trang 24

stmt.execute ("drop table plsqltest");

clause tells Java to handle it via an exception object called SQLException, a standard part of Java’s

SQL implementation As shown in the example, the catch clause takes two parameters (an exception

object and a variable name) and is optionally followed by a block of statements to execute

The try block can contain multiple statements, or you can create separate try blocks for each statement In general, it is easier to manage exception handling if you consolidate your catch blocks,

so consolidating your try blocks will help you manage your code as it changes and grows.

The finally block cleans up the state of the current code section before passing control to any subsequent parts of the program At runtime, the contents of the finally block are always executed,

regardless of the outcome of the try block For example, you could use the finally block to close

a database connection

Reserved Words

The reserved words in Java are listed in Table 34-2 You cannot use these words as the names of

classes, methods, or variables

638 Part V: Java in Oracle

TABLE 34-2. Java Reserved Words

Trang 25

In the prior sections of this chapter, you saw the basic syntax structures for Java In this section,

you will see how to use that syntax to create and use objects A simple program for printing the

word “Oracle” is shown in the following listing:

public class HelloOracle {

public static void main (String[] args) {

select 'Oracle' from dual;

but the Java version has features lacking in the SQL version HelloOracle is a class, and as such

its methods can be called from within other classes HelloOracle could have multiple methods;

in this example, it has only the main method

The main method’s declaration (public static void main) has a number of keywords that you

should become familiar with:

public Defining the class as public allows all classes to call this method.

static Declares that this is a class method; you use static to declare class methods An

additional option is the keyword final for methods and variables whose values cannot change (similar to PL/SQL’s constant option).

void Specifies the return value’s data type from the procedure Since this procedure

does not return values, its type is void.

In this example, the method is given the name main because that will simplify running theclass’s method Now that the class has been created, you can compile and load it

First, save the program as a plain text file called HelloOracle.java Next, compile it:

javac HelloOracle.java

Trang 26

A new file, called HelloOracle.class, will be created on your server You can then run the class:

class variables and methods are defined As with abstract datatypes in Oracle, Java classes have

methods associated with them for the manipulation of their related data

Let’s consider a more complex example The following listing is a Java program that computesthe area of a circle, given a radius value as input (see Chapter 27 for the PL/SQL version):

// AreaOfCircle.java

//

public class AreaOfCircle {

public static void main(String[] args) {

try { int input = Integer.parseInt(args[0]);

double result=area(input);

System.out.println(result);

} catch (ArrayIndexOutOfBoundsException oob) { System.out.println("You did not provide the radius of the circle.");

System.out.println("Usage: java AreaOfCircle 10");

} catch (NumberFormatException nfe) { System.out.println("Enter a valid number for the radius.");

System.out.println("Usage: java AreaOfCircle 10");

} } /// main

public static double area (int rad) {

640 Part V: Java in Oracle

Trang 27

First, note that the class and the name of the file must be the same In this case, the class isnamed AreaOfCircle, so this text is stored in a file called AreaOfCircle.java The class has two

methods, called main and area When you execute the class, the main method is automatically

executed The main method takes the string provided as input and parses it as an integer into the

input variable:

int input=Integer.parseInt(args[0]);

There are at least two possible exceptions that could be thrown when running this code Thefirst exception handled, ArrayIndexOutOfBoundsException, occurs when you try to reference a

position in an array that doesn’t exist As the code explicitly references the first position of the

array named args (args[0]), an exception will be thrown if no data was passed to the program

The other possible error, NumberFormatException, would occur if a non-numeric value was

passed in For example, if you ran the program by entering, “java AreaOfCircle XYZ” instead of

“java AreaOfCircle 123”, the NumberFormatException would be thrown because XYZ isn’t a

valid number Both of these exceptions are handled by the two catch statements that provide

the user with useful feedback regarding the cause of the error:

catch (ArrayIndexOutOfBoundsException oob) {

System.out.println("You did not provide the radius of the circle.");

System.out.println("Usage: java AreaOfCircle 10");

}

catch (NumberFormatException nfe) {

System.out.println("You did not enter a valid number for the radius.");

System.out.println("Usage: java AreaOfCircle 10");

processed, and a variable namedareacircle is calculated and returned to main In main, that

value is then printed:

double result=area(input);

System.out.println(result);

Trang 28

Testing the program is straightforward:

public class AreaOfCircleWhile {

public static void main(String[] args) { try {

int input=Integer.parseInt(args[0]);

while (input < 7) { double result=area(input);

System.out.println(result);

input++;

} } catch (ArrayIndexOutOfBoundsException oob) { System.out.println("You did not provide the radius of the circle.");

System.out.println("Usage: java AreaOfCircle 10");

} catch (NumberFormatException nfe) { System.out.println("Enter a valid number for the radius.");

System.out.println("Usage: java AreaOfCircle 10");

} } /// main public static double area (int rad) { double pi=3.1415927;

double areacircle=pi*rad*rad;

return areacircle;

} /// area } /// AreaOfCircleWhile

In this listing, the area method and the exception handling blocks are unchanged from theprior example The change is in the main method:

Trang 29

While the input value is less than 7, the input value will be processed After the area for that radius

value has been calculated and printed, the input value is incremented:

The output shows the area calculations for input radius values of 4, 5, and 6

This example is not as complete as a finished program—you may need additional exceptionhandling to handle non-integers, for example—but the structure is the important lesson to learn

from this example In addition to the methods shown in this example, you could create a constructor

for the AreaOfCircleWhile class All Java classes have constructors to initialize new objects based

on the class The constructor’s name is the same as the name of the class If you create a class with

no constructor, then Java will create a default constructor at runtime Like a method, the constructor

body can contain local variable declarations, loops, and statement blocks The constructor

initializes these variables for the class

In the following chapters, you will see how to implement Java within Oracle: within storedprocedures and via SQLJ/JDBC Those chapters assume that you have the basic knowledge of

Java that is provided in this chapter For additional information about the Java language, please

see the Sun Microsystems web site and the variety of books devoted to Java

Trang 31

35

JDBC and SQLJ Programming

Trang 32

J ava Database Connectivity (JDBC) and SQLJ build on the Java and programmingbasics described earlier in this book The discussions and examples in this chapter

assume you are familiar with the Java syntax and structures described in Chapter 34

This chapter does not cover every aspect of JDBC and SQLJ but focuses on the basicconfiguration and usage of these tools

You can use JDBC to execute dynamic SQL statements in Java programs Oracle providessample files with its standard software installation The following listing is from the Employee.java

demo file, located with the file /jdbc/demo/demo.zip under the Oracle software home directory

The Employee.java demo issues the following commands after establishing a database connection:

Statement stmt conn.createStatement();

ResultSet rset = stmt.executeQuery ("select ENAME from EMP");

//iterate through the result set and print the employee names

while (rset.next ())

System.out.println (rset.getString (1));

When you execute a SQL statement via JDBC—in this case, select Ename from EMP—the SQL

statement is not checked for errors until it is run The JDBC program that contains the SQL command

will compile even if the SQL statement is invalid

By contrast, SQLJ performs a precompilation step that includes syntax checks for the SQLembedded within the program SQLJ also performs type checking and schema checking to make

sure the data can be properly retrieved and processed When the SQLJ precompilation is complete,

the result is a Java program that runs via JDBC calls SQLJ and JDBC, though distinct, are interrelated

Getting Started

To use the examples in this section, you need a copy of the Java Development Kit (JDK), which

is available for free download from http://java.sun.com You need to install the JDK on the server

on which you will be developing and running the Java programs As of the time of this writing,

JDK 1.4 is the most recent production release; most development efforts use JDK 1.3.1 At a

minimum, you should use JDK 1.2.2 The examples in this chapter assume JDK 1.3.1 is in use

Additional Steps for NT Users

If you will be accessing Oracle9i, you must set the CLASSPATH environment variable to find

the classes12.zip file (for JDK 1.2.2 or 1.3.1) provided by Oracle The file is located in the

/jdbc/lib directory beneath your Oracle home directory or available for download from http://

technet.oracle.com For JDK 1.1.8, use the classes111.zip file found in the /jdbc/lib directory

NOTE

This step is not performed by the standard Oracle9i installation, soyou need to do it manually If the system variables are not properlyset, you will not be able to compile Java classes that use Oracle’sJDBC classes

646 Part V: Java in Oracle

Trang 33

To set your system variables, click the System icon in the Control Panel Choose the Environmenttab to list the environment variables and their definitions The PATH variable should already be

set, so select it and edit its value Add the new entry to the end of the list, as shown in the following

listing This value should be separated from the other values in the list by a semicolon

entry must be a period, which denotes the current directory The second entry must be the directory

for the classes12.zip file, using the same form and value as you used for the PATH value:

Testing Your Connection

Oracle provides a sample program called JdbcCheckup.java that you can use to verify your JDBC

configuration This file may be in a Zip file (demo.zip on the /jdbc/demo directory), in which case

you need to extract it before running the program Compile and execute the JdbcCheckup.java class:

javac JdbcCheckup.java

java JdbcCheckup

When you execute JdbcCheckup, you are prompted for a username, password, and connectstring for a database That connection information will be used to attempt a connection; if successful,

that attempt will return the following output:

Connecting to the database Connecting

connected.

Hello World.

Your JDBC installation is correct.

Trang 34

If you don’t receive feedback telling you that your installation is correct, you need to checkyour configuration Common problems include incorrectly set environment variables (PATH

and CLASSPATH) and mismatched versions of database connection drivers If you change the

environment variable values, you need to shut down and restart the command windows for the

changes to take effect

Using the JDBC Classes

JDBC is implemented in Oracle via a set of Oracle-provided classes whose names begin with

oracle.sql, while the standard JDBC classes provided with the JDK begin with java.sql The

JdbcCheckup.java class, shown in the following listing, provides a good roadmap for beginning

JDBC programmers The JdbcCheckup.java class assumes you are using Oracle Net to connect

to the database

NOTE

The following code is provided by Oracle Your programmingstandards may implement these commands differently, such as bycalling System.out.println in place of System.out.print, or by placingthe brackets in different places

/*

* This sample can be used to check the JDBC installation.

* Just run it and provide the connect information It will select

* "Hello World" from the database.

public static void main (String args [])

throws SQLException, IOException {

// Load the Oracle JDBC driver DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

// Prompt the user for connect information System.out.println ("Please enter information to test connection

to the database");

String user;

String password;

String database;

user = readEntry ("user: ");

648 Part V: Java in Oracle

Trang 35

int slash_index = user.indexOf ('/');

if (slash_index != -1) {

password = user.substring (slash_index + 1);

user = user.substring (0, slash_index);

} else { password = readEntry ("password: ");

} database = readEntry ("database (a TNSNAME entry): ");

System.out.print ("Connecting to the database ");

System.out.flush ();

System.out.println ("Connecting ");

Connection conn = DriverManager.getConnection ("jdbc:oracle:oci8:@" + database, user, password);

System.out.println ("connected.");

// Create a statement Statement stmt = conn.createStatement ();

// Run a query ResultSet rset=stmt.executeQuery("select 'Hello World' from dual");

// Loop through the query results while (rset.next ()) {

System.out.println (rset.getString (1));

} System.out.println ("Your JDBC installation is correct.");

// close the resultSet rset.close();

// Close the statement stmt.close();

// Close the connection conn.close();

}

// Utility function to read a line from standard input

static String readEntry (String prompt)

{

try {

StringBuffer buffer = new StringBuffer ();

Trang 36

System.out.print (prompt);

System.out.flush ();

int c = System.in.read ();

while (c != '\n' && c != -1) {

buffer.append ((char)c);

c = System.in.read ();

} return buffer.toString ().trim ();

} catch (IOException e) {

return "";

} }

}

NOTE

Production applications would be expected to include many moreexception handling sections than shown in this brief example SeeChapter 34 for an example of exception handling

Starting at the top, this script first imports the java.sql classes provided by Sun Microsystems:

user = readEntry ("user: ");

The readEntry function is defined later in the class, in the section beginning

// Utility function to read a line from standard input

static String readEntry (String prompt)

Once the connection data has been input, aconnection object is created to maintain thestate of the database session The getConnection call in the following listing starts the connection:

Trang 37

If you receive an error during the connection, this step is usually the cause An incorrectusername/password combination, a mismatched set of drivers, or failure to install and configure

Oracle Net will cause this step to fail

By default, a connection object is created with autocommit turned on—every transaction is

automatically committed To change that setting, you can use the following command (assuming

you name the connection object conn, as shown in the example):

method, and then it’s executed via the executeQuery method In place of executeQuery, you can

use execute or, if running an insert, update, or delete SQL statement, executeUpdate If you select

a column value (instead of just a text string), you should specify that column value in the print

command, as shown in the following listing

ResultSet rset =stmt.executeQuery("select User from dual");

while (rset.next ()) {

System.out.println (rset.getString ("USER"));

Using JDBC for Data Manipulation

Let’s combine the pieces that have been described so far: the basic connection syntax from

this chapter with the Java classes from Chapter 34 The example in this section will query the

RADIUS_VALS table, calculate an area for each value, and insert those values into the AREAS

table Thus, it requires the use of the Java equivalent of a cursor FOR loop, along with support

for executable commands and inserts.

For the example, put three records into the RADIUS_VALS table:

delete from RADIUS_VALS;

insert into RADIUS_VALS(Radius) values (3);

insert into RADIUS_VALS(Radius) values (4);

insert into RADIUS_VALS(Radius) values (10);

commit;

Trang 38

The following listing, JdbcCircle.java, contains the connection components fromJdbcCheckup.java The executable commands for the circle area start in the section called

RetrieveRadius, shown in bold in the listing

// You need to import the java.sql package to use JDBC

import java.sql.*;

// We import java.io to be able to read from the command line

import java.io.*;

class JdbcCircle {

public static void main (String args [])

throws SQLException, IOException { // Load the Oracle JDBC driver

user = readEntry ("user: ");

int slash_index = user.indexOf ('/');

if (slash_index != -1) { password = user.substring (slash_index + 1);

user = user.substring (0, slash_index);

} else { password = readEntry ("password: ");

} database = readEntry ("database (a TNSNAME entry): ");

System.out.println ("Connecting to the database ");

Connection conn = DriverManager.getConnection ("jdbc:oracle:oci8:@" + database, user, password);

System.out.println ("connected.");

// Create a statement Statement stmt = conn.createStatement ();

// RetrieveRadius

ResultSet rset =stmt.executeQuery("select Radius from RADIUS_VALS");

while (rset.next ()) { // if you wish to print the values:

// System.out.println (rset.getInt ("RADIUS"));

652 Part V: Java in Oracle

Trang 39

int radInput = rset.getInt ("RADIUS");

// Retrieve Radius value, calculate area:

double result = area(radInput);

// insert the value into AREAS String sql = "insert into AREAS values ("+radInput+","+result+ ")";

// If you want to print the SQL statement:

// System.out.println(sql);

// Create a statement for the insert:

Statement insArea = conn.createStatement();

// Execute the insert:

boolean insertResult = insArea.execute(sql);

} // close the resultSet rset.close();

// Close the statement stmt.close();

// Close the connection conn.close();

}

// Utility function to calculate the area

public static double area (int rad) {

double pi=3.1415927;

double areacircle=pi*rad*rad;

return areacircle;

}

// Utility function to read a line from standard input

static String readEntry (String prompt) {

try { StringBuffer buffer = new StringBuffer ();

System.out.print (prompt);

System.out.flush ();

int c = System.in.read ();

while (c != '\n' && c != -1) { buffer.append ((char)c);

c = System.in.read ();

} return buffer.toString ().trim ();

} catch (IOException e) { return "";

Trang 40

654 Part V: Java in Oracle

} }

}

In the RetrieveRadius section, the query to be executed is passed to the executeQuery method

The result of the query is stored in a variable namedrset

// RetrieveRadius

ResultSet rset =stmt.executeQuery("select Radius from RADIUS_VALS");

As noted in Chapter 34, you can use a WHILE loop in Java to approximate the functionality

of a PL/SQL cursor FOR loop The following section of the RetrieveRadius section uses the getInt

method to retrieve the integer Radius value from the result set If the value had been a string, then

the getString method would have been used instead

while (rset.next ()) { // if you wish to print the values:

// System.out.println (rset.getInt ("RADIUS"));

int radInput = rset.getInt ("RADIUS");

TheradInput variable, assigned in the preceding listing, can now be used as input to the areacalculation The area calculation is performed via a utility function (see the full JdbcCircle listing)

based on the code examples presented in Chapter 34

// Retrieve Radius value, calculate area:

double result = area(radInput);

We now have the radius value (theradInput variable) and the area value (the result variable)

to use when populating the AREAS table Let’s build the insert statement to perform the insert First,

use the string concatenation functions in Java to concatenate text with the variable values Make

sure not to include a semicolon at the end of the generated command string

// insert the value into AREAS String sql = "insert into AREAS values ("+radInput+","+result+ ")";

// If you want to print the SQL statement:

// System.out.println(sql);

Next, create a statement and execute the insert command (via a call to thesql variable thatcontains the command text):

// Create a statement for the insert:

Statement insArea = conn.createStatement();

// Execute the insert:

boolean insertResult = insArea.execute(sql);

Did it work? Compile and execute the JdbcCircle.java file, and then check the AREAS table:

select * from AREAS

order by Radius;

Ngày đăng: 07/08/2014, 14:20

TỪ KHÓA LIÊN QUAN