Oracle8i JPublisher User's Guide
Release 2 (8.1.6)

Part Number A81357-01

Library

Solution Area

Contents

Index

Go to previous page Go to beginning of chapter Go to next page

Understanding JPublisher

This section contains these subsections:

Introduction

JPublisher is a utility, written entirely in Java, that generates Java classes to represent the following user-defined database entities in your Java program:

JPublisher enables you to specify and customize the mapping of database object types, reference types, and collection types (varrays or nested tables) to Java classes, in a strongly typed paradigm.

JPublisher generates get and set accessor methods for each attribute of an object type. If your object types have stored procedures, JPublisher can generate wrapper methods to invoke the stored procedures. A wrapper method is a method that invokes a stored procedure that executes in the database.

JPublisher can also generate classes for PL/SQL packages. These classes have wrapper methods to invoke the stored procedures in the PL/SQL packages.

The wrapper methods JPublisher generates contain SQLJ code. Therefore, JPublisher generates .sqlj source files for classes with wrapper methods, that is, classes representing object types or PL/SQL packages. JPublisher generates .java source files for classes representing REF or collection types. If you ask JPublisher to translate object types without generating wrapper methods, JPublisher will generate .java source files to represent the object types. You use SQLJ to compile the .sqlj files; you can use SQLJ or your Java compiler to compile the .java files.

Instead of using JPublisher-generated classes directly, you can:

Object Types and JPublisher

JPublisher allows your Java language applications to employ user-defined object types in an Oracle8 server. If you intend to have your Java-language application access object data, then it must represent the data in a Java format. JPublisher helps you do this by creating the mapping between object types and Java classes, and between object attribute types and their corresponding Java types.

Classes generated by JPublisher implement either the oracle.sql.CustomDatum interface or the java.sql.SQLData interface. Either interface makes it possible to transfer object type instances between the database and your Java program. For more information on the CustomDatum interface, see the Oracle8i JDBC Developer's Guide and Reference . See The JDBC 2.0 API, by Sun Microsystems, for more information on the SQLData interface.

PL/SQL Packages and JPublisher

You might want to call stored procedures in a PL/SQL package from your Java application. The stored procedure can be a PL/SQL subprogram or a Java method that has been published to SQL. Java arguments and functions are passed to and returned from the stored procedure.

To help you do this, you can direct JPublisher to create a class containing a wrapper method for each subprogram in the package. The wrapper methods generated by JPublisher provide a convenient way to invoke PL/SQL stored procedures from Java code or to invoke a Java stored procedure from a client Java program.

If you call PL/SQL code that includes top-level subprograms (subprograms not in any PL/SQL package), JPublisher generates a single class containing wrapper methods for the top-level subprograms you request.

JPublisher Requirements

When you use version 8.1.6 of JPublisher, you should also use version 8.1.6 of SQLJ, because these two products are always installed together. To use all features of JPublisher, you also need:

If you are using only some features of JPublisher, your requirements might be less stringent:

What JPublisher Does

JPublisher connects to a database and retrieves descriptions of the SQL object types or PL/SQL packages that you specify on the command line or from an input file. By default, JPublisher connects to the database by using the JDBC OCI driver, which requires an Oracle client installation, including Net8 and required support files. If you do not have an Oracle client installation, JPublisher can use the Oracle Thin JDBC driver.

JPublisher generates a Java class for each database object type it translates. The Java class includes code required to read objects from and write objects to the database. When you deploy the generated JPublisher classes, your JDBC driver installation includes all the necessary runtime files. If you create wrapper methods, you additionally must have the SQLJ runtime libraries.

JPublisher also generates a class for each PL/SQL package it translates. The class includes code to invoke the package methods on the server. IN arguments for the methods are transmitted from the client to the server, and OUT arguments and results are returned from the server to the client.

The next section furnishes a general description of the source files that JPublisher creates for object types and PL/SQL packages.

What JPublisher Produces

The number of files JPublisher produces depends on whether you request CustomDatum classes (classes that implement the oracle.sql.CustomDatum interface) or SQLData classes (classes that implement the java.sql.SQLData interface).

The CustomDatum interface supports database object, REF, and collection types in a strongly typed way. That is, for each specific object, REF, or collection type in the database, there is a corresponding Java type. The SQLData interface, on the other hand, supports only database object types in a strongly-typed way. All REF types are represented generically as instances of java.sql.Ref, and all collection types are represented generically as instances of java.sql.Array. Therefore, JPublisher generates classes for REF and collection types only if it is generating CustomDatum classes.

When you run JPublisher for a user-defined object type and you request CustomDatum classes, JPublisher automatically creates the following:

If, instead, you request SQLData classes, JPublisher does not generate the reference class and does not generate classes for nested collection attributes.

