Skip to main content

skip to main content

developerWorks  >  Information Management | Java technology  >

Write high performance, Java data access applications, Part 2: Introducing pureQuery inline method style

Streamline common tasks for simplicity and usability

developerWorks
Document options
PDF format - Fits A4 and Letter

PDF - Fits A4 and Letter
67KB (14 pages)

Get Adobe® Reader®

Document options requiring JavaScript are not displayed


My developerWorks needs you!

Connect to your technical community


Rate this page

Help us improve this content


Level: Introductory

Daya Vivek (vivekd@us.ibm.com), developer, pureQuery runtime team, IBM

01 May 2008

IBM® pureQuery is a high-performance Java™ data access platform focused on simplifying the tasks of developing and managing applications that access data. It consists of tools, APIs and a runtime engine. pureQuery introduces two programming styles to help users access the database through simple but powerful APIs. This article introduces one such style, the inline method programming style, and discusses how users can use it to efficiently query and update databases. This article also explores the benefits as well as some of the key features of using the inline method programming style.

Introduction

pureQuery

pureQuery is a feature available for IBM Data Studio and can be obtained with IBM Data Studio pureQuery Runtime or with IBM Data Studio Developer.

pureQuery introduces two new programming styles for SQL execution: the inline method programming style and the annotated method programming style. These styles simplify Java data access development by providing out-of-the-box support for storing and retrieving objects, such as Java beans and maps, to and from the database. The inline programming style also supports the use of customized user-defined result processing.

The annotated method style provides an annotation-based approach for data access. In the annotated method style, the SQL/XQUERY string is defined within a pureQuery Annotation. These annotations are placed on method declarations within a user-defined interface. A code generator pre-processes the interface to generate implementation code for each annotated method. The generated implementation code executes the SQL statements defined in the annotation using the pureQuery runtime. For more information on the annotated method style, refer to Part 1 of this series or the pureQuery documentation.

The pureQuery inline programming style was introduced to reduce the repeated tasks that are common to querying or updating a database using JDBC. The inline method style introduces a set of well-defined and efficient APIs that are simpler and easier to use than JDBC. In the inline style, SQL/XQUERY statements can be created “inline” within the code as a java String object. This dynamically generated statement is passed as a String parameter to the pureQuery Data interface method. The inline style uses JDBC best practices and leverages database-specific APIs to improve performance. An example of the inline method style is the use of batch updates and optimized result-set processing. In contrast to the annotated style, where the SQL has to be defined at compile time, the inline style supports dynamic creation and execution of SQL statements at runtime. The SQL is “inline” and visible within the application, and this makes it is easier to spot errors and make corrections. The inline style also has a pluggable custom result processing for mapping database columns easily.

Table 1 provides a snippet of code to demonstrate the simplicity and usability of the inline method style.


Table 1. A code comparison between JDBC and the pureQuery inline style
JDBC pureQuery inline style
try  {



  //SQL for insert
  String sqlins="'insert into CUSTOMER ("
  +    "NAME, COUNTRY, STREET, CITY, PROVINCE, ZIP,"
  +    "PHONE,INFO)"
  +    "values( ?, ?, ?, ?, ?, ?, ?, ?)";



  //prepare the INSERT statement
  PreparedStatement pstmt = 
       con.prepareStatement(sqlins );

  // setup parameters
  pstmt.setString (1, "custName");
  pstmt.setString (2, "custCountry");
  pstmt.setString (3, "custStreet");
  pstmt.setString (4, "custCity");
  pstmt.setString (5, "custProvince");
  pstmt.setString (6, "custZip");
  pstmt.setString (7, "custPhone");
  pstmt.setString (8, "custInfo");

  
  //execute the INSERT statement
  pstmt.execute();



  //close the prepared statement
  pstmt.close();

  // SQL for SELECT
  String sqlSel = "select Name, Country, Street, "
  + "Province,Zip from CUSTOMER where Customer = ?"; 

  //prepare the SELECT statement 
  pstmt =  con.prepareStatement(sqlSel);
  
  //set the Input parameter
  pstmt.setString (1, "custCountry");

  //execute SELECT statement
  pstmt.execute();



  //get the results and set values in Customer Bean
  ResultSet result = pstmt.getResultSet ();
  List<Customer> custList = 
  new ArrayList<Customer>();
  while (result.next ()) {
  Customer cust = new Customer();
  cust.name = result.getString (1);
  cust.country = result.getString (2);
  cust.street = result.getString (3);
  cust.province = result.getString (4);
  cust.zip = result.getString (5);
  custList.add (cust);
   }
}
catch (SQLException e) {
  e.pringStackTrace ();
}


  


