Extending PL/SQL with Java Libraries, concluded - Building Internal Server Java Objects (Page 2 of 5 )
The Java programming language is Object-Oriented (OO). In the previous examples, Java stored objects were used as static functions. The potential to use Java to accomplish significant OO computing models lies in the Oracle object features introduced in Oracle 9i Release 2. Beginning with that release, you can construct instances of object types and use them as objects. After you develop an understanding of implementing stored Java objects in this section, you can see how PL/SQL objects work in Chapter 6.
Why Would I Use This? We use internal server Java objects for the same reasons you use PL/SQL objects. Using Java as instantiable and threaded objects is where the value of using stored Java objects adds value once you understand how to use the SQLData interface. Java internal server objects have the ability to indirectly instantiate objects. The internal server Java objects are awkward to use for Java developers because they use external or indirect interfaces to effect communication. This section illustrates how the SQLData interface is used and explains the concepts supporting it. We believe Java developers will find this feature useful but tricky to use at first. This section should help you jump-start your use of the feature. |
Server-side stored Java programs support full runtime object behaviors starting with Oracle 9i, as noted earlier. This means you can now design, develop, and implement natural Java applications beneath PL/SQL object type wrappers. These Java classes can have instance methods, which mean nonstatic methods. You may also use static methods for libraries.
The balance of the differences covered earlier in the chapter still applies. You build Java object libraries by writing the Java class file and SQL object type definition. Object type bodies are not defined when the object type implementation is written in a stored Java object.
The substantial difference between external Java and server internal Java objects is the way you construct an instance of the class. You do not directly instantiate the class file and cannot use overriding constructors in the Java class file. The SQLData interface is the key to instantiating stored Java objects. It enables instantiating the Java class by passing back and forth the parameter values. This enables a class to return a reference to a copy or instance of the class.
TIP
There’s no way to instantiate directly a default constructor when using a stored Java object class. You also cannot use overriding constructors. The SQLData interface allows you to pass values to an instantiated class based on known class scope instance variables. Instance variables are not static variables. These limits are imposed by the implementation of the SQLData interface.
Implementing the SQLData interface is done by providing a variable definition and three concrete methods in your Java class file. The following are the components:
- A String data type named sql_type.
- A getSQLTypeName() method that returns a String data type.
- A readSQL() method that takes two formal parameters and returns a void. One formal parameter is a SQLInput that contains a stream. The other is a string that contains a data type name.
- A writeSQL() method that takes one formal parameter, which is a SQLOutput that contains a stream.
Details on implementing runtime Java classes will be illustrated in the following examples. The HelloWorld4 Java class file is designed to work as an instantiable Java stored object type body. The source code for the class is:
-- Available online as part of HelloWorld4.java file.
// Oracle class imports.
import java.sql.*;
import java.io.*;
import oracle.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.oracore.*;
// Class definition.
public class HelloWorld4 implements SQLData {
// Define and initialize a private class name variable.
private String className = new String("HelloWorld4.class");
// Define a formal parameter signature variable.
private String instanceName;
// Define a private schema qualified name value.
private String qualifiedName;
// Define a class instance variable to support SQLData Interface.
private String sql_type;
// --------------------------------------/
// Define default constructor.
public HelloWorld4()
{
// Define local String variables.
String user = new String();
// Use a try-catch block because of SQL statement.
try
{
// Call a method of the inner class.
user = getUserName();
}
catch (Exception e) {}
// Set the class instance variable.
qualifiedName = user + "." + className;
} // End of default constructor.
// --------------------------------------/
// Define a method to return a qualified name.
public String getQualifiedName() throws SQLException
{
// Define and initialize a return variable.
return this.qualifiedName + "." + instanceName;
} // End of getQualifiedName() method.
// --------------------------------------/
// Define a method to return the database object name.
public String getSQLTypeName() throws SQLException
{
// Returns the UDT map value or database object name.
return sql_type;
} // End of getSQLTypeName() method.
// --------------------------------------/
// Define getUserName() method to query the instance.
public String getUserName() throws SQLException
{
// Define and initialize a local return variable.
String userName = new String();
// Define and initialize a query statement.
String getDatabaseSQL = "SELECT user FROM dual";
// Define a connection for Oracle.
Connection conn = new OracleDriver().defaultConnection();
// Define and initialize a prepared statement.
PreparedStatement ps = conn.prepareStatement(getDatabaseSQL);
// Execute a query.
ResultSet rs = ps.executeQuery();
// Use a while-loop even though only one row is returned.
while (rs.next())
{
// Assign the cursor return.
userName = rs.getString(1);
}
// Return the user name.
return userName;
} // End of getUserName() method.
// --------------------------------------/
// Implements readSQL() method from the SQLData interface.
public void readSQL(SQLInput stream, String typeName) throws SQLException
{
// Define sql_type to read input and signal overloading signatures.
sql_type = typeName;
// Pass values into the class.
instanceName = stream.readString();
} // End of readSQL() method.
// -------------------------------------/ // Implements readSQL() method from the SQLData interface.
public void writeSQL(SQLOutput stream) throws SQLException
{
// You pass a value back by using a stream function.
// stream.writeString('variable_name');
} // End of readSQL() method.
} // End of HelloWorld4 class.
The Java class file does the following:
Next: More on Building Internal Server Java Objects >>
More Oracle Articles
More By McGraw-Hill/Osborne
|
This article is excerpted from chapter five of Expert Oracle PL/SQL, written by Ron Hardman and Michael McLaughlin (McGraw-Hill/Osborne, 2005; ISBN: 0072261943). Check it out today at your favorite bookstore. Buy this book now.
|
|