JDXATM Introduction

JDXA™ Introduction

This is a brief introduction to the JDXA ORM product (a.k.a. JDX for Android). JDXA can be used to develop mobile apps that require intuitive object-oriented access to device-local SQLite relational data on the Android platform. This document provides an overview of JDXA followed by brief instructions on how to install and use the product. It also provides sample code and a list of many sample projects shipped with the product SDK that demonstrate how different features of JDXA may easily be used to simplify object modeling and data integration tasks for Android apps.

Note: JDX is the core Object Relational Mapping (ORM) technology developed by Software Tree. This core ORM technology has been adapted for the Android platform and that adaptation is called JDXA. In the context of the Android platform, the terms JDX, JDXA, and JDX for Android may be used synonymously.

Overview

In Object Oriented Programming (OOP) languages (e.g. Java, C++, C#), a class encapsulates the structure and behavior of objects of a certain type. Business objects are easier to represent as instances of classes. A domain object model consists of various classes and their relationships comprising an application domain. Integration of domain object model data with relational data is a common need for most object-oriented applications.  ORM has become the preferred and most popular paradigm for such integration.  Our JDXA ORM product (a.k.a. JDX for Android) increases programmer productivity tremendously by presenting a more intuitive, object-oriented view of relational data and eliminating the need to write endless lines of complex low-level SQL code. Based on some well thought-out KISS (Keep It Simple and Straightforward) principles, JDX provides fast, flexible, lightweight, and easy-to-use ORM functionality.  

JDX bridges the gap between the worlds of objects and relations with a simple and flexible solution. Some of the prominent features of JDX include:

  • Mapping between an object model and a relational model (ORM Specification) is defined textually using a simple grammar that requires minimal specification. JDX User Manual has the full grammar specification
  • Full flexibility in domain object modeling – one-to-one, one-to-many, and many-to-many relationships as well as class-hierarchies supported.
  • A small yet powerful set of APIs that application developers can effectively use to integrate their object-oriented applications with relational databases.
  • POJO (Plain Old Java Objects) friendly non-intrusive programming model, which does not require you to change your Java classes in any way:
    • No need to subclass your domain classes from any base class
    • No need to clutter your source code with annotations
    • No need for DAO classes
    • No source code generation
    • No pre-processing or post-processing of your code
  • Automatic database schema creation based on the ORM specification.
  • A highly optimized metadata-driven object-relational mapping engine that is lightweight, dynamic, and flexible.

There are just 3 simple steps to use JDX:
  1. Define domain object model (Java classes)
  2. Define a declarative object-relational mapping specification textually
  3. Develop applications using intuitive and powerful JDX APIs

On top of the core ORM functionality of JDX, we have created many Android platform-specific utility classes to facilitate the easy and speedy development of mobile apps that need on-device access to SQLite relational database.

The JDXA SDK ships with plenty of documentation including the JDXA User Manual and Javadocs. The SDK also ships with many readymade sample application projects exemplifying the typical ORM-related structure of Android applications, ORM specification files, usage of Android-specific utility classes, and JDX API calls.

The following discussions provide some details about installing and using JDXA ORM SDK for Android app development.

The terms JDX, JDX for Android, and JDXA are used synonymously throughout this document.

Installation

Please unzip the JDXA ORM SDK distribution jar file in a new folder (for example, JDXForAndroid). You will see the following directory structure:

JDXForAndroid\
   JDXForAndroid_Introduction.pdf 
   \libs
   \docs
   \examples
   \SQLDroidLocal

The libs directory has the jar file JDXAndroid-nn.n.jar containing compiled code of JDXA ORM and associated utilities where nn.n denotes the version of JDXA. For example, JDXAndroid-01.5.jar denotes JDXA version 01.5 and JDXAndroid-02.0.jar denotes JDXA version 02.0.

The docs directory contains the Javadocs on JDXA ORM and associated utilities from an application developer’s point of view. This directory also contains the JDXA user manual.

The examples directory contains many sample Eclipse projects that exemplify the usage of JDXA ORM in Android applications.

The SQLDroidLocal directory has the JDBC driver (SQLDroid) library (SQLDroid\bin\sqldroid.jar) based on the open-source code available at GitHub. This library is provided under the terms of The MIT License (MIT).


Using JDXA in your Android project

To use JDXA in your Android project, just add the libraries JDXAndroid-nn.n.jar (shipped in the libs directory of the SDK) and sqldroid.jar (shipped in the SQLDroidLocal\SQLDroid\bin directory of the SDK) as external jars. For example,

  • In Eclipse:
    Put the above two jar files (JDXAndroid-nn.n.jar and sqldroid.jar) in your project’s Java Build Path
    (Properties Java Build Path Libraries Add External Jars…).
  • In Android Studio:
    1. Create, if not already present, a directory named libs under the app directory of your project. Add the above two jar files (JDXAndroid-nn.n.jar and sqldroid.jar) in that libs directory.
    2. Within Android Studio, under the Project view, locate the JDXAndroid-nn.n.jar file in the libs directory and right click on it and then click on the menu item Add as Library…. You will see the dependency on this jar file added to your build.gradle file as:
      compile files('libs/JDXAndroid-nn.n.jar')
    3. Repeat the above step (2) for the sqldroid.jar file.

After setting up these jar files as external libraries, you can start using JDX APIs in your Android project.

Simple Example Code

Just to give you a flavor of coding simplicity achieved by using JDXA ORM, this section provides representative example code of an Android application accessing an on-device SQLite database. Any UI and exception handling code is not provided in these code excerpts. There are just 3 simple steps to use JDX:

1) Define domain object model (Java classes)

