Aspire can be used as a data access library for Java programs. Aspire has three abstractions for data access.
In addition Aspire has a transactional aspect that cuts across all of data abstractions.This article examines each of these abstraction while identifying their relevance
In Relational abstraction Aspire allows you to execute data reads from a variety of sources (primary being the relational database) and returns a collection of rows to the calling program. This abstraction is represented by the following java interfaces
You can learn how to use this abstraction in the following O'Reilly article available at http://www.onjava.com/lpt/a/2856
This abstraction is suitable when you are writing business components that massages relational databases or exports contents out of databases. This may not be the API you want to use if you want to paint web pages. Turn to Hierarchical Data abstraction for this purpose.
In this abstraction a single call to the data access API will return a Hierarchical Data Set (HDS). An HDS is a collection of nodes where each node in the tree represents relational data set. This abstraction is represented by a single java interface called:
Ihds: Representing "interface to hierarchical data set"
You can learn how to use this abstraction in the following O'Reilly article available at http://www.onjava.com/lpt/a/3277
This abstraction is suitable when you are retrieving data to paint web pages. This is because the data needs of a web page are essentially hierarchical. Because of that this abstraction allows you retrieve all the data for a page in a single transaction. This abstraction is also suitable for B2B scenarios where you are returning a complex data set to the interested B2B parties.
When you are painting a web page you can get an "ihds" using this API and then you can use a JSP page to walk through the "ihds" to paint the individual sections of the page.
In this abstraction the focus is on typed data objects. Let us take the relational abstraction that was discussed above. The out put of a relational abstraction is a collection of rows where each row is represented as a generically typed IDataRow object. When you use typed language facilities like Java to access the columns, we can do a better job if this object is typed. For example if there is an IDataRow representing a row from a "Customer" table, it would be nice to see it as typed "CustomerRow" as opposed to the generic IDataRow. These typed objects have two advantages in a language environment:
A minor disadvantage of this approach is that your solution will have lots of data objects whose sole purpose is to act as helpers for programmers and also potentially guard against column name mismatches which will otherwise show up as runtime errors.
Although not documented in any great detail, Aspire is primed for data object access in two ways. In the first mechanism, the "Iterator" that walks through the IDataCollection actually returns objects of type "object". This means that the collection producers can actually return typed objects as opposed to IDataRow. This facility is available even now. Send me an email if you are interested in using this facility.
The second approach to data objects is to use typed hierarchical data sets. In this approach using a hierarchical data sets an equivalent class definition is generated. The programmer will bind this class to the hierarchical data set on the client end. This is like placing a typed view window on the physical hierarchical data set. This approach has the nice advantage of a single row of physical data representing multiple data objects. The data objects will pull the values as needed. Again send me an email if you want to elaborate and pursue on this approach
Irrespective of the data abstraction that is used, Aspire has an aspect that cuts across all of them orthogonally. This is the transactional aspect. Let me give you some examples of well known systems that display transactional aspects so that you can understand what I am talking about. Stored Procedures, Session Beans, CICS transactions are all examples that fall under this criteria.
In all these systems what you are doing is: You call a function identified by a name. That function will take a set of arguments. What comes back is a set of data. There is no state maintained across this transactional call. How this transaction is implemented is a different matter. But the usage of it is primarily functional and transactional.
So in Aspire irrespective of the data you want you end up calling a symbolic name (equivalent to a function) and passing in a hashtable of arguments. Aspire will locate a provider for that transaction (usually an object) and executes that transaction. Aspire uses configuration files to accomplish this.