Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Siminov Hybrid ORM - Object-relational Mapping (Android + Phonegap)

5.00/5 (4 votes)
7 Jul 2013Apache4 min read 20.2K  
Siminov makes an application developer's life easy and simple by mapping JavaScript/Java objects to a relational database.

Siminov Framework

Introduction

A Hybrid Application, by definition, is derived from a combination of technologies, approaches, or elements of different kinds. With respect to mobile applications, a hybrid application leverages the best of both native and mobile web technologies.

In a Hybrid Environment, it is very difficult to map JavaScript/Java objects to a relational database, but Siminov makes the application developer's life easy and simple by mapping JavaScript/Java objects to a relational database.

Siminov can be used with PhoneGap. It enables application developers to build applications for mobile devices using JavaScript, HTML5, and CSS3, instead of device-specific languages such as Java.

Siminov not only takes care of the mapping from JavaScript/Java classes to database tables (and from JavaScript/Java data types to SQL data types) but also provides data query and retrieval facilities. It can significantly reduce development time otherwise spent with manual data handling in SQLite. Siminov's design goal is to relieve the developer from 99% of common data persistence-related programming tasks by eliminating the need for manual, hand-crafted data processing using SQLite. However, unlike many other persistence solutions, Siminov does not hide the power of SQLite from you and guarantees that your investment in relational technology and knowledge is as valid as always.

All the features you need

Easy Configuration