//Get Instance of Data  
Data data = DataFactory.getData(con);

// SQL for insert  
String sqlins = "insert into CUSTOMER (" 
+     "NAME,COUNTRY,STREET,CITY,PROVINCE,ZIP, "
+     "PHONE, INFO)" 
+    "values( ?, ?, ?, ?, ?, ?, ?, ?)";


















//execute the INSERT statement
data.update (sqlins, "custName", 
"custCountry", "custStreet", "custCity", 
"custProvince", "custZip", "custPhone", "custInfo");




// SQL for SELECT
String sqlSel = "select Name, Country, Street, " 
+ "Province,Zip from CUSTOMER where Customer = ?"; 







//execute the Select and get the list of customer
List<Customer> customerList = data.queryList (sqlSel, Customer.
class , "custCountry");













This article includes:

  • A description of the various aspects of code required for the inline coding style
  • An introductory case study to highlight the features of the inline style
  • A description of the querying capabilities provided by the inline style, which includes pureQuery’s default mapping support and the customized query mapping support
  • A description of the single update and batch update support, and APIs to retrieve the auto-generated values
  • An introduction to pureQuery’s pluggable callback mechanism.


Back to top


Developing inline methods

Described below are some of the different objects and APIs that a user may need to program an inline method style application:

  1. The Data interface

    The com.ibm.pdq.runtime.Data interface defines convenience APIs for a user to perform operations on a Database. When using the inline method programming style, a user can invoke methods defined in the Data interface and pass the SQL statement as a parameter in the invocation of a method. The Data interface provides methods to execute queries, execute SQL CALL statements and to return their output parameters. It also provides a means to access the dynamic result sets created by a stored procedure and to execute SQL data manipulation language (DML) statements such as update, insert or delete as single operations or in homogeneous batches. Many of the Data interface’s query methods are generic, so they can return instances of different types including collections.

  2. The DataFactory Class

    The com.ibm.pdq.runtime.factory.DataFactory class provides a means for constructing implementations of the Data interface. One way to create an implementation of the Data interface is to pass a Connection object to the DataFactory.getData() method.

  3. pureQuery bean

    A pureQuery bean can be used to represent relational data such as database tables, views, result sets, and the like. Although pureQuery API methods can deal with input parameters and return values defined as unstructured types, the use of the pureQuery bean provides the user better mapping capabilities of relational data to Java objects. pureQuery analyzes the declared properties, methods, and annotations of a bean to determine how to map between the bean’s properties and the input/output properties of an SQL statement. More information on the conventions and requirements of pureQuery beans can be found in the pureQuery documentation.

  4. Java application with inline methods

    This is the Java file where the user can create an instance of the Data interface and call different query, update or call methods.



Back to top


The Silver Castle example

This section introduces an example of how the data access development team in a fictional company called Silver Castles uses pureQuery. This article uses the background information described here to provide compelling examples and use-cases for each pureQuery inline feature.



Back to top


Background information for the Silver Castle example

Silver Castles is a growing company which sells a variety of silver products. The company is developing a new web-based storefront and has decided to use the pureQuery environment as a tool to develop the persistence layer of their application. Once the development team has obtained a solid understanding of the pureQuery tools environment, they begin to delve deeper into the technical aspects of the pureQuery inline coding style.



Back to top


Sample inline method style program

The Silver Castle development team defined the Customer Table as below:


Listing 1. The Customer table as defined in the database
                
CREATE TABLE PDQ_SC.customer(
  Cid     INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (STARRT WITH 100, INCREMENT BY 1),
  Name       VARCHAR(128),
  Country    VARCHAR(128),
  Street     VARCHAR(128),
  City       VARCHAR(128),
  Province   VARCHAR(128),
  Zip        VARCHAR(128),
  Phone      VARCHAR(128),
  Info       VARCHAR(128),
  CONSTRAINT CID_PK primary key(Cid));

The pureQuery bean for this Customer table can be generated using the Data Studio tool. That Customer bean is defined below:


Listing 2. The Customer class
                
public class Customer {
// Class variables  
 @Id
 @GeneratedKey 
 public int cid;
 public String name;
 public String country;
 public String street;
 public String city;
 public String province;
 public String zip;
 public String phone;
 public String info;

