|
Creating a Persistent Class
The Java code can save any object to the PSE OODB without modifying class contents. The exception is the Phonebook class, which provides the interface to the OODB. The PhoneRegion and PhoneEntry classes do not have to have any special code changes or additions before being stored in the OODB. They do, however, need to be post-processed by an ObjectStore tool in order to be prepared for storage in the database.
Code: Makefile Post-Processing of Stored Objects
osjcfp -dest ./pData -pc PhoneApp/Data/PhonebookEntry.class
In the above code, the command osjcfp (ObjectStore Java Class File Post-processor) takes Java class files and adds extra information about those classes to support the OODB. This command generates a number of files that must be stored in a separate directory (specified by -dest). The command must also know which class files to post-process. In this case we are post-processing the PhonebookEntry.class file.
Database Inserts
Database inserts imply that one or more objects are stored in the OODB. Insertion of objects must take place after a session and database connection has been established. When an object is inserted, all of its attributes (included contained objects) are stored with their proper type and value. This is demonstrated in the following piece of code:
Code: Phonebook Management of PhonebookEntry Inserts
public void addEntry(String firstName, String lastName, ...) {
PhonebookEntry entry = new PhonebookEntry( firstName, lastName, ... );
if ( entry.isValid() ) {
Transaction t = Transaction.begin(ObjectStore.UPDATE);
if (entries.get(phoneNumber) != null) {
t.abort(ObjectStore.RETAIN_READONLY);
System.out.println("Entry already exists.");
} else {
entries.put(phoneNumber, entry);
t.commit(ObjectStore.RETAIN_READONLY);
}
} else {
System.out.println("Invalid entry (" + entry.toString + ")");
}
}
A new PhonebookEntry object is created before being inserted. This object is then tested for validity (format, mandatory fields, etc). Before it is inserted, a transaction is started. If an object already exists in the database with the same "primary key" (phone number), then the insertion aborts. Otherwise, code puts the entry into the OSHashMap, "entries", named by its key, the phoneNumber for that entry. After a successful insertion, the transaction is committed and closed.
Performing Queries
In an OODB-enabled Java application, code queries a collection that corresponds to an entry point in the database. In the previous entry point discussion, I created an "entries" entry point with an OSHashMap. This collection resides within the OODB and stores our PhonebookEntry objects.
Java applications can perform two types of queries against OODB collections: constant and variable queries. In RDBMS terms, a variable query would refer to dynamic SQL. First, let's look at a constant query.
Code: Simple Queries in the Phonebook Class
Query query = new Query(
PhonebookEntry.class,
"firstName == \"John\""
);
Collection queryResults = query.select(entries.values());
String[] results = new String[queryResults.size()];
Iterator resultIterator = queryResults.iterator();
int count = 0;
while(resultIterator.hasNext()) {
PhonebookEntry tmpEntry = (PhonebookEntry)resultIterator.next();
results[count] = tmpEntry.toString();
count++;
}
In the above code (missing things like Transaction code to preserve space), a static query is coded into the application. It's looking for any PhonebookEntry objects with firstName equal to "John." The query runs against the values of the entries OSHashMap. Remember, the entries object actually refers to the "entries" entry point into the OODB. Also keep in mind that the query is running against the OODB, so objects are retrieved into the Java heap only when explicitly accessed.
Once the query is performed, the code then iterates through all results, retrieving the PhonebookEntry objects and calling their toString method to get a text summary of each entry.
Dynamic queries allow the code to specify fields and variables at runtime. The ObjectStore mechanism for this type of query uses FreeVariables and FreeVariableBindings. A FreeVariables object defines "place holders" in the query that will be assigned values at runtime. The FreeVariableBindings object assigns the values to the "place holders" at runtime. (This concept is described in much more detail in the ObjectStore PSE "Getting Started" tutorial included with the evaluation download.) The example below shows a sample query using variables:
Code: Dynamic Queries in the Phonebook Class
FreeVariables dynamicVariables = new FreeVariables();
dynamicVariables.put("firstNameValue", String.class);
Query query = new Query(
PhonebookEntry.class,
"firstName == firstNameValue",
dynamicVariables
);
FreeVariableBindings binding = new FreeVariableBindings();
binding.put("firstNameValue", newFirstName);
Collection queryResults = query.select( entries.values(), binding);
[Iteration through results same as in previous code snippet]
|