You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2012/09/23 09:45:12 UTC
svn commit: r1388971 - in
/cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx: expressions.xml
orderings.xml part2.xml
Author: aadamchik
Date: Sun Sep 23 07:45:11 2012
New Revision: 1388971
URL: http://svn.apache.org/viewvc?rev=1388971&view=rev
Log:
docs
Expressions API
Orderings
Added:
cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/orderings.xml
Modified:
cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/expressions.xml
cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/part2.xml
Modified: cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/expressions.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/expressions.xml?rev=1388971&r1=1388970&r2=1388971&view=diff
==============================================================================
--- cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/expressions.xml (original)
+++ cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/expressions.xml Sun Sep 23 07:45:11 2012
@@ -89,20 +89,22 @@
</section>
<section xml:id="expressions-from-strings">
<title>Creating Expressions from Strings </title>
- <para>While in most cases users are likely to rely on API for expressions creation, as described
- in the following chapter, we'll start by discussing String expressions, as this will
- help to understand the expressions structure. Expressions can be created using
- <code>Expression.fromString</code> method. Here is an
- example:<programlisting>Expression e = Expression.fromString("name like 'A%' and price < 1000");</programlisting>This
- expression may be used to match Paintings with names that start with "A" and a price
- less than $1000. While this example is pretty self-explanatory, there are a few points
- worth mentioning. "name" and "price" here are object paths discussed earlier. As always,
- paths themselves are not attached to a specific root entity and can be applied to any
- entity that has similarly named attributes or relationships. So when we are saying that
- this expression "may be used to match Paintings", we are implying that there may be
- other entities, for which this expression is valid. Now the expression details... </para>
- <para><emphasis role="italic">Character constants</emphasis> that are not paths should be
- enclosed in single or double quotes. Two of the expressions below are
+ <para>While in most cases users are likely to rely on API from the following section for
+ expression creation, we'll start by showing String expressions, as this will help
+ understanding the semantics. A Cayenne expression can be represented as a String, which
+ can be later converted to an expression object using <code>Expression.fromString</code>
+ static method. Here is an
+ example:<programlisting>String expString = "name like 'A%' and price < 1000";
+Expression exp = Expression.fromString(expString);</programlisting>This
+ particular expression may be used to match Paintings with names that start with "A" and
+ a price less than $1000. While this example is pretty self-explanatory, there are a few
+ points worth mentioning. "name" and "price" here are object paths discussed earlier. As
+ always, paths themselves are not attached to a specific root entity and can be applied
+ to any entity that has similarly named attributes or relationships. So when we are
+ saying that this expression "may be used to match Paintings", we are implying that there
+ may be other entities, for which this expression is valid. Now the expression details... </para>
+ <para><emphasis role="italic">Character constants</emphasis> that are not paths or numeric values
+ should be enclosed in single or double quotes. Two of the expressions below are
equivalent:<programlisting>name = 'ABC'
// double quotes are escaped inside Java Strings of course
@@ -141,8 +143,10 @@ name = enum:org.foo.EnumClass.VALUE1</pr
SelectQueries:<programlisting>name like 'A%'</programlisting><emphasis role="italic"
>Named parameters.</emphasis> Expressions can have named parameters (names that
start with "$"). Parameterized expressions allow to create reusable expression
- templates. This warrants a full code
- example:<programlisting>Expression template = Expression.fromString("name = $name");
+ templates. Also if an Expression contains a complex object that doesn't have a simple
+ String representation (e.g. a Date, a DataObject, an ObjectId), parameterizing such
+ expression is the only way to represent it as String. Here are some
+ examples:<programlisting>Expression template = Expression.fromString("name = $name");
...
Map p1 = Collections.singletonMap("name", "Salvador Dali");
Expression qualifier1 = template.expWithParameters(p1);
@@ -162,21 +166,84 @@ Artist dali = // asume we fetched this o
Map p1 = Collections.singletonMap("artist", dali);
Expression qualifier1 = template.expWithParameters(p1);</programlisting>Uninitialized
parameters will be automatically pruned from expressions, so a user can omit some
- parameters when creating an expression from a parameterized template:<programlisting>Expression template = Expression.fromString("name like $name and dateOfBirth > $date");
+ parameters when creating an expression from a parameterized
+ template:<programlisting>Expression template = Expression.fromString("name like $name and dateOfBirth > $date");
...
Map p1 = Collections.singletonMap("name", "Salvador%");
Expression qualifier1 = template.expWithParameters(p1);
// qualifier1 is now equals to "name like 'Salvador%'", the 'dateOfBirth' condition was
-// pruned, as no value was specified for the $date parameter</programlisting><note>
+// pruned, as no value was specified for the $date parameter</programlisting></para>
+ <para><emphasis role="italic">Null handling.</emphasis> Handling of Java nulls as operands
+ is no different from normal values. Instead of using special conditional operators, like
+ SQL does (IS NULL, IS NOT NULL), "=" and "!=" expressions can be used directly with null
+ values. It is up to Cayenne to translate expressions with nulls to the valid SQL.</para>
+ <para>
+ <note>
<para>A formal definition of all possible valid expressions in a form of JavaCC
grammar is provided in Appendix C</para>
- </note></para>
+ </note>
+ </para>
</section>
<section xml:id="expressions-with-expressionfactory">
- <title>Creating Expressions with ExpressionFactory</title>
+ <title>Creating Expressions with API</title>
+ <para>Creating expressions from Strings is a powerful and dynamic approach, however a safer
+ alternative is to use Java API. It provides some degree of compile-time checking of
+ expressions validity. The API is cenetred around ExpressionFactory class, and the
+ Expression class. ExpressionFactory contains a number of rather self-explanatory factory
+ methods. We won't be going over all of them in detail, but will rather show a few
+ general examples and some gotchas. </para>
+ <para>The following code recreates the expression from the previous chapter, but now using
+ expression
+ API:<programlisting>// String expression: name like 'A%' and price < 1000
+Expression e1 = ExpressionFactory.likeExp(Painting.NAME_PROPERTY, "A%");
+Expression e2 = ExpressionFactory.lessExp(Painting.PRICE_PROPERTY, 1000);
+Expression finalExp = e1.andExp(e2); </programlisting>This
+ is more verbose than creating it from String, but it is also more resilient to the
+ entity properties renaming and precludes semantic errors in the expression String.<note>
+ <para>The last line in the example above shows how to create a new expression by
+ "chaining" 2 other epxressions. A common error when chaining expressions is to
+ assume that "andExp" and "orExp" append another expression to the current
+ expression. In fact a new expression is created. I.e. Expression API treats
+ existing expressions as immutable.</para>
+ </note></para>
+ <para>As discussed earlier, Cayenne supports aliases in path Expressions, allowing to
+ control how SQL joins are generated if the same path is encountered more than once in
+ the same Expression. Two ExpressionFactory methods allow to implicitly generate aliases
+ to "split" match paths into individual joins if
+ needed:<programlisting>Expression matchAllExp(String path, Collection values)
+Expression matchAllExp(String path, Object... values)</programlisting></para>
+ <para>"Path" argument to both of these methods can use a split character (a pipe symbol '|')
+ instead of dot to indicate that relationship following a path should be split into a
+ separate set of joins, one per collection value. There can only be one split at most in
+ any given path. Split must always precede a relationship. E.g. "|exhibits.paintings",
+ "exhibits|paintings", etc. Internally Cayenne would generate distinct aliases for each
+ of the split expressions, forcing separate joins.</para>
</section>
<section xml:id="expressions-in-memory">
<title>Evaluating Expressions in Memory</title>
+ <para>When used in a query, an expression is converted to SQL WHERE clause (or ORDER BY
+ clause) by Cayenne during query execution. Thus the actual evaluation against the data
+ is done by the database engine. However the same expressions can also be used for
+ accessing object properties, calculating values, in-memory filtering. </para>
+ <para>Checking whether an object satisfies an
+ expression:<programlisting>Expression e = ExpressionFactory.inExp(User.NAME_PROPERTY, "John", "Bob");
+User user = ...
+if(e.match(user)) {
+ ...
+}</programlisting>Reading
+ property
+ value:<programlisting>Expression e = Expression.fromString(User.NAME_PROPERTY);
+String name = e.evaluate(user);</programlisting></para>
+ <para>Filtering a list of
+ objects:<programlisting>Expression e = ExpressionFactory.inExp(User.NAME_PROPERTY, "John", "Bob");
+List<User> unfiltered = ...
+List<User> filtered = e.filterObjects(unfiltered);</programlisting></para>
+ <para>
+ <note>
+ <para>Current limitation of in-memory expressions is that no collections are
+ permitted in the property path.</para>
+ </note>
+ </para>
</section>
</chapter>
Added: cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/orderings.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/orderings.xml?rev=1388971&view=auto
==============================================================================
--- cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/orderings.xml (added)
+++ cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/orderings.xml Sun Sep 23 07:45:11 2012
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="5.0" xml:id="orderings">
+ <title>Orderings</title>
+ <para>An Ordering object defines how a list of objects should be ordered. Orderings are
+ essentially path expressions combined with a sorting strategy. Creating an Ordering:
+ <programlisting>Ordering o = new Ordering(Painting.NAME_PROPERTY, SortOrder.ASENDING);</programlisting></para>
+ <para>Like expressions, orderings are translated into SQL as parts of queries (and the sorting
+ occurs in the database). Also like expressions, orderings can be used in memory, naturally -
+ to sort
+ objects:<programlisting>Ordering o = new Ordering(Painting.NAME_PROPERTY, SortOrder.ASCENDING_INSENSITIVE);
+List<Painting> list = ...
+o.orderList(list);</programlisting>Note
+ that unlike filtering with Expressions, ordering is performed in-place. This list object is
+ reordered and no new list is created.</para>
+</chapter>
Modified: cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/part2.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/part2.xml?rev=1388971&r1=1388970&r2=1388971&view=diff
==============================================================================
--- cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/part2.xml (original)
+++ cayenne/main/trunk/docs/docbook/cayenne-guide/src/docbkx/part2.xml Sun Sep 23 07:45:11 2012
@@ -6,6 +6,7 @@
<xi:include href="starting-cayenne.xml"/>
<xi:include href="persistent-objects-objectcontext.xml"/>
<xi:include href="expressions.xml"/>
+ <xi:include href="orderings.xml"/>
<xi:include href="queries.xml"/>
<xi:include href="lifecycle-events.xml"/>
<xi:include href="performance-tuning.xml"/>