 public Customer(){}

 public Customer(String name, String country, String street, String city, String province,
                 String zip, String phone, String info){
   this.name = name;
   this.country = country;
   this.street = street;
   this.city = city;
   this.province = province;
   this.zip = zip;
   this.phone = phone;
   this.info = info;
 }
}

Now, the Silver Castles development team tries to create a test program (Listing 3) to do the following:

  1. Get a connection to the database
  2. Get an instance to the implementation of a Data interface
  3. Delete all the rows in the data base
  4. Insert a row using a pureQuery bean as in input parameter
  5. Query the database and retrieve rows in an iterator of pureQuery beans

Listing 3. Manipulating the data objects using the inline Method style
                
                
package com.ibm.db2.demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Iterator;
import java.util.List;
import com.ibm.db2.pureQuery.Customer;
import com.ibm.pdq.runtime.Data;
import com.ibm.pdq.runtime.factory.DataFactory;

public class InlineTest
{
  
  public static void main(String args[]) {
    Connection con = null;
    String sql = null;
    String insertSql = null;
    try {
      // connection to the database
      con = DriverManager.getConnection ();

  // Get an instance to the implementation of a Data interface
      Data data = DataFactory.getData (con);
      
      //delete all rows from the table
      data.update ("delete from PDQ_SC.customer");

      //Insert using a pureQuery Bean 
      insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
		   "Province, Zip, Phone)" +
                  "VALUES(:name,:country,:street,:city,:province,:zip,:phone)";
      Customer addCustomer = new Customer("Customer2","US","BlackBerry Street",
                     "San Jose","Santa Clara","82652","408-273-4856",null); 
      int insertCount = data.update (insertSql,addCustomer );
      System.out.println ("Rows Inserted " + insertCount );
      
    
      sql = "select * from  PDQ_SC.Customer where Country = ?";

      //Query with Iterator using default handler 
      Iterator<Customer> iterator = data.queryIterator (sql, Customer.class, "US");
         
      con.close ();
    }
    catch (Exception e) {
      System.out.println ("Error encountered");
      e.printStackTrace ();
    }
  }
  
  
 public static Connection getConnection ()
  {
    Connection connection = null;

    try {
      Class.forName ("com.ibm.db2.jcc.DB2Driver").newInstance ();
      java.util.Properties info = new java.util.Properties ();      
      info.put ("retrieveMessagesFromServerOnGetMessage", "true");
      info.put ("user", "USER");
      info.put ("password", "PASSWORD");
      String url = "jdbc:db2://atom.blue.test.com:298/SAMPLE:deferPrepares=false;";
      connection = DriverManager.getConnection (url, info);
    }
    catch (Exception e) {
      e.printStackTrace ();
    }

    return connection;
  }
}



Back to top


Creating an instance of the Data object

To create an instance of com.ibm.pdq.runtime. Data, a connection to a database is required in the form of either a java.sql.Connection object or a javax.sql.DataSource object. Once a connection has been established, a user can call a getData() method in com.ibm.pdq.runtime.factory.DataFactory to create an instance of the Data interface. In addition to the methods for executing an SQL statement, the Data interface supports the close(), commit(), rollback() and setAutoCommit() JDBC methods.

In Listing 3, the Silver Castle team uses the getConnection() method to create a database connection. This method uses the Driver Manager API to create this connection by passing a database connection URL String. The connection is then passed to the DataFactory.getData() method to get an instance of the Data interface.



Back to top


Input parameter options

The Silver Castle developers may want to use any of the parameter markers or host variable styles provided by pureQuery. Their preference could be based on the number of input parameters or the types of input parameters to the inline method. The parameters that are passed into the method invocation are matched to the parameters in the SQL. pureQuery follows parameter marker rules to determine the mapping between the parameters declared in the SQL/XQUERY and the parameters that are passed to the inline method. In the simplest form, there is a one to one correspondence between the two sets of parameters. pureQuery can also take a variety of parameter types like pureQuery Beans or a java.util.Map.



Back to top


Querying objects in a database

The inline method style provides convenience methods and provides out-of-the-box support for mapping database results to maps and pureQuery beans. The Data interface’s overloaded queryArray(), queryIterator(), and queryList() methods can be used to return the entire result set of a query as an Array, Iterator, or List object.

