Maybe worth imitating how JPA 2.0 does it? I've only glanced at it in the past, but it seems similar. (Eclipselink is the reference implementation.)
http://wiki.eclipse.org/Introduction_to_EclipseLink_Expressions_%28ELUG%29 http://wiki.eclipse.org/EclipseLink/Examples/JPA/ORMQueries http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/expressions/ExpressionBuilder.html There's also something called a Criteria api now in JPA 2.0. I only looked at it (in the spec) as I was typing this message. http://jcp.org/aboutJava/communityprocess/pfd/jsr317/index2.html Chapter 6 Not sure exactly how it's different -- maybe it's just a specification of the expression builder syntax. On Wed, Dec 30, 2009 at 4:54 PM, Andrus Adamchik <[email protected]> wrote: > > On Dec 30, 2009, at 9:59 PM, Andrus Adamchik wrote: > >> I'd like to see if a similar approach can be extended to query building. >> Although that'll be a entirely different level of effort. > > Or maybe it is not that hopeless and we can use a set of user-facing query > "builders" without affecting our backend implementations. Just prototyped a > builder that can create EJBQL/SelectQuery with parameterized result type > that can be tied to ObjectContext.performQuery()... > > public interface Query<T> ... > public class Select<T> implements Query<T>... > > Here is now we can build correctly parameterized queries for different > result types. Also shows other EJBQL features, like subqueries. While it > adds some more terse API compared to SelectQuery, parameterization is the > main point here. I guess this is a good way to make EJBQLQuery finally > usable: > > void query_newAPI_EntityResult() { > > Select<Artist> query = Select.entity(Artist.class); > query.setDistinct(); > > Select<Painting> subquery = Select.entity(Painting.class); > subquery.setWhere(Painting.NAME.like("X%")); > > Expression clause1 = Artist.NAME.eq("X"); > Expression clause2 = Artist.PAINTINGS.dot(Painting.NAME).eq("Y"); > Expression clause3 = Exists.in(subquery); > query.setWhere(All.of(clause1, clause2, clause3)); > > query.addOrderByAscending(Artist.NAME); > query.addOrderByAscending(Artist.PAINTINGS.dot(Painting.NAME)); > > query.addDisjointPrefetch(Artist.PAINTINGS); > } > > void query_newAPI_ScalarResult() { > > Select<Date> query = Select.scalar(Artist.class, > Artist.DATE_OF_BIRTH); > > Expression clause1 = Artist.NAME.eq("X"); > Expression clause2 = Artist.PAINTINGS.dot(Painting.NAME).eq("Y"); > query.setWhere(Any.of(clause1, clause2)); > } > > void query_newAPI_MixedResult() { > > // fetching Artist entity plus paintings count > Select<Object[]> query = Select.mixed(Artist.class, > new Key<Artist>(""), Artist.PAINTINGS.count()); > > Expression clause1 = Artist.NAME.eq("X"); > Expression clause2 = Artist.PAINTINGS.dot(Painting.NAME).eq("Y"); > query.setWhere(Any.of(clause1, clause2)); > } > > void query_newAPI_GenericObject() { > > Select<Persistent> query = Select.generic(Persistent.class, > "MyGenericEntity"); > > Expression clause1 = new Key<String>("name").eq("X"); > Expression clause2 = new Key<Integer>("age").eq(5); > query.setWhere(All.of(clause1, clause2)); > } > > void query_newAPI_DataRow() { > > Select<DataRow> query = Select.dataRow(Artist.class); > > Expression clause1 = Artist.NAME.eq("X"); > Expression clause2 = Artist.PAINTINGS.dot(Painting.NAME).eq("Y"); > query.setWhere(All.of(clause1, clause2)); > } > > > > Andrus >
