Persisting Domain Queries

Wolfgang Schuetzelhofer edited this page Jul 31, 2017 · 17 revisions
Previous Next Table of Contents

Persisting Domain Queries

JCypher allows to persist Domain Queries with your domain. You can later reuse those queries by retrieving them from the db and executing them.
As JCypher also provides a generic domain model and allows to execute generic domain queries, you can retrieve and execute stored domain queries even if you don't have access to the Java code which originally created those queries.

You can store a domain query after you have created and completely specified the query. You can store the query either before or after you have executed it. To store it you don't need to execute the query at all.

Some sample code:
First we create a query (the code refers to the model of the JCypher sample project).

// create a domain access
IDomainAccess domainAccess = DomainAccessFactory
   .createDomainAccess(dbAccess, domainName);

/****** Select all Persons with lastName Smith who have Addresses in Europe ****/
// create a DomainQuery object
DomainQuery q = domainAccess.createQuery();
// create a DomainObjectMatch for objects of type Person
DomainObjectMatch<Person> smithsMatch = q.createMatch(Person.class);
// define a predicate expression in form of a WHERE clause
// which constrains the set of Persons
q.WHERE(smithsMatch.atttribute("lastName")).EQUALS("Smith");
		
// create a DomainObjectMatch for objects of type Area
DomainObjectMatch<Area> europeMatch = q.createMatch(Area.class);
// constrain the set of areas
// to contain europe only
q.WHERE(europeMatch.atttribute("name")).EQUALS("Europe");
		
// collect all Areas of Smith's Addresses
DomainObjectMatch<Area> smithAreasMatch = 
   q.TRAVERSE_FROM(smithsMatch).FORTH("pointsOfContact").FORTH("area")
      .FORTH("partOf").DISTANCE(0, -1).TO(Area.class);
		
// Select from all Smiths those with Addresses in Europe
DomainObjectMatch<Person> smithsInEuropeMatch = q.SELECT_FROM(smithsMatch).ELEMENTS(
	q.WHERE(smithAreasMatch).CONTAINS(europeMatch)
);

To store a query you use the QueryPersistor.

// Create a query persistor
QueryPersistor qPersistor = domainAccess.createQueryPersistor(q);

You can augment a query you want to persist by giving names to DomainObjectMatches. That provides for easier reuse of a stored query, and also provides for better readability of a string representation of a stored query.

// Augment DomainObjectMatches by assigning them with meaningful names.
// In that way stored queries are easier to reuse and to read.
qPersistor.augment(smithsMatch, "smiths")
   .augment(smithsInEuropeMatch, "smithsInEurope")
   .augment(europeMatch, "europe")
   .augment(smithAreasMatch, "smithAreas");

Finally you store the query giving it a unique name within the domain.

// Store the domain query.
// A domain query must have a unique name within a domain.
qPersistor.storeAs("Smiths_In_Europe");

Note: You can do the same thing using generic domain models and generic domain queries. The only difference is that you start with an IGenericDomainAccess instead of an IDomainAccess.

// create a generic domain access
IGenericDomainAccess domainAccess = DomainAccessFactory
   .createGenericDomainAccess(dbAccess, domainName);

Loading a Persisted Query

To load a persisted query, you use the QueryLoader. Again loading can either result in a DomainQuery or in a generic domain query 'GDomainQuery', depending on you starting with an IDomainAccess or an IGenericDomainAccess.
With the generic domain query execution will result in a generic domain model. You don't need to have the Java classes of the model at hand.

// create a domain access
IDomainAccess domainAccess = DomainAccessFactory
   .createDomainAccess(dbAccess, domainName);
// create a query loader for a stored domain query
QueryLoader<DomainQuery> qLoader = domainAccess.createQueryLoader("Smiths_In_Europe");
// load the query
DomainQuery qloaded = qLoader.load();

Or the generic variant:

// create a generic domain access
IGenericDomainAccess domainAccess = DomainAccessFactory
   .createGenericDomainAccess(dbAccess, domainName);
// create a query loader for a stored domain query
QueryLoader<GDomainQuery> qLoader = domainAccess.createQueryLoader("Smiths_In_Europe");
// load the generic query
GDomainQuery qloaded = qLoader.load();

Execute the query, retrieve the result(s) you are interested in.

// execute the query
DomainQueryResult result = qloaded.execute();
		
// get the DomainObjectMatch you are interested in.
// See how handy it comes in, that you have given a name
// to the DomainObjectMatch (you have augmented it).
DomainObjectMatch<?> smithsInEuropeM = qLoader
   .getDomainObjectMatch("smithsInEurope");
// or if you know the type.
DomainObjectMatch<Person> smithsInEuropeMatch = qLoader
   .getDomainObjectMatch("smithsInEurope", Person.class);

// retrieve the list of matching domain objects
List<Person> smithInEurope = result.resultOf(smithsInEuropeMatch);

Retrieve a List of Persisted Query Names

You can retrieve the list of names of all persisted queries of a domain.

// create a domain access
IDomainAccess domainAccess = DomainAccessFactory
   .createDomainAccess(dbAccess, domainName);
// get the names of persisted queries
List<String> names = domainAccess.getStoredQueryNames();

Previous Next Table of Contents