The query methods can return results as primitive types, beans, collections, and the like, including:

  • java.sql.ResultSet,
  • Primitive wrapper types or simple Object types that are supported directly by JDBC (does not include user-defined types)
  • java.util.Map object, where column names become String keys, and column values become Object values
  • java.util.Map objects grouped together into Arrays, Collections, or Iterators
  • Individual pureQuery beans, where a user can store the results of a query in a pureQuery Bean (the @Column annotations provide information needed to associate columns of the select-list with their respective properties; more details of pureQuery annotation can be found in the pureQuery documentation)
  • pureQuery beans grouped together into Arrays, Collections, or Iterators where the class of the return bean is passed in as a parameter

Once the target data type has been decided, the user needs to consider whether or not to use a custom handler to transform information selected from the data source into the target. Instances of pureQuery beans can be created either with pureQuery’s default mapping from a SELECT statement’s select-list to the target Bean class, or by using a user defined handler.



Back to top


Querying the Silver Castle Customer table

The Silver Castle developers want to inform all the customers in Australia about an upcoming special on the salt and pepper shaker sets. The common print utility methods that print all the pamphlets take a java.util.List as input. The developer queries the Customer table for all customers who reside in Australia and get the rows returned as a List. They can use the queryList() API, and pass in the country as an input parameter. The returned list (customerList in the example below) is then passed to the print utility, so that the pamphlets get addressed to the correct set of customers on the list.


Listing 4. Querying the Customer table
                
      sql = "select * from  PDQ_SC.Customer where Country = ?";
      //Query with List using default handler
      List<Customer> customerList = data.queryList (sql, Customer.class, "Australia");



Back to top


User-defined custom mapping of result sets

The RowHandler and ResultHandler interfaces gives users the ability to provide a customized user-defined mapping. pureQuery is told how to map the columns in a result set to a different Java object using the handle() method in either the RowHandler or ResultHandler interface. Row Handlers and Result Handlers allow the developer a great degree of flexibility, and the potential for code reuse because they are able to make use of a ResultSet’s ResultSetMetaData to handle variations in the select list. This can be used to include the omission of some properties or to specify properties that are not needed.

In some cases, an application developer might want some form of serialization to occur to the query’s result as a whole. For example, the only processing done against the query’s result could be serialization in JSON, or XML, or simply to send the data to another (or the same) data source. The user can use the ResultHandler to perform such custom operations.

Mapping one row of a result set

The RowHandler interface is used to map one row of a result set to an object. The only method in the RowHandler interface is handle(). This is a generic method that, given a ResultSet object and optionally an instance of the class <T>, either produces a new Java object of class <T>, or updates the given instance of <T>. If the ResultSet object is empty, or the last row of the ResultSet object has been read, the handle() method is not called. When the handle() method is called, the ResultSet object that is passed to the method is positioned on the row to be processed. The handle() method must not invoke the next() method on the input ResultSet object as pureQuery performs that action automatically.

Mapping a result set to an object

The ResultHandler interface is used to map an entire result set to an object. The user can use the handle() method in the ResultHandler interface to convert the query results to another object, say XML, that can be passed along to another application that takes XML as an input.



Back to top


Updating objects in a database

The Data interface’s update() method can be used to perform a single update to a database object and the updateMany() method to perform a batch of updates that are based on a single SQL statement. The methods supported are INSERT, DELETE, and UPDATE operations.

Single updates

The update() method in the Data interface can be used for a single operation, which returns an update count. Listing 5 is an example to a call to the overloaded method update() from the application


Listing 5.Application calling the overloaded method update()
                
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
            "Province, Zip, Phone) VALUES (:name, :country, :street, " +
        ":city, :province,:zip,:phone)";

//Create an instance of Customer Bean with the values to be inserted
Customer addCustomer = 
new Customer("Customer2","US","BlackBerry Street","San Jose",
                     "Santa Clara","82652","408-273-4856", null); 
//Insert using a Bean
int updateCount = data.update (insertSql, addCustomer);
  

Batch updates

In the Data interface, the updateMany() method indicates that a statement is to be run multiple times. The updateMany() method allows passing a collection, or batch, of data to iterate through.

The returned int array indicates, as in JDBC, the success (and associated update count) or failure of each run of the SQL statement. This includes use of JDBC’s update counts, Statement.EXECUTE_FAILED and SUCCESS_NO_INFO. to indicate if failures occur -- a com.ibm.pdq.runtime.exception.UpdateManyException exception is thrown. This runtime exception contains information that JDBC reports in java.sql.BatchUpdateException.



Back to top


Updating the Silver Castle Customer Table