Siminov Hybrid ORM provides a easy set of defined descriptors which works for both Native and Web. These can be broadly classified as:

  • Application Descriptor: Application Descriptor is the one who connects application to Siminov Framework. It provide basic information about application, which defines the behavior of application.
  • XML
    <!-- Design Of ApplicationDescriptor.si.xml -->
    
    <siminov>
        
        <!-- General Application Description Properties -->    
            <!-- Mandatory Field -->
        <property name="name">application_name</property>    
        
            <!-- Optional Field -->
        <property name="description">application_description</property>
        
            <!-- Mandatory Field (Default is 0.0) -->
        <property name="version">application_version</property>
    
        <!-- Siminov Framework Performance Properties -->    
            <!-- Optional Field (Default is true)-->
        <property name="load_initially">true/false</property>
    
        <!-- Database Descriptors Used By Application (zero-to-many) -->    
            <!-- Optional Field's -->
        <database-descriptors>
            <database-descriptor>full_path_of_database_descriptor_file</database-descriptor>
        </database-descriptors>
        
        <!-- Event Handlers Implemented By Application (zero-to-many) -->    
            <!-- Optional Field's -->
        <event-handlers>
            <event-handler>full_java_class_path_of_event_handler/javascript_class_path_of
              _event_handler (ISiminovHandler/IDatabaseHandler)</event-handler>
        </event-handlers>
    </siminov>
  • Database Descriptor: Database Descriptor is the one who defines the schema of database.
  • XML
    <!-- Design Of DatabaseDescriptor.si.xml -->
    
    <database-descriptor>
    
            <!-- General Database Descriptor Properties -->    
                <!-- Mandatory Field -->
        <property name="database_name">name_of_database_file</property>
    
                <!-- Optional Field (Default is sqlite)-->
        <property name="type">type_of_database</property>
    
            <!-- Optional Field -->
        <property name="description">database_description</property>
    
            <!-- Optional Field (Default is false) -->r/>    
             <property name="is_locking_required">true/false</property>
        
            <!-- Optional Field (Default is false) -->
        <property name="external_storage">true/false</property>
    
                    
        <!-- Database Mapping Descriptor Paths Needed Under 
                      This Database Descriptor -->    br/>            <!-- Optional Field -->
        <database-mappings>
                    <database-mapping path="full_path_of_database_mapping_descriptor_file" />
        </database-mappings>
    
    
        <!-- Libraries Needed Under This Database Descriptor -->    
                <!-- Optional Field -->
        <libraries>
            <library>full_path_of_library_descriptor_file</library>
        </libraries>br/>    
    </database-descriptor>
  • Library Descriptor: Library Descriptor is the one who defines the properties of library.
  • XML
    <!-- Design Of LibraryDescriptor.si.xml -->
    
    <library>
    
            <!-- General Library Properties -->
                <!-- Mandatory Field -->
        <property name="name">name_of_library</property>
        
            <!-- Optional Field -->r/>    
               <property name="description">description_of_library</property>
    
        <!-- Database Mapping Descriptor Paths Needed Under 
                  This Library Descriptor -->    br/>        <!-- Optional Field -->
        <database-mappings>
            <database-mapping path="full_path_of_database_mapping_descriptor_file" />
        </database-mappings>br/>
        <!-- Hybrid Adapters Needed Under This Library Descriptor -->
            
        <!-- Optional Field -->
            <!-- Hybrid Adapters -->
        <adapters>
            <adapter path="full_path_of_hybrid_adapter_file"></adapter>
        </adapters>
         
    </library>
  • Database Mapping Descriptor: Database Mapping Descriptor is one which does ORM, it maps POJO class to database table.
  • XML
    <!-- Design Of DatabaseMappingDescriptor.si.xml -->
    
    <database-mapping>
    
        <!-- General Properties Of Table And Class -->
        
            <!-- TABLE_NAME: Mandatory Field -->
                    <!-- CLASS_NAME: Mandatory Field -->
        <table table_name="name_of_table" 
          class_name="mapped_pojo_java_class_name/mapped_pojo_javascript_class_name">
            
            <!-- Column Properties Required Under This Table -->
            
            <!-- Optional Field -->
            
                <!-- VARIABLE_NAME: Mandatory Field -->
                            <!-- COLUMN_NAME: Mandatory Field -->
            <column variable_name="class_variable_name" column_name="column_name_of_table">
                
                    <!-- Mandatory Field -->
                <property name="type">java_variable_data_type/javascript_variable_data_type</property>
                
                    <!-- Optional Field (Default is false) -->
                <property name="primary_key">true/false</property>
                
                    <!-- Optional Field (Default is false) -->
                <property name="not_null">true/false</property>
                
                    <!-- Optional Field (Default is false) --> 
                       <property name="unique">true/false</property>
                
                    <!-- Optional Field -->
                <property name="check">
                  condition_to_be_checked (Eg: variable_name 'condition' value; variable_name > 0)
                </property>
                
                    <!-- Optional Field -->
                <property name="default">default_value_of_column (Eg: 0.1)</property>
            
            </column>       
            
            <!-- Index Properties -->
                    
            <!-- Optional Field -->
                <!-- NAME: Mandatory Field -->
                <!-- UNIQUE: Optional Field (Default is false) -->
            <index name="name_of_index" unique="true/false">
                <column>column_name_needs_to_add</column>
            </index>
            
            <!-- Map Relationship Properties -->
                    
            <!-- Optional Field -->    
            <relationships>
                
                    <!-- REFER: Mandatory Field -->
                    <!-- REFER_TO: Mandatory Field -->
                <one-to-one refer="class_variable_name" 
                  refer_to="map_to_pojo_java_class_name/map_to_pojo_javascript_class_name" 
                  on_update="cascade/restrict/no_action/set_null/set_default" 
                  on_delete="cascade/restrict/no_action/set_null/set_default">
                        
                        <!-- Optional Field (Default is false) -->
                    <property name="load">true/false</property>
                </one-to-one>        
                
                    <!-- REFER: Mandatory Field -->
                    <!-- REFER_TO: Mandatory Field -->
                <one-to-many refer="class_variable_name" 
                  refer_to="map_to_pojo_java_class_name/map_to_pojo_javascript_class_name" 
                  on_update="cascade/restrict/no_action/set_null/set_default" 
                  on_delete="cascade/restrict/no_action/set_null/set_default">
                        
                        <!-- Optional Field (Default is false) -->
                    <property name="load">true/false</property>
                </one-to-many>        
    
                        <!-- REFER: Mandatory Field -->
                    <!-- REFER_TO: Mandatory Field -->
                <many-to-one refer="class_variable_name" 
                  refer_to="map_to_pojo_java_class_name/map_to_pojo_javascript_class_name" 
                  on_update="cascade/restrict/no_action/set_null/set_default" 
                  on_delete="cascade/restrict/no_action/set_null/set_default">
                        
                        <!-- Optional Field (Default is false) -->
                    <property name="load">true/false</property>
                </many-to-one>        
    
                    <!-- REFER: Mandatory Field -->
                    <!-- REFER_TO: Mandatory Field -->
                <many-to-many refer="class_variable_name" 
                  refer_to="map_to_pojo_java_class_name/map_to_pojo_javascript_class_name" 
                  on_update="cascade/restrict/no_action/set_null/set_default" 
                  on_delete="cascade/restrict/no_action/set_null/set_default">
                        
                        <!-- Optional Field (Default is false) -->
                    <property name="load">true/false</property>
                </many-to-many>        
                                        
            </relationships>
    
        </table>
    
    </database-mapping>
  • Hybrid Descriptor: Hybrid Descriptor is one which describes properties required to map Web to Native and vice-versa. It is optional descriptor.
  • XML
    <!-- Design of HybridDescriptor.si.xml -->
     
    <hybird-descriptor>
    
        <!-- Adapters -->
        <adapters>
            
            <!-- Adapter -->
            <adapter>
                
                <!-- General Adapter Properties -->
                    <!-- Mandatory Field -->
                <property name="name">adapter_name</property>
                    
                    <!-- Optional Field -->
                    <property name="description">adapter_description</property>
                
                    <!-- Mandatory Field -->
                <property name="type">WEB-TO-NATIVE|NATIVE-TO-WEB</property>
                
                    <!-- Optional Field -->
                <property name="map_to">name_of_adapter_class</property>
        
                    <!-- Optional Field (DEFAULT: FALSE)--> <property name="cache">true/false</property>
                
                <!-- Handlers -->
                    <!-- Handler -->
                <handlers>
                    
                    <handler>
                        
                        <!-- General Handler Properties -->
                            <!-- Mandatory Field -->
                                            <property name="name">handler_name</property>
                        
                            <!-- Optional Field -->
                        <property name="description">handler_description</property>                
                                            
                            <!-- Mandatory Field -->
                            <property name="map_to">name_of_handler_method</property>                
                                                                           
                        <!-- Parameters -->
                        <parameters>
                            
                            <!-- Parameter -->
                            <parameter>
                                
                                    <!-- Mandatory Field -->
                                <property name="name">name_of_parameter</property>
                                
                                    <!-- Mandatory Field -->
                                    <property name="type">parameter_type</property>
                                
                                    <!-- Optional Field -->
                                <property name="description">description_of_parameter</property>
                                
                            </parameter>
                            
                        </parameters>
                        
                        <return>
                            
                                <!-- Mandatory Field -->
                            <property name="type">return_type</property>
                            
                                <!-- Optional Field -->
                            <property name="description">return_data_description</property>
                            
                        </return>     
                    </handler>
                        
                </handlers>
        
            </adapter>
    
            
            <!-- Adapter Paths -->
                    <adapter path="adapter_path" />
                        
        </adapters>
        
    
        <!-- Library Needed Under This HybridDescriptor -->
        <libraries>
            
            <library>full_path_of_library_descriptor_file</library>
            
        </libraries>
        
    </hybird-descriptor>

