Message:

Subscribe rss
Blog categories
All | Backendless features
How to Load Relational Data from mBaaS
May 28, 2014 by markpiller
Spread the love

This article reviews the APIs for working with relational persistent data in Backendless. By the end of the article, you will have a working application which demonstrates various mechanisms for loading related data objects from the backend-as-a-service data store. To avoid any terminology confusion or overlap, let’s define related data as multiple objects referencing one another in the object-oriented data model. For example, suppose there is a class called Order. The class aggregates (references) a collection of OrderItem’s. This is a one-to-many relation. The OrderItem class has a one-to-one relation with a class called Manufacturer. Consider the following diagram: class model - How to Load Relational Data from mBaaS

Java implementation of the class diagram shown above may look like this:

Order.java:

OrderItem.java

Manufacturer.java

The classes above will be used in the example. A complete project will all the functionality reviewed in this article is available in the Backendless Github repository.

Setting Up Your Dev Environment

We will be reviewing Backendless Data Service APIs in this article and you are welcome to follow along. For this you will need a Java IDE so you can build the client-side of the program and also setup a Backendless backend. For the IDE part, you can use the project from our Github repository or create a new one. For the latter, make sure to import backendless.jar which you can obtain from the Backendless SDK for Android/Java.

To setup the backend:

  1. Register/login to Backendless Console.
  2. Create/select an app.
  3. Click the Manage icon to get to the App Settings screen.
  4. From the App Settings screen copy/paste Application ID and Android Secret Key.
  5. Application ID and Secret Key must be pasted into the following API call:
    Java program: 

    Android program:

    The API call must be placed somewhere the begging of the program before any other code runs.

Populating Backend with Data

In order to see how related objects can be retrieved from the persistent storage, it must be populated with data. Backendless storage maps a table for each class. Therefore there will be 3 tables containing objects of the corresponding classes: Order, OrderItem and Manufacturer. There are two ways to add data to your Backendless backend:

  • Using the Import function of Backendless console.
    1. Download the zip archive which contains CSV files for each table.
    2. In your Backendless app/backend, navigate to Manage and select Import.
    3. Click the “single Zip file” link and browse to the zip file from step 1.
    4. Backendless automatically starts the import, which creates all the required tables and puts the object data in there.
  • Running the code which saves objects in the backend.
    1. Download the project Zip file from the GitHub repository.
    2. In your Backendless app/backend, navigate to Manage > App Settings.
    3. Copy/paste Application ID and Android/Java Secret Key into the code (see the main function in Main.java).
    4. Run the setupData() method:

Once the data is imported through console or created with the code, it should look as in the image below. This is a screenshot from the Backendless console’s Data screen. Feel free to browse around the created tables and inspect the relations between the data objects.

import result - How to Load Relational Data from mBaaS

Basic Data Load

The most basic way to load saved objects from Backendless uses the following API:

where T is the class designating the type of objects to load. For example, to load Order objects, you could use the following code:

This produces the following output:

Notice that with the basic data loading mechanism (the find() method without any arguments), the objects are loaded without any related data – none of the Order objects has the “items” collection initialized. The sections below describe how to retrieve these related objects.

Backend-driven Auto Load

With this approach related objects can be retrieved along with the parent instances without any changes in the calling program. Exactly the same code as shown above can retrieve some or all related objects. take a look at the Order objects in Backendless console. Specifically, notice the header of the “items” column:

auto load checkbox - How to Load Relational Data from mBaaS

Selecting the “auto load” checkbox instructs the Backendless backend to automatically pre-populate the specified relation when the parent object is retrieved with an API call. For example, when the checkbox shown above is selected, the method shown above produces the following result:

The auto-load option can be applied to any relation at any level. Notice that the output above does not include the “manufacturer” property. This can be corrected by selecting the “auto load” checkbox for that relation in the OrderItem table.

Single-Step Relations Fetch (API)

As the name suggests, this approach allows to pre-initialize specific relations when loading the parent object. For example, the code below loads a collection of Order objects and requests that both “items” and “manufacturer” relations to be pre-initialized in the returned Order instances:

The code produces the following output:

Two-Step Relations Fetch (API)

With this approach a parent object is loaded first and then there is a separate API call to load specific related objects into the given parent object. For instance, the example below fetches an Order object and then loads the “items” relations for the Order object using the loadRelations method.

Since the relationProps is a collection of strings, it can accommodate multiple relation properties (as shown in the example above). Specifically, notice the “items.manufacturer” property refers to the “manufacturer” relation in the OrderItem class. The code above produces the following output:

This approach can be combined with the “auto-load” option described above.

Loading Specific Child Objects

Quite often an application needs to load only specific subset of child objects. For example with the dataset used in this article, it may be required to load all the order items where the price is greater than certain value. Consider the example below. The code in this example loads the order items for a specific order with the condition specified in the query:

The queryString value uses a special format which we came up with to allow child-to-parent references. Notice the code loads objects from the OrderItem table (the argument of the “of” method is OrderItem.class:

The first part of queryString is “Order[items]”. The way you should read this is: the table from which the data is loaded is always referenced in the brackets expressed as a property of the parent object: “[items]”. To the left from that is a level-up lookup to the parent object: “Order”. Thus you can reference the parent object’s properties as it is done in the query: “Order[items].objectId” which means: take “objectId” from the Order object, which is a parent for the table where the backend runs the find operation – “[items]” or OrderItem.

Share this post
Tweet about this on TwitterShare on FacebookGoogle+