Once every couple of months, a customer may contact the Silver Castle administration team with an update to an address or phone number. The Silver Castle developers can update the table with the new information using the single update API. Listing 6 shows the use of this update API.


Listing 6. Single update API to update table
                
//Update the Street name for Customer
String updateSql = "UPDATE PDQ_SC.customer SET Street= 'Townsend' WHERE name= ?";
int updateCount = data.update (updateSql,"Customer3");
System.out.println ("Rows Updated " + updateCount);

The Silver Castle team also has a website where new customers can sign up to have the Silver Castle catalog mailed to them. Every month a utility is run to update the Customer database to add these new customers. For this purpose, the developers could create a job that can batch all the requests and insert them into the database by using just one inline method. They could use the batch update API for this case to efficiently update the database. Listing 7 shows the batch update API.


Listing 7. Batch update API
                
//Example Using UpdateMany
Customer addFirstCustomer = 
new Customer("Customer3","Costa Rica","Main Street","Arenal",
      "La Fortuna","90291","506-375-0273",null); 
Customer addSecondCustomer = 
new Customer("Customer4","Puerto Rico","Church Street",
 "Puerto Nuevo","San Juan","38364","293-484-8244",null); 
ArrayList<Customer> customerList = new ArrayList<Customer>();
customerList.add (addFirstCustomer);
customerList.add (addSecondCustomer);

insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
            "Province, Zip, Phone) VALUES (:name, :country, :street, " +
        ":city, :province,:zip,:phone)";