When you run JPublisher for a user-defined collection type, you must request CustomDatum classes. JPublisher automatically creates the following:

When you run JPublisher for a PL/SQL package, it automatically creates the following:

Type Mappings

JPublisher maps the Oracle datatypes of the object's attributes and the PL/SQL package's arguments and function results to Java, according to mappings you specify globally. You can request Oracle-style or JDBC-style mappings. For numeric types, two other mapping styles are available: Object JDBC style and BigDecimal style.

You can find a more detailed description of the Oracle, JDBC, and Object JDBC mappings in "Type Mappings for All Types (-mapping)" and "Understanding Datatype Mappings".

Translating and Using PL/SQL Packages and Oracle Objects

Here are the basic steps for translating and using code for objects (including nested tables and varrays) and PL/SQL packages:

  1. Create the desired object datatypes (Oracle objects) and PL/SQL packages in the database.

  2. JPublisher generates source code for Java classes that represent PL/SQL packages, user-defined types, and REF types and places them in specified Java packages. JPublisher generates .java files for REF, varray, and nested table classes. If you ask JPublisher to generate wrapper methods, it will generate .sqlj files for object types and packages. If not, JPublisher will generate .java files without wrapper methods for object types and will not generate classes for packages (because they contain only wrapper methods).

  3. Import these classes into your application code.

  4. Use the methods in the generated classes to access and manipulate the Oracle objects and their attributes.

  5. Compile all classes (the JPublisher-generated code and your code). The SQLJ compiler compiles the .sqlj files, and the Java or SQLJ compiler compiles the .java files.

  6. Run your compiled application.

Figure 1-1 illustrates the preceding steps.

Figure 1-1 Translating and Using Object Code

Representing User-defined Object, Collection, and REF Types in Your Program

Here are the three ways in which you can represent user-defined object, collection, and REF types in your Java program:

Compared to classes that implement SQLData, classes that implement CustomDatum are fundamentally more efficient, because CustomDatum classes avoid unnecessary conversions to native Java types. For a comparison of the SQLData and CustomDatum interfaces, see the Oracle8i JDBC Developer's Guide and Reference.

Compared to oracle.sql.* classes, classes that implement CustomDatum or SQLData are strongly typed. Your connected SQLJ translator will detect an error at translation time if, for example, you mistakenly select a Person object into a CustomDatum that represents an Address.

JPublisher generated classes that implement CustomDatum or SQLData have additional advantages.

Sample JPublisher Command Line

On most operating systems, you invoke JPublisher on the command line. JPublisher responds by connecting to the database and obtaining the declarations of the types or packages you specify, then generating one or more custom Java files, and writing the names of the translated object types or PL/SQL packages to standard output.

Here is an example of a command that invokes JPublisher:

jpub -user=scott/tiger -input=demoin -numbertypes=oracle -usertypes=oracle 
-dir=demo -package=corp

You enter the command on one line, allowing it to wrap as necessary. For convenience, this chapter refers to the input file (the file specified by the -input option) as the INPUT file.

This command causes JPublisher to connect to the database with username scott and password tiger and translate database types to Java classes, based on instructions in the INPUT file demoin. The -numbertypes=oracle option directs JPublisher to map object attribute types to Java classes supplied by Oracle, and the -usertypes=oracle directs JPublisher to generate Oracle-specific CustomDatum classes. JPublisher places the classes that it generates in the package corp in the directory demo.

"JPublisher Options" describes each of these options in more detail.

Sample JPublisher Translation

This section illustrates a sample JPublisher translation of a simple object type. At this point, do not worry about the details of the code JPublisher generates. You can find more information about JPublisher input and output files, options, datatype mappings, and translation later in this chapter.

Create the object type employee:

CREATE TYPE employee AS OBJECT
(
    name       VARCHAR2(30),
    empno      INTEGER,
    deptno     NUMBER,
    hiredate   DATE,
    salary     REAL
);

The integer, number, and real types are all stored in the database as NUMBER types, but after translation, they have different representations in the Java program, based on your choice for the value of the -numbertypes option.

JPublisher translates the types according to the command line:

jpub -user=scott/tiger -dir=demo -numbertypes=objectjdbc -builtintypes=jdbc 
-package=corp -case=mixed -sql=Employee

Because -dir=demo was specified on the JPublisher command line, the package corp with the translated class employee is written to the file:

./demo/corp/Employee.sqlj           (UNIX)
.\demo\corp\Employee.sqlj           (Windows NT)

The Employee.sqlj class file would contain this code:


Note:
The details of the code JPublisher generates are subject to change in future releases. In particular, non-public methods, non-public fields, and all method bodies are subject to change.  

package corp;