JDX does not impose any restriction in terms of how a class should be defined. Instances of any POJO (Plain Old Java Object) can be persisted using JDX. Here is an example of a class definition (com.mycompany.model.Employee)

package com.mycompany.model;

import java.util.Date;

public class Employee {
    private int id;
    private String name;
    private Date DOB;  
    private boolean exempt; 
    private float compensation;  
       
     // A no-arg constructor needed for JDX
    public Employee() {
    }

    // Define other constructors, and setters/getters
}
Domain model class file Employee.java


2) Define a declarative object-relational mapping specification textually

Here is an example of the mapping specification contained in a text file (say example.jdx), which should be located in the res/raw directory of the Android project.

  • The name of the database is example.db, which is created/located in the default database directory for the package com.mycompany at /data/data/com.mycompany/databases/.
  • A CLASS specification mentioning the fully qualified class name encapsulates all the ORM information for that class. A primary key specification is mandatory for each class.
  • The default column name and type for each class attribute (field) is automatically deduced by JDX. The SQLMAP specification below is to change the column name of the table from the default ‘compensation’ to ‘salary’. If the default column name were to be acceptable (as in case of other attributes), the SQLMAP specification below would not be needed.
  • By default, JDX treats all those attributes, which are neither static, nor transient, nor volatile to be persistent. However, by using an IGNORE statement (not shown here) in the mapping specification, one can specify a list of 'regular' attributes that JDX should ignore for persistence.
JDX_DATABASE JDX:jdbc:sqldroid:/data/data/com.mycompany/databases/example.db;…
;
CLASS com.mycompany.model.Employee TABLE Employee
   PRIMARY_KEY id
   SQLMAP FOR compensation COLUMN_NAME Salary
;
Mapping file example.jdx

3) Develop applications using intuitive and powerful JDX APIs

The following code gives an example of how the core and utility JDX classes described earlier can be used to initialize an on-device SQLite database and the ORM system, and to interact with the database in an intuitive object-oriented way that does not involve writing any complex SQL code. The AppSpecificJDXSetup utility class (code not shown) is used to easily initialize the database (example.db) and the ORM system based on the mapping specification (example.jdx).

   public class JDXAndroidExampleActivity extends Activity { 
       JDXSetup jdxSetup = null;

       public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.main);

           try {
              AppSpecificJDXSetup.initialize(); 
              jdxSetup = AppSpecificJDXSetup.getInstance(this);
              useJDXORM(jdxSetup);
           } catch (Exception ex) { // Handle exception
               cleanup();
               return;
           }
       }

       private void cleanup() {
           AppSpecificJDXSetup.cleanup(); 
           jdxSetup = null;
       }

       private void useJDXORM(JDXSetup jdxSetup) throws Exception {
           JDXHelper jdxHelper = new JDXHelper(jdxSetup);

           String employeeClassName = Employee.class.getName();

           // First delete all existing employees from the database.
           jdxHelper.delete2(employeeClassName, null);

           // Create and save a new employee Mark
           Employee emp = new Employee(1, "Mark", …);
           jdxHelper.insert(emp, false);

           // Create and save a new employee Bill
           emp = new Employee(2, "Bill", …);
           jdxHelper.insert(emp, false);

           // Retrieve all the employees
           List queryResults = jdxHelper.getObjects(employeeClassName, null);

           // Retrieve employee Bill (id=2)
           emp = (Employee) jdxHelper.getObjectById(employeeClassName, "id=2", …);

           // Change and update attributes of Bill
           emp.setExempt(true);
           jdxHelper.update(emp, false);
       
           return;
       }
   }
Android activity programming file JDXAndroidExampleActivity.java

Sample Projects

