Oracle9i SQLJ Developer's Guide and Reference Release 2 (9.2) Part Number A96655-01 |
|
This chapter provides a general overview of SQLJ features and scenarios. The following topics are discussed:
This section introduces the basic concepts of SQLJ and discusses the complementary relationship between Java and PL/SQL in Oracle applications.
SQLJ enables applications programmers to embed SQL operations in Java code in a way that is compatible with the Java design philosophy. A SQLJ program is a Java program containing embedded SQL statements that comply with the ISO standard SQLJ Language Reference syntax. Oracle9i SQLJ supports the ISO SQLJ standard specification. The standard covers only static SQL operations--those that are predefined and do not change in real-time as a user runs the application (although the data values that are transmitted can change dynamically). Oracle SQLJ also offers extensions to support dynamic SQL operations--those that are not predefined, where the operations themselves can change in real-time. (It is also possible to use dynamic SQL operations through JDBC code or PL/SQL code within a SQLJ application.) Typical applications contain much more static SQL than dynamic SQL.
SQLJ consists of both a translator and a runtime component and is smoothly integrated into your development environment. The developer runs the translator, with translation, compilation, and customization (for ISO standard code) taking place in a single step when the sqlj
front-end utility is run. The translation process replaces embedded SQL with calls to the SQLJ runtime, which implements the SQL operations. In ISO standard SQLJ this is typically, but not necessarily, performed through calls to a JDBC driver. To access an Oracle database, you would typically use an Oracle JDBC driver. When the end user runs the SQLJ application, the runtime is invoked to handle the SQL operations.
The Oracle SQLJ translator is conceptually similar to other Oracle precompilers and allows the developer to check SQL syntax, verify SQL operations against what is available in the schema, and check the compatibility of Java types with corresponding database types. In this way, errors can be caught by the developer instead of by a user at runtime. The translator checks the following:
It verifies table names and column names, for example.
The SQLJ methodology of embedding SQL operations directly in Java code is much more convenient and concise than the JDBC methodology. In this way, SQLJ reduces development and maintenance costs in Java programs that require database connectivity.
While the Oracle SQLJ implementation supports the ISO SQLJ standard, it also offers the option of Oracle-specific code generation, where Oracle JDBC calls are generated directly into the code. As of Oracle9i release 2, this is the default behavior. In the case of Oracle-specific code generation, be aware of the following:
Much of the SQLJ introductory discussion in this chapter mentions features of ISO standard code, so be aware of these key differences in Oracle-specific code.
For more information, see "Oracle-Specific Code Generation (No Profiles)".
Java (including SQLJ) in Oracle applications does not replace PL/SQL. Java and PL/SQL are complementary to each other in the needs they serve.
While PL/SQL and Java can both be used to build database applications, the two languages were designed with different intents and, as a result, are suited for different kinds of applications:
Oracle provides easy interoperability between PL/SQL and Java, ensuring that you can take advantage of the strengths of both languages. PL/SQL programs can transparently call Java stored procedures, enabling you to build component-based Enterprise JavaBeans applications. PL/SQL programs can have transparent access to a wide variety of existing Java class libraries through PL/SQL call specifications.
Java programs can call PL/SQL stored procedures and anonymous blocks through JDBC or SQLJ. In particular, SQLJ provides syntax for calling stored procedures and functions from within a SQLJ statement, and also supports embedded PL/SQL anonymous blocks within a SQLJ statement.
Note: Using PL/SQL anonymous blocks within SQLJ statements is one way to support dynamic SQL in a SQLJ application. However, Oracle9i SQLJ includes extensions to support dynamic SQL directly. (See "Support for Dynamic SQL".) |
This section introduces the main SQLJ components and the concept of SQLJ profiles. (Profiles are for ISO code generation only.)
Oracle SQLJ consists of two major components:
The translator, written in pure Java, supports a programming syntax that allows you to embed SQL operations inside SQLJ executable statements. SQLJ executable statements, as well as SQLJ declarations, are preceded by the #sql
token and can be interspersed with Java statements in a SQLJ source code file. SQLJ source code file names must have the .sqlj
extension. Here is a sample SQLJ statement:
#sql { INSERT INTO emp (ename, sal) VALUES ('Joe', 43000) };
The translator produces a .java
file and, for ISO standard SQLJ code generation, one or more SQLJ profiles, which contain information about your SQL operations. SQLJ then automatically invokes a Java compiler to produce .class
files from the .java
file.
Note: By default as of Oracle9i release 2, there is an Oracle-specific code generation setting that results in translation directly into Oracle JDBC code. In this case, no profiles are produced. See "Oracle-Specific Code Generation (No Profiles)". |
For ISO standard code generation, the SQLJ runtime implements the desired actions of your SQL operations, accessing the database using a JDBC driver. The generic ISO SQLJ standard does not require that a SQLJ runtime use a JDBC driver to access the database; however, Oracle SQLJ does require a JDBC driver, and, in fact, requires an Oracle JDBC driver if your application is customized with the default Oracle customizer (see below).
For Oracle-specific code generation (the default), Oracle JDBC calls are generated directly into the translated code and the SQLJ runtime plays a much smaller role.
For more information about the runtime, see "SQLJ Runtime".
In addition to the translator and runtime, there is a component known as the customizer that plays a role if you use ISO standard code generation. A customizer tailors SQLJ profiles for a particular database implementation and vendor-specific features and datatypes. By default, for ISO standard code, the Oracle SQLJ front end invokes an Oracle customizer to tailor your profiles for an Oracle database and Oracle-specific features and datatypes.
When you use the Oracle customizer during translation, your application will require the Oracle SQLJ runtime and an Oracle JDBC driver when it runs.
With ISO standard SQLJ code generation, SQLJ profiles are serialized Java resources (or, optionally, classes) generated by the SQLJ translator, which contain details about the embedded SQL operations in your SQLJ source code. The translator creates these profiles, then either serializes them and puts them into binary resource files, or puts them into .class
files (according to your translator option settings).
Note: By default, as of Oracle9i release 2, Oracle-specific code generation is used. In this case, the translator generates Oracle JDBC calls directly, and details of your embedded SQL operations are embodied in the JDBC calls. There are no profiles. See "Oracle-Specific Code Generation (No Profiles)". |
SQLJ profiles are used in ISO standard code in implementing the embedded SQL operations in your SQLJ executable statements. Profiles contain information about your SQL operations and the types and modes of data being accessed. A profile consists of a collection of entries, where each entry maps to one SQL operation. Each entry fully specifies the corresponding SQL operation, describing each of the parameters used in executing this instruction.
For ISO code generation, SQLJ generates a profile for each connection context class in your application, where, typically, each connection context class corresponds to a particular set of SQL entities you use in your database operations. (There is one default connection context class, and you can declare additional classes.) The ISO SQLJ standard requires that the profiles be of standard format and content. Therefore, for your application to use vendor-specific extended features, your profiles must be customized. By default, this occurs automatically, with your profiles being customized to use Oracle-specific extended features.
Profile customization allows vendors to add value in two ways:
PreparedStatement
method calls in translated SQLJ code to OraclePreparedStatement
method calls, which provide support for Oracle type extensions.For example, you must customize your profile to use Oracle objects in your SQLJ application.
SQLJ-generated profile files support binary portability. That is, you can port them as is and use them with other kinds of databases or in other environments if you have not employed vendor-specific datatypes or features. This is true of generated .class
files as well.
Oracle9i SQLJ supports the ISO SQLJ specification. Because the ISO SQLJ standard is a superset of the ANSI SQLJ standard, it requires a JDK 1.2 or later environment that complies with J2EE. The ANSI SQLJ standard requires only JDK 1.1.x. The Oracle SQLJ translator accepts a broader range of SQL syntax than the ANSI SQLJ standard specifies.
The ANSI standard addresses only the SQL92 dialect of SQL, but allows extension beyond that. Oracle SQLJ supports the Oracle SQL dialect, which is a superset of SQL92. If you need to create SQLJ programs that work with other DBMS vendors, avoid using SQL syntax and SQL types that are not in the standard and, therefore, may not be supported in other environments. (On your product CD, the directory [Oracle_Home]/sqlj/demo/components
includes a semantics-checker that you can use to verify that your SQLJ statements contain only standard SQL.)
For general information about Oracle SQLJ extensions, see Chapter 5, "Type Support", and Chapter 6, "Objects, Collections, and OPAQUE Types".
Oracle SQLJ supports the Java types listed below as extensions to the SQLJ standard. Do not use these or other types if you may want to use your code in other environments. To ensure that your application is portable, use the Oracle SQLJ -warn=portable
flag. See "Translator Warnings (-warn)".
Using any of the following extensions requires Oracle-specific code generation or Oracle customization during translation, as well as the Oracle SQLJ runtime and an Oracle JDBC driver when your application runs.
oracle.sql.*
classes as wrappers for SQL data
See "Support for JDBC 2.0 LOB Types and Oracle Type Extensions".
oracle.sql.ORAData
interface or the JDBC standard java.sql.SQLdata
interface), typically produced by the Oracle9i JPublisher utility to correspond to SQL objects, object references, and collections
See "Custom Java Classes". Note, however, that the SQLData
interface is standard. Classes that implement it are likely supported by other vendors' JDBC drivers and databases.
BinaryStream
and CharacterStream
, the latter of which replaces the deprecated AsciiStream
and UnicodeStream
, used as output parameters (see "Support for Streams")The SQLJ standard specifies them only in result expressions or cast statements; see "Using Iterators and Result Sets as Host Variables" and "Using Iterators and Result Sets as Stored Function Returns".
NString
, NCHAR
, NCLOB
, and NcharCharacterStream, the latter of which replaces the deprecated NcharAsciiStream
and NcharUnicodeStream
(see "Oracle SQLJ Extended Globalization Support")Oracle SQLJ also supports the following extended functionality:
This generates JDBC code directly. No profiles are produced and much of the SQLJ runtime functionality is bypassed during program execution. See "Oracle-Specific Code Generation (No Profiles)".
FETCH
syntax from result set iterators and scrollable result set iterators
See "Column Definitions", "Parameter Size Definitions", and "Options for Code Generation, Optimizations, and CHAR Comparisons".
CHAR
comparisons for WHERE
clauses
See "Binding Host Expressions by Identifier (-bind-by-identifier)" and "CHAR Comparisons with Blank Padding (-fixedchar)".
See "Statement Caching".
This section introduces the following:
For more detailed information about the translation steps, see "Internal Translator Operations".
SQLJ source code contains a mixture of standard Java source together with SQLJ class declarations and SQLJ executable statements containing embedded SQL operations.
SQLJ source files have the .sqlj
file name extension. The file name must be a legal Java identifier. If the source file declares a public class (maximum of one), then the file name must match the name of this class. If the source file does not declare a public class, then the file name should match the first defined class.
After you have written your .sqlj
file, you must run SQLJ to process the files. (For coding the .sqlj
file, basic SQLJ programming features and key considerations are discussed in Chapter 3 and Chapter 4.) The following example, for the source file Foo.sqlj
whose first public class is Foo
, shows SQLJ being run in its simplest form, with no command-line options:
sqlj Foo.sqlj
What this command actually runs is a front-end script or utility (depending on the platform) that reads the command line, invokes a Java virtual machine (JVM), and passes arguments to it. The JVM invokes the SQLJ translator and acts as a front end.
This document refers to running the front end as "running SQLJ" and to its command line as the "SQLJ command line". For information about command-line syntax, see "Command-Line Syntax and Operations".
From this point the following sequence of events occurs (presuming each step completes without fatal error). See "Internal Translator Operations" for more detailed information.
.sqlj
file, checking for proper SQLJ syntax and looking for type mismatches between your declared SQL datatypes and corresponding Java host variables. (Host variables are local Java variables used as input or output parameters in your SQL operations. "Java Host Expressions, Context Expressions, and Result Expressions" describes them.)When online checking is specified, SQLJ will connect to a specified database schema to verify that the database supports all the database tables, stored procedures, and SQL syntax that the application uses, and that the host variable types in the SQLJ application are compatible with datatypes of corresponding database columns.
-codegen=oracle
), SQL operations are converted directly into Oracle JDBC calls, and no profiles are produced. See "Oracle-Specific Code Generation (No Profiles)".
For ISO standard code generation (-codegen=iso
), the translator processes your SQLJ source code, converts SQL operations to SQLJ runtime calls, and generates Java output code and one or more SQLJ profiles. A separate profile is generated for each connection context class in your source code, where a different connection context class is typically used for each interrelated set of SQL entities that you use in your operations.
Generated Java code is put into a .java
output file containing the following:
.sqlj
source fileGenerated profiles (for ISO standard code generation only) contain information about all the embedded SQL statements in your SQLJ source code, such as actions to take, datatypes being manipulated, and tables being accessed. When your application is run, the SQLJ runtime accesses the profiles to retrieve your SQL operations and passes them to the JDBC driver.
By default, profiles (if applicable) are put into .ser
serialized resource files, but SQLJ can optionally convert the .ser
files to .class
files as part of the translation.
javac
provided with the Sun Microsystems JDK..class
files as appropriate. This will include a .class
file for each class you defined, a .class
file for each of your SQLJ declarations, and a .class
file for the profile-keys class (for ISO code generation).Consider the following when translating and running SQLJ applications:
.java
files on the command line to be compiled (and to be available for type resolution as well), or to specify pre-existing profiles to be customized, or to specify .jar
files containing profiles to be customized. See "Translator Command Line and Properties Files" for more information.-profile=false
when you translate, to bypass Oracle-specific customization.This section summarizes what the SQLJ translator takes as input, what it produces as output, and where it places its output.
Note: This discussion mentions iterator class and connection context class declarations. Iterators are similar to JDBC result sets; connection contexts are used for database connections. For more information about these class declarations, see "Overview of SQLJ Declarations". |
In its most basic operation, the SQLJ translator takes one or more .sqlj
source files as input in its command line. The name of your main .sqlj
file is based on the public class it defines, if any, or else on the first class it defines. Each public class you define must be in its own .sqlj
file.
If your main .sqlj
file defines class MyClass
, then the source file name must be:
MyClass.sqlj
This must also be the file name if there are no public class definitions but MyClass
is the first class defined.
When you run SQLJ, you can also specify numerous SQLJ options in the command line or properties files.
For more information about SQLJ input, including additional types of files you can specify in the command line, see "Translator Command Line and Properties Files".
The translation step produces a Java source file for each .sqlj
file in your application, and, for ISO standard code generation, at least one application profile (presuming your source code uses SQLJ executable statements).
SQLJ generates source files and profiles as follows:
.java
files with the same base names as your .sqlj
files.
For example, MyClass.sqlj
defines class MyClass
and the translator produces MyClass.java
. The output .java file also contains class definitions for any iterators or connection context classes you declare.
.sqlj
file, plus the following extensions:
_SJProfile0.ser _SJProfile1.ser _SJProfile2.ser ...
For example, for MyClass.sqlj
the translator produces:
MyClass_SJProfile0.ser
The .ser
file extension reflects the fact that the profiles are serialized. The .ser
files are binary files.
The compilation step compiles the Java source file into multiple class files. There is one .class
file for each class you define in your .sqlj
source file (minimum of one), and, for ISO code, one for a class known as the profile-keys class that the translator generates and uses with the profiles to implement your SQL operations (presuming your source code uses SQLJ executable statements). Additional .class
files are produced if you declared any SQLJ iterators or connection contexts. (See "Overview of SQLJ Declarations".) Also, separate .class
files will be produced for any inner classes or anonymous classes in your code.
For Oracle-specific code generation (the default), no profiles or profile-keys class are produced. For information about Oracle-specific code generation, see "Oracle-Specific Code Generation (No Profiles)".
The .class
files are named as follows:
.class
extension.
For example, the translator output file MyClass.java
is compiled into the MyClass.class
class file.
.sqlj
file, plus the following:
_SJProfileKeys
So the class file has the following extension:
_SJProfileKeys.class
For example, for MyClass.sqlj
, the translator together with the compiler produce:
MyClass_SJProfileKeys.class
MyIter
, there will be a MyIter.class
class file.The customization step alters the profiles but produces no additional output.
Note: It is not necessary to reference SQLJ profiles or the profile-keys class directly. This is all handled automatically. |
By default, SQLJ places generated .java
files in the same directory as your .sqlj
file. You can specify a different .java
file location, however, using the SQLJ -dir
option.
By default, SQLJ places generated .class
and .ser
files (if any) in the same directory as the generated .java
files. You can specify a different .class
and .ser
file location, however, using the SQLJ -d
option. This option setting is passed to the Java compiler so that .class
files and .ser
files will be in the same location.
For either the -d
or -dir
option, you must specify a directory that already exists. For more information about these options, see "Options for Output Files and Directories".
This section discusses runtime processing during program execution, considering both Oracle-specific code generation and ISO standard SQLJ code generation.
When you translate with the default setting -codegen=oracle
, your program at runtime will execute the following:
For general information about Oracle-specific code generation, see "Oracle-Specific Code Generation (No Profiles)".
For ISO standard SQLJ applications, the SQLJ runtime reads the profiles and creates "connected profiles", which incorporate database connections. Then the following occurs each time the application must access the database:
This section presents a side-by-side comparison of two versions of the same sample code--one version written in JDBC and the other in SQLJ. The objective of this section is to point out the differences in coding requirements between SQLJ and JDBC.
The particulars of SQLJ statements and features used here are described later in this manual, but this example is still useful here to give you a general idea in comparing and contrasting SQLJ and JDBC. You can look at it again when you are more familiar with SQLJ concepts and features.
In the sample, two methods are defined: getEmployeeAddress()
, which selects from a table and returns an employee's address based on the employee's number, and updateAddress()
, which takes the retrieved address, calls a stored procedure, and returns the updated address to the database.
In both versions of the sample code, the following assumptions are made:
UPDATE_ADDRESS()
exists, and updates a given address.Connection
object (for JDBC) and default connection context (for SQLJ) have been created previously by the caller.addr
) passed to the updateAddress()
method can be null.
Following is the JDBC version of the sample code, which defines methods to retrieve an employee's address from the database, update the address, and return it to the database. Note that the to-do items in the comment lines indicate where you might want to add additional code to increase the usefulness of the code sample.
import java.sql.*; import oracle.jdbc.*; /** This is what we have to do in JDBC **/ public class SimpleDemoJDBC // line 7 { //TO DO: make a main that calls this public Address getEmployeeAddress(int empno, Connection conn) throws SQLException // line 13 { Address addr; PreparedStatement pstmt = // line 16 conn.prepareStatement("SELECT office_addr FROM employees" + " WHERE empnumber = ?"); pstmt.setInt(1, empno); OracleResultSet rs = (OracleResultSet)pstmt.executeQuery(); rs.next(); // line 21 //TO DO: what if false (result set contains no data)? addr = (Address)rs.getORAData(1, Address.getORADataFactory()); //TO DO: what if additional rows? rs.close(); // line 25 pstmt.close(); return addr; // line 27 } public Address updateAddress(Address addr, Connection conn) throws SQLException // line 30 { OracleCallableStatement cstmt = (OracleCallableStatement) conn.prepareCall("{ ? = call UPDATE_ADDRESS(?) }"); //line 34 cstmt.registerOutParameter(1, Address._SQL_TYPECODE, Address._SQL_NAME); // line 36 if (addr == null) { cstmt.setNull(2, Address._SQL_TYPECODE, Address._SQL_NAME); } else { cstmt.setORAData(2, addr); } cstmt.executeUpdate(); // line 43 addr = (Address)cstmt.getORAData(1, Address.getORADataFactory()); cstmt.close(); // line 45 return addr; } }
In the getEmployeeAddress()
method definition, you must pass the connection object to the method definition explicitly.
Prepare a statement that selects an employee's address from the EMPLOYEES
table, based on the employee number. The employee number is represented by a marker variable, which is set with the setInt()
method. Note that because the prepared statement does not recognize "INTO
" syntax, you must provide your own code to populate the address (addr
) variable. Because the prepared statement is returning a custom object, cast the output to an Oracle result set.
Because the Oracle result set contains a custom object of type Address
, use the getORAData()
method to retrieve it. The Address
class can be created by JPublisher. The getORAData()
method requires a "factory" object that it can use to create additional custom objects (additional Address
objects in this case) as it retrieves the data to populate them. Use the static factory method Address.getORADataFactory()
to materialize an Address
factory object for the getORAData()
method to use.
Because getORAData()
returns a Datum
, cast the output to an Address
object.
Note that the routine assumes a one-row result set. The to-do items in the comment statements indicate that you must write additional code for the cases where the result set contains either no rows or more than one row.
Close the result set and prepared statement objects, then return the addr
variable.
In the updateAddress()
definition, you must pass the connection object and the Address
object explicitly.
The updateAddress()
method passes an address object (Address
) to the database for update, then fetches it back. The actual updating of the address is performed by the stored function UPDATE_ADDRESS()
. (The code for this function is not provided in this example.)
Prepare an Oracle callable statement that takes an address object (Address
) and passes it to the UPDATE_ADDRESS()
stored procedure. To register an object as an output parameter, you must know the SQL type code and SQL type name of the object.
Before passing the address object (addr
) as an input parameter, the program must determine whether addr
has a value or is null. Depending on the value of addr
, the program calls different setter methods. If addr
is null, the program calls setNull()
; if addr
has a value, the program calls setORAData()
.
Fetch the return result addr
. Because the Oracle callable statement returns a custom object of type Address
, use the getORAData()
method to retrieve it. The Address
class can be created by JPublisher. The getORAData()
method requires you to use the factory method Address.getORADataFactory
to materialize an instance of an Address
object. Because getORAData()
returns a Datum
object, cast the output to an Address
object.
Close the Oracle callable statement, then return the addr
variable.
Note the following coding requirements for the JDBC version of the sample code:
getEmployeeAddress()
and updateAddress()
definitions must explicitly include the connection object._SQL_TYPECODE
and _SQL_NAME
values of the factory object and any objects that you are registering as output parameters.getEmployeeAddress()
and updateAddress()
, then you must code this appropriately. Both Oracle SQLJ and Oracle JDBC support statement caching.JDBC programs are potentially expensive to maintain. For example, in the above code sample, if you add another WHERE
clause, then you must change the SELECT
string. If you append another host variable, then you must increment the index of the other host variables by one. A simple change to one line in a JDBC program might require changes in several other areas of the program.
Following is the SQLJ version of the sample code that defines methods to retrieve an employee's address from the database, update the address, and return it to the database.
import java.sql.*; /** This is what we have to do in SQLJ **/ public class SimpleDemoSQLJ // line 6 { //TO DO: make a main that calls this public Address getEmployeeAddress(int empno) // line 10 throws SQLException { Address addr; // line 13 #sql { SELECT office_addr INTO :addr FROM employees WHERE empnumber = :empno }; return addr; } // line 18 public Address updateAddress(Address addr) throws SQLException { #sql addr = { VALUES(UPDATE_ADDRESS(:addr)) }; // line 22 return addr; } }
The getEmployeeAddress()
method does not require an explicit connection object. SQLJ can use a default connection context instance, which would have been initialized previously somewhere in the application.
The getEmployeeAddress()
method retrieves an employee address according to employee number. Use standard SQLJ SELECT
INTO
syntax to select an employee's address from the employee table if the employee number matches the one (empno
) passed in to getEmployeeAddress()
. This requires a declaration of the Address object (addr
) that will receive the data. The empno
and addr
variables are used as input host variables.
The getEmployeeAddress()
method returns the addr
object.
The updateAddress()
method also uses the default connection context instance.
The address is passed to the updateAddress()
method, which passes it to the database. The database updates it and passes it back. The actual updating of the address is performed by the UPDATE_ADDRESS()
stored function. (The code for this function is not shown here.) Use standard SQLJ function-call syntax to receive the address object (addr
) output by UPDATE_ADDRESS()
.
The updateAddress()
method returns the addr
object.
Note the following coding requirements (and lack of requirements) for the SQLJ version of the sample code:
_SQL_TYPECODE
, _SQL_NAME
, or factories.SELECT INTO
statements are supported and OBDC-style escapes are not used.#sql
statements. This results in improved performance, for example, if you repeatedly call getEmployeeAddress()
and updateAddress()
.Although this manual mainly discusses writing for client-side SQLJ applications, you may find it useful to run SQLJ code in the following scenarios:
Because the SQLJ runtime is pure Java, you can use SQLJ source code in applets as well as applications. There are, however, a few considerations, as discussed below.
For applet issues that apply more generally to the Oracle JDBC drivers, see the Oracle9i JDBC Developer's Guide and Reference, which includes discussion of firewalls and security issues as well.
The following general considerations apply to the use of Oracle SQLJ applets.
sqlj.runtime sqlj.runtime.ref sqlj.runtime.profile sqlj.runtime.profile.ref sqlj.runtime.error
as well as the following if you used Oracle customization (for ISO code generation):
oracle.sqlj.runtime oracle.sqlj.runtime.error
These classes are included with your Oracle installation in one of several runtime libraries in the [Oracle_Home]/lib
directory. (See "Requirements for Using Oracle SQLJ".)
-codegen=oracle
generates Oracle-specific code. This will eliminate the use of Java reflection at runtime, thereby increasing portability across different browser environments. For information about the -codegen
option, see "Code Generation (-codegen)". For general information about Oracle-specific code generation, see "Oracle-Specific Code Generation (No Profiles)".When end users run your SQLJ applet, classes in their classpath may conflict with classes that are downloaded with the applet.
Oracle, therefore, recommends that end users clear their classpath before running the applet.
Here are some additional considerations regarding the Java environment and use of Oracle-specific features.
One option is to use a Java plug-in offered by Sun Microsystems. For information, refer to the following Web site:
http://www.javasoft.com/products/plugin
.ser
extension, which is the extension employed by the SQLJ serialized object files that are used for profiles (relevant for ISO standard code only). The Sun Microsystems Java plug-in, however, supports .ser
files.
Alternatively, if you do not want to use the plug-in, Oracle SQLJ offers the -ser2class
option to convert .ser
files to .class
files during translation. See "Conversion of .ser File to .class File (-ser2class)" for more information.
oracle.sqlj.*
. The Oracle SQLJ runtime
library requires the Java Reflection API (java.lang.reflect.*
); the runtime11
, runtime12
, and runtime12ee
runtime libraries must use the Reflection API only in the circumstances outlined below. Most browsers do not support the Reflection API or impose security restrictions, but the Sun Microsystems Java plug-in provides support for the Reflection API.
Note: The term "Oracle-specific features" refers to the use of Oracle type extensions (discussed in Chapter 5, "Type Support") and the use of SQLJ features that require Oracle-specific code generation or, for ISO code generation, require your application to be customized to work against an Oracle database. (For example, this is true of the |
With ISO standard SQLJ code generation, the following SQLJ language features always require the Java Reflection API (java.lang.reflect.*
), regardless of the version of the SQLJ runtime you are using:
CAST
statementjava.sql.Ref
, Struct
, Blob
, or Clob
objectsoracle.sql.ORAData
or java.sql.SQLData
interfaces
runtime11
library for your applets, or runtime12
/runtime12ee
if your browser supports JDK 1.2. Doing so permits you to use Oracle-specific features and Oracle-specific customization.runtime-nonoracle
. To support this, do not use Oracle-specific code generation and do not customize the applet during translation. Set -codegen=iso
and -profile=false
when you translate the code. If you neglect to set -profile=false
, then the default Oracle customizer will load Oracle-specific runtime classes. This will result in your applet requiring the Oracle runtime even though it does not use Oracle-specific features.The preceding issues can be summarized as follows, focusing on users with Internet Explorer and Netscape browsers:
runtime11
and classes111
libraries. In this case, the SQLJ and JDBC versions must match. For example, to use the SQLJ 9.0.0 runtime, you must have the Oracle 9.0.0 JDBC driver.CAST
statement in your SQLJ statements, then you must adhere to your choice of the following:
or:
or:
-codegen=iso
) without customization (-profile=false
) and distribute it with the generic SQLJ runtime, runtime-nonoracle
.In addition to its use in client applications, SQLJ code can run within a target Oracle9i database in stored procedures, stored functions, or triggers. Server-side access occurs through an Oracle JDBC driver that runs inside the server itself. Additionally, the Oracle9i database has an embedded SQLJ translator so that SQLJ source files for server-side use can optionally be translated directly in the server.
The two main areas to consider, which Chapter 11, "SQLJ in the Server", discusses in detail, are the following:
Coding a SQLJ application for use within the target Oracle9i database is similar to coding for client-side use. What issues do exist are due to general JDBC characteristics, as opposed to SQLJ-specific characteristics. The main differences involve connections:
Additionally, the JDBC server-side driver used for connections within the server does not support auto-commit mode.
Note: There is also a server-side Thin driver for connecting to one server from code that runs in another. This case is effectively the same as using a Thin driver from a client and is coded in the same way. See "Overview of the Oracle JDBC Drivers". |
You can translate and compile your code either on a client or in the server. If you do this on a client, you can then load the class and resource files into the server from your client machine, either pushing them from the client using the Oracle loadjava
utility, or pulling them in from the server using SQL commands. (It is convenient to have them all in a single .jar
file first.)
Alternatively, you can translate and load in one step, using the embedded server-side SQLJ translator. If you load a SQLJ source file instead of class or resource files, then translation and compilation are done automatically. In general, loadjava
or SQL commands can be used for class and resource files or for source files. From a user perspective .sqlj
files are treated the same as .java
files, with translation taking place implicitly.
See "Loading SQLJ Source and Translating in the Server" for information about using the embedded server-side translator.
Note: The server-side translator does not support the Oracle SQLJ |
You can use SQLJ on top of Oracle9i Lite. This section provides an overview of this functionality. For more information, refer to the Oracle9i Lite Java Developer's Guide.
Oracle9i Lite is a lightweight database that offers flexibility and versatility that larger databases cannot. It requires only 350K to 750K of memory for full functionality, natively synchronizes with the Palm Computing platform, and can run on Windows NT (3.51 or higher), Windows 95, and Windows 98. It offers an embedded environment that requires no background or server processes.
Oracle9i Lite is compatible with Oracle9i, Oracle8i, Oracle8, and Oracle7. It provides comprehensive support for Java, including JDBC, SQLJ, and Java stored procedures. There are two alternatives for access to Oracle9i Lite from Java programs, as follows:
This is intended for Java applications that use the relational data model, allowing them direct communication with the object-relational database engine.
Use the relational data model if your program has to access data that is already in SQL format, must run on top of other relational database systems, or uses very complex queries.
This is intended for Java applications that use either the Java object model or the Oracle9i Lite object model, allowing them to access persistent information stored in Oracle9i Lite, without having to map between the object model and the relational model. Use of JAC also requires a persistent Java proxy class to model the Oracle9i Lite schema. This can be generated by Oracle9i Lite tools.
Use the object model if you want your program to have a smaller footprint and run faster and you do not require the full capability of the SQL language.
There is interoperability between Oracle9i Lite JDBC and JAC, with JAC supporting all types that JDBC supports, and JDBC supporting JAC types that meet certain requirements.
Note the following requirements if you intend to run a Java program on top of Oracle9i Lite:
The JREs supplied with JDK 1.1.x and higher, Oracle JDeveloper, and Symantec Visual Cafe support JNI.
Oracle9i Lite 4.0.x and higher includes an Oracle-specific JDBC driver and Oracle-specific SQLJ runtime classes (including the Oracle semantics-checkers and customizer), allowing use of Oracle-specific features and type extensions.
The discussion in this book assumes that you are coding manually in a UNIX environment for English-language deployment. However, you can use SQLJ on other platforms and with IDEs. There is also globalization support for deployment to other languages. This section introduces these topics:
Oracle SQLJ support for native languages and character encodings is based on Java built-in globalization support capabilities.
The standard user.language
and file.encoding
properties of the JVM determine appropriate language and encoding for translator and runtime messages. The SQLJ -encoding
option determines encoding for interpreting and generating source files during translation.
For information, see "Globalization Support in the Translator and Runtime".
Oracle SQLJ includes a programmatic API so that it can be embedded in integrated development environments (IDEs) such as Oracle9i JDeveloper. The IDE takes on a role similar to that of the front-end sqlj
script, invoking the translator, semantics-checker, compiler, and customizer (as applicable).
JDeveloper is a Windows NT-based visual development environment for Java programming. The JDeveloper Suite enables developers to build multitier, scalable Internet applications using Java across the Oracle Internet Platform. The core product of the suite--the JDeveloper Integrated Development Environment--excels in creating, debugging, and deploying component-based applications.
The Oracle JDBC OCI and Thin drivers are included with JDeveloper, as well as drivers to access Oracle9i Lite.
JDeveloper's compilation functionality includes an integrated Oracle SQLJ translator so that your SQLJ application is translated automatically as it is compiled.
Information about JDeveloper is available at the following URL:
http://otn.oracle.com/products/jdev/content.html
Note the following if you are using a Windows platform instead of a UNIX environment:
ksh
on NT) that permits a different file name syntax.sqlj
, that you use to invoke the SQLJ translator. On Windows, Oracle SQLJ instead provides an executable file, sqlj.exe
. Using a script is not feasible on Windows platforms because .bat
files on these platforms do not support embedded equals signs (=) in arguments, string operations on arguments, or wildcard characters in file name arguments.Environment
tab in the System
control panel. Additionally, since Windows 95 does not support the "=" character in variable settings, SQLJ supports the use of "#" instead of "=" in setting SQLJ_OPTIONS
, an environment variable that SQLJ can use for option settings. Consult your operating system documentation regarding settings and syntax for environment variables, and be aware of any size limitations.Refer to the Windows platform README
file for additional information.
|
Copyright © 1999, 2002 Oracle Corporation. All Rights Reserved. |
|