import java.sql.SQLException;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleTypes;
import oracle.sql.CustomDatum;
import oracle.sql.CustomDatumFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;
import sqlj.runtime.ref.DefaultContext;
import sqlj.runtime.ConnectionContext;
import java.sql.Connection;

public class Employee implements CustomDatum, CustomDatumFactory
{
  public static final String _SQL_NAME = "SCOTT.EMPLOYEE";
  public static final int _SQL_TYPECODE = OracleTypes.STRUCT;

  #sql static context _Ctx;
  _Ctx _ctx;

  MutableStruct _struct;

  static int[] _sqlType =
  {
    12, 4, 2, 91, 7
  };

  static CustomDatumFactory[] _factory = new CustomDatumFactory[5];

  static final Employee _EmployeeFactory = new Employee();
  public static CustomDatumFactory getFactory()
  {
    return _EmployeeFactory;
  }

  /* constructors */
  public Employee()
  {
    _struct = new MutableStruct(new Object[5], _sqlType, _factory);
    try
    {
      _ctx = new _Ctx(DefaultContext.getDefaultContext());
    }
    catch (Exception e)
    {
      _ctx = null;
    }
  }

  public Employee(ConnectionContext c) throws SQLException
  {
    _struct = new MutableStruct(new Object[5], _sqlType, _factory);
    _ctx = new _Ctx(c == null ? DefaultContext.getDefaultContext()
                              : c);
  }
  public Employee(Connection c) throws SQLException
  {
    _struct = new MutableStruct(new Object[5], _sqlType, _factory);
    _ctx = new _Ctx(c);
  }

  /* CustomDatum interface */
  public Datum toDatum(OracleConnection c) throws SQLException
  {
    _ctx = new _Ctx(c);
    return _struct.toDatum(c, _SQL_NAME);
  }

  /* CustomDatumFactory interface */
  public CustomDatum create(Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null;
    Employee o = new Employee();
    o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
    o._ctx = new _Ctx(((STRUCT) d).getConnection());
    return o;
  }

  /* accessor methods */
  public String getName() throws SQLException
  { return (String) _struct.getAttribute(0); }

  public void setName(String name) throws SQLException
  { _struct.setAttribute(0, name); }

  public int getEmpno() throws SQLException
  { return ((Integer) _struct.getAttribute(1)).intValue(); }

  public void setEmpno(int empno) throws SQLException
  { _struct.setAttribute(1, new Integer(empno)); }

  public java.math.BigDecimal getDeptno() throws SQLException
  { return (java.math.BigDecimal) _struct.getAttribute(2); }

  public void setDeptno(java.math.BigDecimal deptno) throws SQLException
  { _struct.setAttribute(2, deptno); }

  public java.sql.Timestamp getHiredate() throws SQLException
  { return (java.sql.Timestamp) _struct.getAttribute(3); }

  public void setHiredate(java.sql.Timestamp hiredate) throws SQLException
  { _struct.setAttribute(3, hiredate); }

  public float getSalary() throws SQLException
  { return ((Float) _struct.getAttribute(4)).floatValue(); }

  public void setSalary(float salary) throws SQLException
  { _struct.setAttribute(4, new Float(salary)); }

}

JPublisher also generates an EmployeeRef.java class. The contents of this file are displayed below.

package corp;

import java.sql.SQLException;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleTypes;
import oracle.sql.CustomDatum;
import oracle.sql.CustomDatumFactory;
import oracle.sql.Datum;
import oracle.sql.REF;
import oracle.sql.STRUCT;

public class EmployeeRef implements CustomDatum, CustomDatumFactory
{
  public static final String _SQL_BASETYPE = "SCOTT.EMPLOYEE";
  public static final int _SQL_TYPECODE = OracleTypes.REF;

  REF _ref;

  static final EmployeeRef _EmployeeRefFactory = new EmployeeRef();
  public static CustomDatumFactory getFactory()
  {
    return _EmployeeRefFactory;
  }

  /* constructor */
  public EmployeeRef()
  {
  }

  /* CustomDatum interface */
  public Datum toDatum(OracleConnection c) throws SQLException
  {
    return _ref;
  }

  /* CustomDatumFactory interface */
  public CustomDatum create(Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null;
    EmployeeRef r = new EmployeeRef();
    r._ref = (REF) d;
    return r;
  }
  public Employee getValue() throws SQLException
  {
     return (Employee) Employee.getFactory().create(
       _ref.getSTRUCT(), OracleTypes.REF);
  }

  public void setValue(Employee c) throws SQLException
  {
    _ref.setValue((STRUCT) c.toDatum(_ref.getConnection()));
  }
}

You can find more examples of object mappings in "Example: JPublisher Type Mapping".



Go to previous page
Go to beginning of chapter
Go to next page
Oracle
Copyright © 1996-2000, Oracle Corporation.

All Rights Reserved.

Library

Solution Area

Contents

Index