Welcome to JaxMe!

SourceForge.net Logo
JaxMe

- A Framework for Java/XML binding based on SAX2 -

JaxMe Views

One of the most powerful features of SQL is to combine arbitrary tables and columns into new, virtual tables by joining and/or grouping existing, real tables. The select command is one possibility to achieve this, but it is even possible to fix the virtual table into a view.

JaxMe has a similar construct, that is specifically designed to support views. It works quite similar to reading schemata from a JDBC table. The idea is, that you may specify one or more select statements, which create a new virtual table with an identical structure. A new manager is created, which cannot write data, but only perform the given SQL statements to read data. Let's take a look at an example. Suggest the following table definition:

        CREATE TABLE language (
          id INT NOT NULL,
          language VARCHAR(10) NOT NULL,
          country VARCHAR(10) NOT NULL
        );
        CREATE CACHED TABLE httpSession (
          id INT NOT NULL IDENTITY,
          languageid INT NOT NULL,
          ipaddress VARCHAR(15) NOT NULL
        );
      

We can now use the following element in the XML schema:

         <xs:element name="ROSession">
           <xs:annotation>
             <xs:appinfo>
               <jdbcm:view name="ROSessionView">
                 <jdbcm:listMethod name="listByLanguage">
                   <jdbcm:query>
                     SELECT s.id, s.languageid, s.ipaddress, l.language,
                       l.country FROM httpSession AS s, language AS l
                       WHERE s.languageid = l.id AND l.id = ?
                   </jdbcm:query>
                   <jdbcm:description>
                     Returns all session instances with the given language.
                   </jdbcm:description>
                   <jdbcm:param name="pLanguage" type="xs:integer"/>
                 </jdbcm:listMethod>
               </jdbcm:view>
             </xs:appinfo>
           </xs:annotation>
           <xs:complexType>
             <xs:sequence/>
           </xs:complexType>
         </xs:element>
     

The above example will be mapped to XML documents like

        <ROSession>
          <ID>232</ID>
          <LANGUAGEID>2</LANGUAGEUD>
          <IPADDRESS>127.0.0.1</IPADDRESS>
          <LANGUAGE>de</LANGUAGE>
          <COUNTRY>DE</COUNTRY>
        <ROSession>
      
To create such documents, you would use a special manager, that is created for you:
        ClsROSessionManager manager = new ClsROSessionManager();
        java.util.List germanSessions = manager.listByLanguage(new Integer(2));
      
This ClsROSessionManager is no real manager: It cannot insert, update or delete documents. Even more, its select() method is also relatively useless. However, it has an added method listByLanguage() which you have specified in the above schema.

It is possible to combine multiple list methods into a single manager, as long as they all return the same table structure.

JaxMe views are particularly useful in the case of EJB: The BeanWriter can take the above schema and create a session bean with the same method. Using such methods is much faster than a comparable findByLannguage(Integer pLanguage) in the entity bean, because it doesn't instantiate the associated entity beans.

JaxMe views can control the size of the returned collection. Any list method can have attributes minResultSize (default 0) or maxResultSize (default "unbounded"). If the default is changed, then the generated methods will throw a SAX exception, if the number of instances returned is too low or too high. For convenience, if maxResultSize is 1, then the interface of the generated method is changed: It doesn't return a collection, but a single instance. For example:

        <jdbcm:listMethod name="listByLanguage" maxOccurs="1">s
          <jdbcm:query>
            SELECT s.id, s.languageid, s.ipaddress, l.language,
              l.country FROM httpSession AS s, language AS l
              WHERE s.languageid = l.id AND l.id = ?
          </jdbcm:query>
          <jdbcm:description>
            Returns the session instance with the given language.
          </jdbcm:description>
          <jdbcm:param name="pLanguage" type="xs:integer"/>
        </jdbcm:listMethod>
      
Without the maxOccurs parameter, the method interface would be
        java.util.List listByLanguage(Integer pLanguage);
      
In the above example, however, it looks like
        ClsROSession listByLanguage(Integer pLanguage);
      

Dynamic queries

It is quite usual, that queries are not fixed, but built dynamic. For example, suggest an HTML form that allows to search for books. Various search fields might allow to specify an ISBN number, an author or a title being searched. Even more, one would use a combination.

JaxMe allows to specify dynamic queries by using so called patterns:

        <jdbcm:listMethod name="listByDynamicQuery">
          <jdbcm:query>
            SELECT * FROM books WHERE {DynamicPart}
          </jdbcm:query>
          <jdbcm:description>
            Returns a list of instances matching the given conditions.
          </jdbcm:description>
          <jdbcm:pattern name="pDynamicPart" sample="1=1"
            match="{DynamicPart}"/>
        </jdbcm:listMethod>
      
This example would create a method
        java.util.List listByDynamicQuery(String pDynamicPart);
      
The value of pDynamicPart might be, for example, Author = 'Adams, Douglas'. Of course, you can also mix the use of placeholders and patterns by specifying both jdbcm:pattern and jdbcm:param subelements.

In the above example the dynamic query part was Author = 'Adams, Douglas'. Typically one would prefer a dynamic part like Author = ?. This can be achieved by the following definition:

        <jdbcm:listMethod name="listByDynamicQuery">
          <jdbcm:query>
            SELECT * FROM books WHERE {DynamicPart}
          </jdbcm:query>
          <jdbcm:description>
            Returns all instances matching the conditions in
              pDynamicPart. The String pDynamicPart may use
              question marks (placeholders). If you use placeholders,
              you must also supply the values being substituted in
              the array pValue.
            The conditions may use placeh
          </jdbcm:description>
          <jdbcm:pattern name="pDynamicPart" sample="1=1"
            match="{DynamicPart}"/>
          <jdbcm:placeholders name="pValues"/>
        </jdbcm:listMethod>
      
The created methods signature would now be:
        java.util.List listByDynamicQuery(String pDynamicPart,
                                          Object[] pValues);
      
For any placeholder in the dynamic part one must supply a type/value pair, with the type being one of the constants from
JMManager. For example:
        Object[] values = new Object[]{JMManager.VARCHAR,
                                       "Douglas Adams"};
        java.util.List result = listByDynamicQuery("Author = ?", values);
      

  FAQ   |   Reference   |   Contact   |   Comments   |   Forward   |   Back   |   Top of Page