Showing posts with label storing objects android. Show all posts
Showing posts with label storing objects android. Show all posts

Tuesday, 8 January 2013

Using Database for Object (db4o) in android part-2

In previous post we discussed db4o benefits over relational databases and saw how we can setup and use db4o in android applications.

Today we will go little deeper in understanding the advance functionality of  db4o and its querying mechanism. QBE is easy but We need more sophisticated  mechanisms of querying in actual android applications, and that's Native Queries.

Native queries provide us absolute power of conditional querying. We can query an object by any of its fields and using all conditional operators and we can combine our quries using logical operators AND, OR, NOT. Lets start with an example. Lets say we have a  Contact class

Class Contact{
    Public String name;
    Public String number;
    Public int age;
    Public boolean member;
}

Querying based on conditions is very easy in db4o than in relational databases. We have a predicate function   in which we can write any condition which should be true. Lets see :

Find a contact where number= 1234


ObjectSet<Contact> result = db.query(new Predicate<Contact>() {
public boolean match(Contact conObj) {
return (conObj.number.equal("1234"));
}
});

find a contact where age=20


ObjectSet<Contact> result = db.query(new Predicate<Contact>() {
public boolean match(Contact conObj) {
return (conObj.age==20);
}
});

to get all objects of type Contact

ObjectSet<Contact> result = db.query(new Predicate<Contact>() {
public boolean match(Contact conObj) {
return true;
}
});



Note that we are using db.query instead of db.QBE. db.query return us one or more matching objects in result which Contact type object set. We can iterate result to get objetcs. We can write any expression in match function which should be true when querying objects.

To retrieve found objects, check the result returned by db.query

if(result.hasNext()) // if result is not empty
   Contact obj= result.Next();


and if you want to return all objects returned by query

ArrayList<Contact> list=new ArrayList<Contact>();

while(result.hasNext()){
  list.add(result.Next());
}


that's it about native queries. There are some other interesting things like indexing for  fast querying and dealing with objects containing other objects. You are encouraged to read about them in db4o reference document and tutorial.

Thursday, 13 September 2012

Using database for objects (db4o) in android part-1

Mapping object paradigm to relational paradigm is very hectic job for programmer and intensive for processor. As mobile development move to object oriented paradigm, we need object based database where we can directly store/retrieve/update and delete objects without first converting them to relational table entities.

Fortunately we have db4o, which was released just after first release of android. db4o is database for objects. when we say "objects" this means objects are not converted to relational tables at any stage (neither by programmer nor by framework). db4o is fast, has small footprint and low processing overhead. You can read about performance comparison with other mobile databases  here.

In this post I'll explain:
  1. How to setup db4o to use in android project using eclipse. and
  2. How to perform CRUD operations on simple objects.

In order to setup db4o for your project, download latest version db4o library, extract the zip and put db4o-all.jar in your lib folder and update java build path.


Lets say we have custom class, Contact.java:

public class Contact {

    private String name;

    private String number;

    int age;

    boolean member;

    public Contact() {

        // default constructor

        name = null;

        number = null;

        age = 0;

        member = false;

    }

    public Contact(String name, String number, int age, boolean member) {

        this.name = name;

        this.number = number;

        this.age = age;

        this.member = member;

    }

    public String getNumber() {

        return number;

    }

    public void setNumber(String number) {

        this.number = number;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public boolean isMember() {

        return member;

    }

    public void setMember(boolean member) {

        this.member = member;

    }


    public void setName(String name) {

        this.name = name;

    }


    public String getName() {

        return name;

    }


    public String toString() {


        return name + "/" + number + "/" + Integer.toString(age) + "/"

                + Boolean.toString(member);

    }


}



Now lets start working with db40, first open the database:

ObjectContainer db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), DATABASE_PATH);



ObjectContainer is the db4o type which hold the database reference. We will use this reference to call all db4o methods for CRUD. There various options we can set using configuration, for the time being lets just use the default configuration Db4oEmbedded.newConfiguration().