The JDXA ORM for Android SDK ships with many sample Eclipse projects of working Android applications, which use JDXA ORM for data integration. These projects provide examples of many different features of the JDXA ORM technology including how to specify mappings for domain model classes having one-to-one, one-to-many, and many-to-many relationships, how to use sequence generators for unique ids, how to use object-oriented list view classes, how to automatically create the underlying database schema (tables and constraints) as per the mapping specification, and how to leverage various JDX APIs to easily interact with a relational database in an object-oriented way.

These projects are conveniently located under the examples directory. You may have to adjust the build/library paths for these projects depending upon the location of your SDK installation. Many of these applications produce some illustrative output in either the LogCat panel of the Eclipse IDE
(Window Show View Other, Android LogCat)
or on the screen.

High-level descriptions of some sample projects follow. Please see the actual code and the documentation for more details.

All the sample projects are provided as Eclipse IDE projects. However, an X in the Available as Android Studio Project column means that the SDK also contains that sample project for Android Studio IDE (in the directory examples/ AndroidStudioJDXAProjects).

Sample Project Brief Description Available as Android Studio Project
JDXAndroidSimpleExample Demonstrates how JDXA ORM and associated utilities can be used to easily develop an Android app that exchanges data of domain model objects with an SQLite database. X
JDXAndroidSimpleExample2 Demonstrates how a JDXHelper object can be used to interact with relational data using simpler methods. X
JDXAndroidAutoIncrementExample Demonstrates JDX facilitating the use of an autoincrement column for a primary key attribute of an object X
JDXAndroidSimpleLoginExample Demonstrates how to easily develop a user login/signup subsystem for an Android app. X
JDXAndroidRelationshipsExample Demonstrates using JDX for an object model with one-to-one and one-to-many relationships. X
JDXAndroidRelationships2Example Demonstrates how JDX can be used with one-to-one relationships such that the attribute values of the related (e.g., Address) objects are stored (INLINE or EMBEDDED) in the same table where the attribute values of the parent (e.g., Employee) objects are stored. X
JDXAndroidClassHierarchyExample Demonstrates using JDX for an object model with class hierarchies. Person is the superclass with BaseEmployee and Intern has its subclasses. BaseEmployee has further two subclasses - PermEmployee and TempEmployee. X
JDXAndroidImagesExample Demonstrates using JDX with image data. X
JDXAndroidListExample1 Demonstrates using a JDX provided ListAdapter class to query a list of objects from the database and displaying them. X
JDXAndroidListExample2 Demonstrates using a JDX provided ListAdapter class to query a filtered list of objects from the database and displaying them. X
JDXAndroidStreamingExample Demonstrates use of streaming queries to retrieve a list of objects in separate chunks as needed. X
JDXAndroidStreamingListExample Demonstrates using a JDX provided streaming ListAdapter class to query a list of objects from the database and displaying them iteratively on demand by fetching only a few objects from the database at a time.
JDXAndroidSequencesExample Demonstrates defining named sequences for generating persistently unique sequence numbers and using the JDXSeqUtility class to easily and efficiently create unique keys at runtime. X
JDXAndroidManyToManyExample Demonstrates using JDX for an object model with many-to-many relationships. X
JDXAndroidJSONExample Demonstrates using JDX for persistence of JSON objects. X
JDXAndroidJSON2Example Demonstrates using JDX for persistence of JSON objects with one-to-one and one-to-many relationships. X
JDXAndroidJSON2Example Demonstrates using JDXA for persistence of JSON objects with one-to-one and one-to-many relationships as well reusing the persistent data through other domain model classes. X
JDXAndroidListWithHolderPatternExample Demonstrates using JDX for retrieving a list of objects from databases, employing a holder pattern to cache and use the references to widgets for displaying an object in a list view, and persisting an updated object back into the database. X
JDXAndroidPrePostMethodsExample Demonstrates using JDXPreInsert, JDXPresUpdate, and JDXPostQuery callback methods in a domain model class to automatically massage (for example, encode, decode, compress, and decompress) instance data (perhaps for security and saving disk space reasons) before saving it to the database and after retrieving it from the database. X
JDXAndroidAsyncQueryExample Demonstrates using JDX for retrieving object(s) asynchronously in a background thread and then showing them in a UI (main) thread. X
JDXAndroidCachingExample Demonstrates how, with JDX, in-memory caches may be established for particular classes such that the database need not be queried for previously cached objects. X
JDXAndroidDBUpgradeV1Example
JDXAndroidDBUpgradeV2Example
Demonstrate a strategy to facilitate easy migration of the existing data produced from an old version of an app for use in the new version of the app. In this strategy, any needed data from the old (existing) database is migrated to a new database, which is then used by the new version of the app. The old database remains unchanged and may be discarded or may be used as a backup resource. X