- A Framework for Java/XML binding based on SAX2 -JaxMe ViewsOne 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
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 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
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 queriesIt 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); |