Application Deployment

All resources required by application are created and managed by Siminov Framework. (Eg: Creating Application Database, Deploying Application, Managing Relationships, Generating Database Queries).

Multiple Schema's Supported

Siminov Framework provides easy way to support multiple schema's if required by application. Using descriptors developer can define properties of database.

Events Notifier

Siminov provides event notification by which application get notification if their is any event triggered by framework.

  • Siminov Events: ISiminov is a event handler which automatically gets triggered when any action happen in framework. Application have to provide implementation for ISiminov event notifier and register them with siminov.
  • Java
    public interface ISiminovEvents {
    
        public void firstTimeSiminovInitialized();
    
        public void siminovInitialized();
    
        public void siminovStopped();
    }
  • Database Events: IDatabase is a event handler which automatically gets triggered when action happen with database. Application have to provide implementation for IDatabase event notifier and register them with siminov.
  • Java
    public interface IDatabase {
    
        public void openOrCreate(final DatabaseDescriptor databaseDescriptor) throws DatabaseException;
    
        public void close(final DatabaseDescriptor databaseDescriptor) throws DatabaseException;
    
        public void executeQuery(final DatabaseDescriptor databaseDescriptor, 
          final DatabaseMappingDescriptor databaseMappingDescriptor, 
          final String query) throws DatabaseException;
    
        public void executeBindQuery(final DatabaseDescriptor databaseDescriptor, 
          final DatabaseMappingDescriptor databaseMappingDescriptor, 
          final String query, final Iterator columnValues) throws DatabaseException;
    
        public Iterator executeFetchQuery(final DatabaseDescriptor databaseDescriptor, 
          final DatabaseMappingDescriptor databaseMappingDescriptor, 
          final String query) throws DatabaseException;
    
        public void executeMethod(final String methodName, 
          final Object parameters) throws DatabaseException;
    }

