In addition to the usual object-oriented reasons for using inheritance, this inheritance model provides a very important kind of querying functionality. Given the above model, one can now perform a query like:
Get all the clothing items that have a shipping weight > 2 pounds.
Most importantly, the items returned are a combination of coat items and shorts items. Without SQL repository support for inheritance, this query must be run against each subtype in turn. At first glance this may not seem significant; however, given a store with ten subtypes like this, running this query against all subtypes can be painful. When the inheritance knowledge is built into the SQL repository, it can optimize the actual SQL queries needed.
The code for this query looks like this:
// get hold of the repository Repository gsa = ...; // get the view to use for querying "clothing" type items RepositoryView clothingView = gsa.getView("clothing"); // get a query builder QueryBuilder qb = clothingView.getQueryBuilder(); // build the query QueryExpression weightLimit = qb.createConstantQueryExpression(new Integer(2)); QueryExpression itemWeight = qb.createPropertyQueryExpression("shippingWeight"); Query q = qb.createComparisonQuery(itemWeight, weightLimit, QueryBuilder.GREATER_THAN); // run the query RepositoryItem[] items = clothingView.executeQuery(q); // separate the coats and shorts and do whatever with them for (int i=0; i<items.length; i++) { RepositoryItem item = items[i]; // all clothing items have a name and a description logDebug("clothing: " + item.getPropertyValue("name") + ' ' + item.getPropertyValue("description")); // the ItemDescriptor defines the "type" of an item RepositoryItemDescriptor desc = item.getItemDescriptor(); // now we do different things, depending on the // type of clothing item we have if (desc.getItemDescriptorName().equals("coat") { // coats have a property called "season" logDebug("\tcoat, season = " + item.getPropertyValue("season")); // do coat-related things myCoatProcessor(item); } else { // shorts have a property called "pleated" logDebug("\tcoat, season = " + item.getPropertyValue("pleated")); // do shorts-related things myShortsProcessor(item); } }
This example uses the name of the item descriptor to determine the item type. You can also look at the value of the type
property declared in your template. In the example, the enumerated properties are defined with the useCodeForValue
attribute set to true
. As result, the query looks like this:
... RepositoryItem item = items[i]; Integer itemTypeCode = (Integer)item.getPropertyValue("type"); if (itemTypeCode.intValue() == 0) { ... coats ... } else { ... shorts ... }
Which technique to use is up to you and may be largely a matter of style. The item descriptor approach uses the actual name like coat
or shorts
. The type attribute approach uses the type code stored in the clothing table: typically something like 0
or 1
, as in this case.