ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

For Tomcat Developers, Aspire Comes in a JAR
Pages: 1, 2, 3, 4, 5

Performing Database Updates



So far so good. How do we work with updates? It is quite similar and just as easy.

import com.ai.application.interfaces.*;
import com.ai.application.utils.*;
import com.ai.data.*;
          
public void someUpdateFunction()
{
   try
   {
      Hashtable args = new Hashtable();
                
      string key1 = "col1-key";
      args.put(key1.toLowerCase(),"68");
                
      RequestExecutorResponse r = 
         (RequestExecutorResponse)AppObjects.getObject("MyUpdate",args);
          
      AppObjects.log("Info: Successfully executed");
   }
   catch(com.ai.application.interfaces.RequestExecutionException x)
   {
      AppObjects.log("Error: Could not get data collection. Factory error",x);
   }
   catch(com.ai.data.DataException x)
   {
      AppObjects.log("Error: Data related error",x);
   }
}

The similarities include coming up with a symbolic name, in this case MyUpdate, and passing in a hashtable of arguments. The AppObjects.getObject(...) in this case will return a RequestExecutorResponse instead of IDataCollection. Here is how you specify the properties file for the MyUpdate symbolic name.

Request.MyUpdate.classname=com.ai.db.DBRequestExecutor2
Request.MyUpdate.db=MyDataBaseAlias
Request.MyUpdate.query_type=update
Request.MyUpdate.stmt=\
   Insert into table1 values({col1-key.quote})

Notice the extra query_type. Both stored procedures and SQL statements can be used. If you use a stored procedure, you have to specify the StoredProcedureExecutor2. An example follows:

Request.MyUpdate.classname=com.ai.db.StoredProcedureExecutor2
Request.MyUpdate.db=MyDataBaseAlias
Request.MyUpdate.query_type=update
Request. MyUpdate.stmt=\
   Call oraclepkg.sp_insert({col1-key.quote})

Note that the stored procedure has lost the?, as this is an update. Also, for testing your hashtable of arguments, you can use a FileWriter part in place of the DBRequestExecutor2 or StoredProcedureExecutor2. Here is an example:

Request.MyUpdate.classname=com.ai.db.FileWriter
Request.MyUpdate.filename=aspire:\\dataout\\out.txt
Request.MyUpdate.openmode=append

The open-mode defaults to rewrite, where the file gets created every time.

Executing Multiple SQL Statements

So far, I have been pointing at and alluding to the "declarative" nature of data access and business logic. This declarative nature comes into its own once we start providing components the sole goal of which is composition or orchestration. Let us see this by examining a MultiExecutor, the only purpose of which is to execute a series of other functional executors such as FileReader, DBRequestExecutor, StoredProcedureExecutor, etc., including itself recursively.

For this, let's define two updates in the config file that we can call: MyUpdate1 and MyUpdate2.

Request.MyUpdate1.classname=com.ai.db.StoredProcedureExecutor2
Request.MyUpdate1.db=MyDataBaseAlias
Request.MyUpdate1.query_type=update
Request.MyUpdate1.stmt=\
   Call oraclepkg.sp_insert({col1-key.quote})

Request.MyUpdate2.classname=com.ai.db.StoredProcedureExecutor2
Request.MyUpdate2.db=MyDataBaseAlias
Request.MyUpdate2.query_type=update
Request.MyUpdate2.stmt=\
   Call oraclepkg.sp_insert2({col1-key.quote})

Now let's see how we can compose a third update by combining the two updates that we have defined earlier.

Request.MyUpdate.classname=com.ai.db.PreTranslateArgsMultiRequestExecutor
Request.MyUpdate1.db=MyDataBaseAlias
Request.MyUpdate1.request.1=MyUpdate1
Request.MyUpdate1.request.2=MyUpdate2

You have just made your MyUpdate call MyUpdate1 and MyUpdate2, without writing any Java code. Moreover, you have transactionally bound both updates as a single update. In essence, we now have access to three updates: MyUpdate1, MyUpdate2, and MyUpdate. Clients can call any of these in any order and still guarantee the transactional features. Which means MyUpdate1 will commit or roll back if it is called by itself, but will restrain from such activity when it is called as part of a composition.

Let us continue the magic a bit further by defining another select statement:

Request.MyUpdateQuery.classname=com.ai.db.DBRequestExecutor2
Request.MyUpdateQuery.db=MyDataBaseAlias
Request.MyUpdateQuery.stmt=\
   Select "3500" as key2 from dual

The above section is retrieving a row with a single column called key2 with a value of 3500. See how this value can be used in your update:

Request.MyUpdate.classname=com.ai.db.PreTranslateArgsMultiRequestExecutor
Request.MyUpdate1.db=MyDataBaseAlias
Request.MyUpdate1.request.1=MyUpdateQuery
Request.MyUpdate1.request.2=MyUpdate1
Request.MyUpdate1.request.3=MyUpdate2

Now you know why this MultiRequestExecutor part is called "pretranslate" -- because it has just introduced a new key called key2 into the hashtables that could be used by the downstream updates or selects. In a sense, we have translated key2 to its value. Here is how this key2 is used by MyUpdate3:

Request.MyUpdate3.classname=com.ai.db.StoredProcedureExecutor2
Request.MyUpdate3.db=MyDataBaseAlias
Request.MyUpdate3.query_type=update
Request.MyUpdate3.stmt=\
   Call oraclepkg.sp_insert3({col1-key.quote},{key2})

Tool for Testing Data Access

Another benefit of declaring these database access requirements in a config file is that we can write a test driver that can test these data access procedures. One such test driver is available in the .jar file itself. The following batch file demonstrates this utility driver:

set classpath=aspire_r2.0_b16.3_jsdk21.jar;q:\jars\classes12_817.zip;
p:\jdk13\bin\java com.ai.test.TestCollection %1

where classes12_817.jar is the 8.1.7 release of the Oracle's JDBC driver. Once you have the batch file ready, you can execute the command as follows:

RunTestCollection.cmd <your properties file>

When prompted, use the following syntax for executing the symbolic names (commands):

Command,arg1=value,arg2=value
Use "quit" command to exit

where command is same as your symbolic name. See how you are passing arguments. For any output or errors, check the log file. You can use both query commands and update commands. In case of an update command, the output is ignored.

Pages: 1, 2, 3, 4, 5

Next Pagearrow