Database APIs

  • Create and Drop Database
  • Java
    public class Database {
        public static IDatabase createDatabase(DatabaseDesriptor) throws DatabaseException;
    }
  • Create and Drop Table
  • Create and Drop Index
  • Select
  • Java
    Native: public ISelect select() throws DatabaseException;                    
    Web: this.select() = function();
  • Save
  • Java
    Native: public final void save() throws DatabaseException;

    Example: Saving Java Object

    Java
    Liquor beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.save();
    } catch(DatabaseException de) {
        //Log it.
    }
    Java
    Web: this.save = function();

    Example: Saving JavaScript Object

    Java
    var beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.save();
    } catch(DatabaseException de) {
        //Log it.
    }
  • Update
  • Java
    Native: public final void update() throws DatabaseException;

    Exmaple: Updating Java Object

    Java
    Liquor beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.update();
    } catch(DatabaseException de) {
        //Log it.
    }
    Web: this.update = function();

    Exmaple: Updating JavaScript Object

    Java
    var beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.update();
    } catch(DatabaseException de) {
        //Log it.
    }
  • Save Or Update
  • jav
    Native: public final void saveOrUpdate() throws DatabaseException;

    Example: Save Or Update Java Object

    Java
    Liquor beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.saveOrUpdate();
    } catch(DatabaseException de) {
        //Log it.
    }
    Web: this.saveOrUpdate() = function();

    Example: Save Or Update JavaScript Object

    Java
    var beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.saveOrUpdate();
    } catch(DatabaseException de) {
        //Log it.
    }
  • Delete
  • Java
    Native: public final void delete() throws DatabaseException { }

    Example: Deleting Java Object

    Java
    Liquor beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.delete();
    } catch(DatabaseException de) {
        //Log it.
    }
    Web: this.delete() = function();

    Example: Deleting JavaScript Object

    Java
    var beer = new Liquor();
    beer.setLiquorType(Liquor.LIQUOR_TYPE_BEER);
    beer.setDescription(applicationContext.getString(R.string.beer_description));
    beer.setHistory(applicationContext.getString(R.string.beer_history));
    beer.setLink(applicationContext.getString(R.string.beer_link));
    beer.setAlcholContent(applicationContext.getString(R.string.beer_alchol_content));
    
    try {
        beer.delete();
    } catch(DatabaseException de) {
        //Log it.
    }

Aggregation APIs

  • Count
  • Java
    Native: public ICount count() throws DatabaseException;
    Web: this.count() = function();
  • Average
  • Java
    Native: public IAverage avg() throws DatabaseException;
    Web: this.avg() = function();
  • Sum
  • Java
    Native: public ISum sum() throws DatabaseException;
    Web: this.sum() = function();
  • Total
  • Java
    Native: public ITotal total() throws DatabaseException;
    Web: this.total() = function();
  • Minimum
  • Java
    Native: public IMin min() throws DatabaseException;
    Web: this.min() = function();
  • Maximum
  • Java
    Native: public IMax max() throws DatabaseException;
    Web: this.max() = function();
  • Group Concat
  • Java
    Native: public IGroupConcat groupConcat() throws DatabaseException;
    Web: this.groupConcat() = function();

Database Transaction APIs

  • Begin Transaction
  • Java
    Native: public static final void beginTransaction(
      final DatabaseDescriptor databaseDescriptor) throws DatabaseException;
    Web: this.beginTransaction = function(databaseDescriptor);
  • Commit Transaction
  • Java
    Native: public static final void commitTransaction(
      final DatabaseDescriptor databaseDescriptor) throws DatabaseException;
    Web: this.commitTransaction = function(databaseDescriptor);
  • End Transaction
  • Java
    Native: public static final void endTransaction(
      final DatabaseDescriptor databaseDescriptor) throws DatabaseException;
    Web: this.endTransaction = function(databaseDescriptor);

Database Encryption (SQLCipher)

Data Security plays important role when we talk about database. It protect your database from destructive forces and the unwanted actions of unauthorized users.

Siminov provides implementation for SQLCipher to protect application database from any unauthorized users.

Handling Libraries Based ORM

An android library project is a development project that holds shared android source code and resources. Other android application projects can reference the library project and, at build time, include its compiled sources in their .apk files.

Siminov provides mechanism to configure ORM for your library projects.

License

[SIMINOV FRAMEWORK]
Copyright [2013] [Siminov Software Solution|support@siminov.com]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Conclusion

If you are looking to bridge the object-relational impedance mismatch and increase your productivity and data access performance, you should consider the Siminov Hybrid ORM. It offers all features which you need in a ORM like Easy Configuration, Application Deployment, Multiple Schema's Supported, Events Notifer, Database APIs, Aggregation APIs, Database Transaction APIs, Database Encryption (SQLCipher), Handling Libraries Based ORM.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0