HierarchicalMap Tutorial - Intermediate Level

HierarchicalMap is an interface. So anyone can implement it. This tutorial is based on BasicHierarchicalmap, a reference implementation of HierarchicalMap.

Following subjects are covered in this tutorial:

    Basic Level
  1. Getting Started
  2. Creating Structure
  3. Recovering the Data
  4. Interacting with Collections
  5. Restructuring the Map

  6. Intermediate Level
  7. Working with Stream
  8. Working with XML
  9. Handling Large XML
  10. Accessing Data Base
  11. Accessing Preferences

  12. Advanced Level
  13. Template Filling
  14. .NET Interoperability
  15. Runtime schema validation
  16. Writing Application

  17. Planned for Future
  18. IDE's plugin for coding-time schema validation and code completion

(Javascript must be enabled to allow syntax highlighting for source code snippets in this tutorial)

Intermediate Level

9. Accessing DataBase

For this chapter, we will explore the org.dhmp.io.MapSQLStatement class. It is similar to java.sql.CallableStatement and can be used to issue SQL commands receiving HierarchicalMap as input and retrieving resultset mapped to HierarchicalMap.

Executing Statements

Start creating a model like below:

It is composed by 3 simple tables: book, book order and order item. The following code can create the table in Postgres assuming that port number, database user and password are correct. (There is a testcase in the source code where you can find a example for Oracle Express and SQL Server Express).

Now, we can insert some values on recently created tables. Also we want a unique id for books and orders. The sequence (or use identity for SQL Server) suits for that purpose. It is good practice to create a stored procedure to encapsulate these operations.

Calling Procedures

Then, we can invoke the stored procedure using MapSQLStatement. Actually, it is best practice to create database object using system user and execute the stored procedure using ordinary user to grant minimum privilege to the application user. Another point is the use of prepared statement instead of direct execution from concatenated String command. This is very important to avoid SQL Injection vulnerability.

Note that SQL statement has no named parameter. Thus the stored procedures parameters are retrieved sequentially from HierarchicalMap. The key, associated to the parameter value, is only for improving the readability of source code and could be omitted.

A relevant point is that parameter's class type must match the SQL type expected from data base.

The following code will create another stored procedure to list the table content and execute it, retrieving the result into HierarchicalMap:

The result should be something like the following:

<book>
   <id>1</id>
   <isbn>978-1441408488</isbn>
   <title>Treasure Island</title>
   <price>6.94</price>
</book>
<book>
   <id>2</id>
   <isbn>978-0670062645</isbn>
   <title>The Story of Ferdinand</title>
   <price>9.99</price>
</book>

...

Receiving Output Parameters

The MapSQLStatement.OutParameter class is an wrapper to identify output type parameter. The constructor receives the java.sql.Type that indicates the type of output parameter to be registered.

The return value will be added to HierarchicalMap under the key passed in parameter.

The MapSQLStatement.InOutParameter class can be used in similar way for stored procedure with a in/out parameter. Check the sample code below:

Note that MapSQLStatement.ResultSet is used to label the returning resultset as "items". The default label is "resultset" for the first resultset, "resultset1" for the second and so on.

The result should be like the following:

<items>
   <seq>1</seq>
   <title>The Story of Ferdinand</title>
   <isbn>978-0670062645</isbn>
   <quantity>2</quantity>
</items>
<items>
   <seq>2</seq>
   <title>Alexander and the Terrible, 
      Horrible, No Good, Very Bad Day</title>
   <isbn>978-0689711732</isbn>
   <quantity>1</quantity>
</items>

Note: line break was applied to the title element for better viewing of this page.

Multiple Resultsets

Sometimes, it is desirable to retrieve more than one resultset in a single stored procedure call. The MapSQLStatement can identify the resultsets and map it into HierarchicalMap.

Note that each database has different approach for resultset handling. For instance, Postgres and Oracle can only return resultsets as output parameters while SQL Server must return them as sequence of selects.

The next code must be executed after last sample code, i.e. after filling the order and order items properly.

The result should be like the following:

<list>
    <id>1</id>
    <isbn>978-1441408488</isbn>
    <title>Treasure Island</title>
    <price>6.94</price>
</list>
<list>
    <id>2</id>
    <isbn>978-0670062645</isbn>
    <title>The Story of Ferdinand</title>
    <price>9.99</price>
</list>
<list>
    <id>3</id>
    <isbn>978-0689711732</isbn>
    <title>Alexander and the Terrible, 
    Horrible, No Good, Very Bad Day
    </title>
    <price>7.99</price>
</list>
<list>
    <id>4</id>
    <isbn>978-0060229351</isbn>
    <title>Harold and the Purple Crayon</title>
    <price>11.55</price>
</list>
<items>
    <seq>1</seq>
    <title>The Story of Ferdinand</title>
    <isbn>978-0670062645</isbn>
    <quantity>2</quantity>
</items>
<items>
    <seq>2</seq>
    <title>Alexander and the Terrible, 
    Horrible, No Good, Very Bad Day
    </title>
    <isbn>978-0689711732</isbn>
    <quantity>1</quantity>
</items>

Note: line break was applied to the title element for better viewing of this page.

Continue to Intermediate Level - Accessing Preferences