Example

Here is a sample structure.xml file:

<!DOCTYPE database PUBLIC "-//AIS.PL//DTD Mapping Description 0.4//EN"
                          "http://www.ais.pl/dtds/mapping_0_4.dtd">

<database>
  <structure name="AIS Project">
    <sql-table name="projects"/>
    <java-class name="Project"/>
    <fields>
      <field name="id" notNull="true" primaryKey="true">
        <sql-field name="id" type="integer" default=""/>
        <java-field name="id" default="" type="Integer"/>
      </field>
      <field name="Client id" notNull="true" primaryKey="false">
        <sql-field name="client_id" type="integer" default=""/>
        <java-field name="clientId" default="" type="Integer"/>
      </field>
      <field name="Name" notNull="true" primaryKey="false">
        <sql-field name="project_name" type="varchar(20)" default=""/>
        <java-field name="name" default="" type="String"/>
      </field>
    </fields>
    <operations>
      <select>
        <sql-query order-by="project_name"/>
        <java-method name="allProjects"/>
      </select>
      <select>
        <sql-query where="client_id = ?" order-by="project_name"/>
        <java-method name="forClient">
           <java-param name="clientId" type="Integer"/>
        </java-method>
      </select>
      <update>
        <sql-query set="project_name=?" where="client_id = ?"/>
        <java-method name="setNameForClient">
           <java-param name="name"     type="String"/>
           <java-param name="clientId" type="Integer"/>
        </java-method>
      </update>
    </operations>
  </structure>
  
  <structure name="AIS Client">
    <sql-table name="clients"/>
    <java-class name="Client"/>
    <fields>
      <field name="id" notNull="true" primaryKey="true">
        <sql-field name="id" type="integer" default=""/>
        <java-field name="id" type="Integer" default=""/>
      </field>
      <field name="Name" notNull="false" primaryKey="false">
        <sql-field name="name" type="varchar(128)" default=""/>
        <java-field name="name" type="String" default=""/>
      </field>
    </fields>
    <operations>
      <call>
        <sql-query body="{? = call process_client(?,?,?)}"/>
        <java-method name="processClient">
           <java-param name="adjustment" type="Integer"/>
        </java-method>
        <call-params>
          <call-param accessType="out" type="String"/>
          <call-param accessType="in"  fieldRef="Name"/>
          <call-param accessType="in"  fieldRef="id"/>
          <call-param accessType="in"  methodRef="adjustment"/>
        </call-params>
      </call>
    </operations>
  </structure>
</database>
   

This sample file defines two structures: AIS Project and AIS Client. We assume here that we have access to two underlying database tables (projects and clients) and these tables contain the columns referenced in our file (sql-field elements). We also assume that the data source for the database is correctly set in the application (see description of AIS.PL Framework).

The AIS Project structure has three fields and one of them - id - is the primary key. This structure also contains three operations: the first is used for getting all Project objects, the second returns objects which have the specified clientId property and the third sets the specified name property on Projects which have the given clientId value. The AIS Client structure has two fields with id field marked as primary key. The AIS Client also contains one operation - a call to stored procedure named "process_client".

The following files will be generated:

  • ApplicationDatabase.java
  • objects/base/BaseClient.java
  • objects/base/BaseProject.java
  • dbhandlers/ClientHandler.java
  • dbhandlers/ProjectHandler.java
  • handlers/ClientHandler.java
  • handlers/ProjectHandler.java

The generated ApplicationDatabase class will have the following public methods:

  • public Project selectProject(Integer id)
  • public void updateProject(Project object)
  • public void insertProject(Project object)
  • public void deleteProject(Project object)
  • public List selectProjectAllProjects()
  • public List selectProjectForClient(Integer clientId)
  • public int updateProjectSetNameForClient(String name, Integer clientId)
  • public Client selectClient(Integer id)
  • public void updateClient(Client object)
  • public void insertClient(Client object)
  • public void deleteClient(Client object)
  • public String callClientProcessClient(Client object, Integer adjustment)
The Project and Client classes should be added by the programmer to the objects directory (package). They must extend BaseProject and BaseClient respectively. Each BaseX class has private properties (as defined in java-field elements) and public get/set methods to access them.

The classes in the handlers directory (package) provide some helpful static methods to convert object properties to/from Map. For handlers/ClientHandler.java these methods are as follows:

  • public static Map describe(Client object)
  • public static void populate(Client object, Map properties)
  • public static void carefulPopulate(Client object, Map properties)
The describe method takes a Client instance and returns a Map with property names as keys and property values as values. The populate method does the opposite - it takes a Client instance, a Map instance and fills the Client with values from the Map. The carefulPopulate does some extra type checking - a property will be filled only if this property and the corresponding object in the Map are of the same class.

It is also possible to generate the appropriate structure.xml from an existing database. This is done by invoking dbdescribe script.