int[] updateCount = data.updateMany( sql, customerList);
if (updateCount != null)
  System.out.println ("Rows Inserted:” + updateCount.length);



Back to top


Retrieving auto-generated values

The overloading of the update() method allows the user to optionally request information regarding auto-generated columns. The Silver Castle developers can get the values generated by the database in any number of ways based on what the input to the update method is. Shown below are examples of the different ways the Silver Castle developers can code their application to get generated values back from the database after an insert.

Auto-generated values with pureQuery beans

In this example, the input to the insert is a pureQuery bean. The Customer object is defined with an @GeneratedKey annotation, and the column CID is defined as an identity column that always generates an integer. The value in the CID column is passed into the CID property before control is returned from the call to the update() method. Here, the auto-generated value is set in the CID property of the customer object.


Listing 8. Get the auto-generated value in the CID property of the Customer bean
                
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
            "Province, Zip, Phone) VALUES (:name, :country, :street, " +
        ":city, :province,:zip,:phone)";

//Create an instance of Customer Bean with the values to be inserted
Customer customer = 
new Customer("Customer2","US","BlackBerry Street","San Jose",
                     "Santa Clara","82652","408-273-4856", null); 
//Insert using a Bean
int updateCount = data.update (insertSql, customer);
System.out.println ("Generated Key Value:" + customer.cid);

Auto-generated values without pureQuery Beans

The Silver Castle developer can pass values without a pureQuery bean and still retrieve auto-generated values by using the following version of the update() method:

   <T> T update(java.lang.String sql, Class<T> returnClass, 
 String[] columnNames, Object... parameters) 

This method returns one or more generated values, depending on the return type indicated. The value of the return type Class<T> must be either:

  • Object[].class
  • A simple class directly assignable from JDBC, such as Integer.class or String.class

When the return type is a simple, directly assignable JDBC class, a single generated value is returned of the given type. The update count is not returned. Below is how a Silver Castle developer could get the auto-generated value into a simple class (for example, int.class).


Listing 9. Get the auto-generated value into a simple class
                
Object[] customerArray = new Object[7];
customerArray[0] = "CustomerForGenKey";
customerArray[1] = "US";
customerArray[2] = "Bixby Street";
customerArray[3] = "San Martin";
customerArray[4] = "Santa Clara";
customerArray[5] = "62826";
customerArray[6] = "408-272-6565";

insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street," + 
            "City, Province, Zip, Phone) VALUES(?,?,?,?,?,?,?)";
String[] colunmName = new String[] { "cid" };
int i = data.update (insertSql, int.class, colunmName, customerArray);
System.out.println ("AutoGenerated Keys as Int " + i + "\n");

When the return type is Object[].class, the first n elements of the array are the n generated values from the columns in the columnName parameter. The last element in the array is the update count. Below is how the Silver Castle developer could get the generated key value using an Object[]. The auto-generated value is returned in Object[0] and the update count is returned in Object[1] as Listing 10 shows.


Listing 10. Get the auto-generated value into an Object[ ]
                
Object[] customerArray = new Object[7];
customerArray[0] = "CustomerForGenKey";
customerArray[1] = "US";
customerArray[2] = "Barnaby Street";
customerArray[3] = "Gilroy";
customerArray[4] = "Santa Clara";
customerArray[5] = "62823";
customerArray[6] = "408-273-6568";

insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street," + 
            " City, Province, Zip, Phone) VALUES(?,?,?,?,?,?,?)";
String[] colunmName = new String[] { "cid" };
Object[] output = data.update (insertSql, Object[].class, 
                  colunmName, customerArray); 



Back to top


A pluggable callback mechanism using the Hook interface

The com.ibm.pdq.runtime.Hook interface can be used to create methods that run before and after inline methods. Assume that the Silver Castle developers know that their products cannot be shipped to customers in certain countries. For the sake of this example, we can assume that the countries with shipping restrictions are Costa Rica and Australia. The Hook interface provides an easy way so that a developer can define this check once and not have to add code in multiple places to check the customer’s country each time the Customer table is updated.

Hooks must be registered to instances of Data when the instances are created. When the Data object that is used by inline methods has a Hook registered, the following steps occur when an application calls a method of the Data interface:

  • Before any work is done by a method of the Data interface, the pre() method of the registered Hook is invoked.
  • The method being called does its work.
  • After all work is done by the method, the post () method of the registered Hook is invoked.

The Data interface, which defines inline methods, contains a number of JDBC methods on Connection objects, such as close (), commit (), rollback (), setAutoCommit (), and getAutoCommit (). The pre () and post () methods of a registered hook do not bracket these methods.

The pre () and post () methods need to be defined using the following parameters

  • String methodName: pureQuery passes the signature of the method to the pre () method
  • Data dataInstance: pureQuery passes the object that implements the Data interface
  • SqlStatementType statementType: pureQuery passes the type of the SQL statement (for example, SELECT, UPDATE, INSERT)
  • Object... parameters: pureQuery passes the parameters that are passed to the inline method
  • Object returnValue: return value from the call to the inline method

The example below demonstrates the use of the Hook interface. A Silver Castle application developer would define the pre() and post() method in the application under a class named HookCall. The pre() method checks whether the input parameter, the customer’s country, is valid and prevents an invalid row from being inserted into the database. Validation of the output from the method call can be checked using the post() method.


Listing 11. Use of the Hook interface
                
public static class HookCall implements Hook
{
  public void pre (String methodName, Data objectInstance, 
		    SqlStatementType statementType, Object... parameters)
  {
    String country = ((Customer)parameters[0]).country;
    If (!statementType.equalsIgnoreCase ("update") ||
        !statementType.equalsIgnoreCase("insert")) return;
    if (!(country.equals ("Australia") || country.equals ("Costa Rica")) )
    throw new DataRuntimeException
	  ("This Country " + country + " is not part of our customer base");
  }

  public void post (String methodName, Data objectInstance, 
     Object retValue, SqlStatementType statementType,
     Object... parameters)
  {
    //Do nothing
  }
}

The application could register the hook as shown in Listing 12 below. The input value for the country property of the Customer bean will be validated when the pre() method gets invoked.


Listing 12. Registering the hook
                
Connection con = DriverManager.getConnection(...);
HookCall hookCall = new HookCall ();
Data db = DataFactory.getData(con, hookCall);
sql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, Province, Zip, Phone)"
    + "VALUES(:name,:country,:street,:city,:province,:zip,:phone)";
Customer addCustomer2 = new Customer ("Customer2", "Costa Rica", "BlackBerry Street", 
                        "San Jose", "Santa Clara", "82652","408-273-4856", null);
int insertCount = db.update (sql, addCustomer2);



Back to top


Summary

This article provides a high-level introduction to the pureQuery inline method coding style. It provides some examples to illustrate likely motivations for a development team to develop a pureQuery application using inline methods. It also outlines the basic steps required to develop an inline method style application. Several powerful features of the style are introduced as potential motivators for choosing to code using inline method programming style.

If you are interested in learning more about developing pureQuery inline style applications, please follow the links throughout the article and in the resources section to the pureQuery online documentation, additional articles, and helpful tutorials.



Resources



About the author

Daya Vivek

Daya Vivek is a developer on the pureQuery runtime team at the IBM Silicon Valley Lab in San Jose California.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top