Once database is open, we can store, retrieve update and delete objects:
  • Inserting objects:
    • store(Object o) method of ObjectContainer is used to insert new objects in database. e.g
           
 Contact con= new Contact("sohail", "111", 10, true);
 db.store(con);
 db.commit();
         

  • Querying objects:
    • There are two methods we can use to retrieve stored objects, these are: 
      • queryByExample(Object o) and
      • native query
In this tutorial, I'll use queryByExample which is simple and understand  for  beginners.

queryByExample takes and object and retrieve object/s similar to object supplied in arguments. In order to get all objects, we need to pass a dummy object whose all fields are set to null/0.

For example to get all objects where age=10,

 

Contact c=new Contact(null,null,10,true);

ObjectSet list=db.queryByExample(c);

this will return a list of all objects where age=10.

To fetch all objects of type Contact:

Contact t= new Contact();

ObjectSet list= db.queryByExample(t);



this will return all the objects of type Contact, Note that default constructor initializing all the fields to null and zeros. This is necessary to fetch all object. ObjectSet is db4o type which can be think of list of objects.


  • Updating objects:
    • In order to update an object, we need to first query that object and then we can update it using store method. e.g to update object where name= sohail
 

Object q=new Object();

q.setName("sohail);

ObjectSet result= db.queryByExample(q);



if(result.hasNext())

{

    Contact c= (Contact) result.next();

    //update age,number

    c.setAge(33);

   c.setNumber("444444444"); 

  db.store(c);



}

 

what we are doing here is to find the object where name=sohail, if found (result.hasNext) then update it.

  • Deleting Objects:
    • like updating, in order to delete objects we need to first query that object and bring it into memory, then we can use delete() method to delete.e.g deleting object where contact name=sohail
 

Contact n=new Contact();

n.setName("sohail");

ObjectSet result= db.queryByExample(n);



if(result.hasNext())

{

     Contact d=(Contact) result.next(); 

     db.delete(d);

}


Thats all. QueryByExample is simple however it has some limitations, we will discuss native queries in next tutorial which use the semantic of programming language, give more control and are recommended.


Full source:
package sohail.aziz.db4oexample;
import java.util.ArrayList;
import android.util.Log;
import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;

public class DbHelperQBE {

    String dbpath;
    ObjectContainer db;

    boolean OpenDb(String name) {

        if (name != null) {

            db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), name);

            return true;

        }

        return false;

    }


    void CloseDb() {

        db.close();

    }

    void emptyDb(){
   
        ObjectSet result= db.queryByExample(new Object());
    
        while(result.hasNext()){

               db.delete(result.next());   

        }
     

    }


    void StoreContact(Contact con) {

        db.store(con);

        db.commit();

        Log.d("sohail", "object stored");

    }

    Contact getContactByName(String name) {

       // define

        Contact obj = new Contact();

        obj.setName(name);

        ObjectSet result = db.queryByExample(obj);


        if (result.hasNext()) {

            return (Contact) result.next();

        }

        return null;

    }

    Contact getContact(Contact con) {

        ObjectSet result = db.queryByExample(con);


        if (result.hasNext()) {

            return (Contact) result.next();

        } else

            return null;

    }


    ArrayList<Contact> getAllContacts() {


        ArrayList<Contact> list = new ArrayList<Contact>();

        Contact proto = new Contact();

        ObjectSet<Contact> result = db.queryByExample(proto);


        while (result.hasNext()) {

            list.add(result.next());

        }

        return list;

    }

    boolean updateObject(Contact ObjTo, Contact ObjFrom) {



        Contact found = null;

        ObjectSet<Contact> result = db.queryByExample(ObjTo);

        if (result.hasNext()) { // if found

            found = result.next();

            found.setAge(ObjFrom.getAge()); // shallow copy just replay to, to From.

            found.setMember(ObjFrom.isMember());

            found.setName(ObjFrom.getName());

            found.setNumber(ObjFrom.getNumber());

            db.store(found);

            db.commit();

            return true;

        }

        return false;

    }

    boolean deleteObject(Contact p) {

        Contact found = null;
        ObjectSet<Contact> result = db.queryByExample(p);

        if (result.hasNext()) {

            found = result.next();
            db.delete(found);

            return true;

        } else {

            return false;

        }

    }

}