Wednesday, January 27, 2016

App Engine's Datastore


     App Engine's datastore is built on top of Bigtable. To use App Engine we need to create account using our gmail, create identifier/key for our application and finally create our application in Eclipse.
You can install Google App Engine Plugin in any Eclipse e.g. in Luna use the following URL: https://dl.google.com/eclipse/plugin/4.4

This represents all Google tools, select the App Engine tools.

To use Google datastore from inside our Java code we can use one of the following three methods:

A) Using Java Data Objects (JDO) 

JDO is a standard interface for accessing databases in Java, providing a mapping between Java classes and database tables.
Let's explore how to use JDO to access datastore:
We can follow the following simple steps:

1) Create the Entity Class(es) :
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class PersonLocation implements Serializable {
private static final long serialVersionUID = 1L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
public Long id;
@Persistent
public int personId;
@Persistent
public double lat;
@Persistent
public double lon;
@Persistent
public double accuracy;
+ settings, getters and constructors.

2) Get the persistent manager factory:

PersistenceManagerFactory pmfInstance = JDOHelper
.getPersistenceManagerFactory("transactions-optional");

3) Get PersistenceManager from the factory and use it for CRUD operations:
PersistenceManager pm = pmfInstance.getPersistenceManager();

4) Create Entity :
Create an object from the entity and persist it.
PersonLocation location = null;
try {
location=new PersonLocation();
location.setPersonId(entityId);
location.setLat(lat);
location.setLon(lon);
location.setAccuracy(accuracy);
pm.makePersistent(location);
System.out.println("id="+location.getId());
} finally {
pm.close();
}
Once the entity persistent you can get the id.

5) Get Entity:
Either use the getObjectById as in the previous methods or execute datastore query to retireve the requied data.
location = pm.getObjectById(PersonLocation.class, id);

Or use the Query object, the query retrieves all entities of the given kind that satisfy all of the given filters, sorted in the specified order.
    public List getAllLocationsForEntity(int entityId){
PersistenceManager pm = pmfInstance.getPersistenceManager();
String queryStr = "select from " + PersonLocation.class.getName();
Query selectQuery=pm.newQuery(queryStr);
selectQuery.setFilter("personId=="+entityId);
return (List) selectQuery.execute();
}

6) Update Entity: 
Get the entity, update the entity and persist the updates.
try {
pm.currentTransaction().begin();
// We do lookup for the required id
location = pm.getObjectById(PersonLocation.class, id);
location.setPersonId(entityId);
location.setLat(lat);
location.setLon(lon);
location.setAccuracy(accuracy);
pm.makePersistent(location);
pm.currentTransaction().commit();
} catch (Exception ex) {
pm.currentTransaction().rollback();
throw new RuntimeException(ex);
} finally {
pm.close();
}



7) Delete Entity: 
Get the entity and delete it.
try {
pm.currentTransaction().begin();
// We do lookup for the required id
location = pm.getObjectById(PersonLocation.class, id);
pm.deletePersistent(location);
pm.currentTransaction().commit();
} catch (Exception ex) {
pm.currentTransaction().rollback();
throw new RuntimeException(ex);
} finally {
pm.close();
}



B) Using JPA

Similarly to using JPA:
1) In persistence.xml
            org.datanucleus.api.jpa.PersistenceProviderImpl
2) Get the EntityManagerFactory:
 private static final EntityManagerFactory emfInstance =
        Persistence.createEntityManagerFactory("transactions-optional");
3) Get the EntityManager from the EntityManagerFactory:
EntityManager em = emfInstance.createEntityManager();
4) Annotate your entity:
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
    private String firstName;
    private String lastName;}
... setters, getters and constructors
 }
5) Use the entity manager to do the JPA CRUD operations. 
   

C) Using the low-level Datastore API, or one of the open-source APIs developed specifically for Datastore, such as Objectify. 

This is recommended by Google as JDO and JPA was designed for use with traditional relational databases, and so has no way to explicitly represent some of the aspects of Datastore that make it different from relational databases, such as entity groups and ancestor queries. This can lead to subtle issues that are difficult to understand and fix.
https://github.com/objectify/objectify

Sample Code:
@Entity
class Car {
    @Id String vin; // Can be Long, long, or String
    String color;
}

ofy().save().entity(new Car("123123", "red")).now();
Car c = ofy().load().type(Car.class).id("123123").now();
ofy().delete().entity(c);

No comments:

Post a Comment