Inverted Relation Retrieval¶
Backendless supports a special query syntax for loading a subset of child objects for a specific parent. Consider the following table schemas:
PhoneBook table:
Contact table:
Address table:
These tables will be used to demonstrate how to query Backendless for conditional related object retrieval.
The Map-based approach does not require you defining classes for the objects stored in Backendless. Instead your code can use java.util.Map
to to store and retrieve objects in/from Backendless. === "Custom Class"
Consider the following class definitions for the entities from the diagram: PhoneBook class:
package com.sample.entity;
import java.util.List;
public class PhoneBook
{
private String objectId;
private Contact owner;
private List<Contact> contacts;
public String getObjectId()
{
return objectId;
}
public void setObjectId( String objectId )
{
this.objectId = objectId;
}
public Contact getOwner()
{
return owner;
}
public void setOwner( Contact owner )
{
this.owner = owner;
}
public List<Contact> getContacts()
{
return contacts;
}
public void setContacts( List<Contact> contacts )
{
this.contacts = contacts;
}
}
package com.sample.entity;
import java.util.Date;
public class Contact
{
private String objectId;
private String name;
private int age;
private String phone;
private String title;
private Address address;
private Date updated;
public String getObjectId()
{
return objectId;
}
public void setObjectId( String objectId )
{
this.objectId = objectId;
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge( int age )
{
this.age = age;
}
public String getPhone()
{
return phone;
}
public void setPhone( String phone )
{
this.phone = phone;
}
public String getTitle()
{
return title;
}
public void setTitle( String title )
{
this.title = title;
}
public Address getAddress()
{
return address;
}
public void setAddress( Address address )
{
this.address = address;
}
public Date getUpdated()
{
return updated;
}
public void setUpdated( Date updated )
{
this.updated = updated;
}
}
package com.sample.entity;
public class Address
{
private String street;
private String city;
private String state;
public String getStreet()
{
return street;
}
public void setStreet( String street )
{
this.street = street;
}
public String getCity()
{
return city;
}
public void setCity( String city )
{
this.city = city;
}
public String getState()
{
return state;
}
public void setState( String state )
{
this.state = state;
}
}
The general structure of a whereClause query to load a collection of child objects for a specific parent object is:
ParentTableName[ relatedColumnName ].parentColumnName COLUMN-VALUE-CONDITION
Both columns relatedColumnName
and parentColumnName
must be declared in a table with name of ParentTableName
. The relatedColumnName
must be a relation column. The table relatedColumnName
points to is the table where the objects must be loaded from. The examples below demonstrate the usage of this syntax:
Find all contacts in a city for a specific phone book¶
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city = 'Smallville'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city = 'Smallville'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );
Find all contacts for the specific phone book where the city name contains letter 'a'¶
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city like '%a%'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "address.city like '%a%'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );
Find all contacts where age is greater than 20 for a specific phone book¶
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );
Find all contacts for a specific phone book where age is within the specified range¶
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age >= 21 and age <= 30" )
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age >= 21 and age <= 30" )
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );
Find all contacts for a specific phone book where age is greater than 20 and the city is Tokyo¶
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.get( "objectId" ) ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20 and address.city = 'Tokyo'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Map> result = Backendless.Data.of( "Contact" ).find( queryBuilder );
StringBuilder whereClause = new StringBuilder();
whereClause.append( "PhoneBook[contacts]" );
whereClause.append( ".objectId='" ).append( savedPhoneBook.getObjectId() ).append( "'" );
whereClause.append( " and " );
whereClause.append( "age > 20 and address.city = 'Tokyo'" );
DataQueryBuilder queryBuilder = DataQueryBuilder.create();
queryBuilder.setWhereClause( whereClause.toString() );
List<Contact> result = Backendless.Data.of( Contact.class ).find( queryBuilder );