Thursday, June 25, 2009

Using Java Data Storage in Google App Engine

The App Engine datastore stores and performs queries over data objects, known as entities.

Entity is an basic unit of storage ,It consists of four main components

  1. Kind--(Table)
  2. Key--(Primary Key)
  3. Entity group--(Partition)
  4. 0..N typed properties--(columns)

An sample data is as shown below

KindBrand
Key/Brand:Toyota
Entity Group/Brand:Toyota
Rankint64:1
Countrystring:Japan

The Datastore is

  • Transactional
  • Natively Partitioned
  • Hierarchial
  • Schema less
  • Based on Big Table
  • Not a relational database
  • Not a SQL engine

JDO or JPA is transparent persistent frameworks which java app engine supports.

To use JDO to access the datastore, an App Engine app needs the following:

  1. The JDO and DataNucleus App Engine plugin JARs must be in the app's war/WEB-INF/lib/ directory.
  2. A configuration file named jdoconfig.xml must be in the app's war/WEB-INF/classes/META-INF/ directory, with configuration that tells JDO to use the App Engine datastore.
  3. The project's build process must perform a post-compilation "enhancement" step on the compiled data classes to associate them with the JDO implementation.

All the above 3 steps are taken care when we use google plugin for eclipse .

Lets develop an sample application to add ,modify ,delete from datastorage using JDO.

Create an java persistance class for above "brand" example as shown below

package com.tutorials;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Brand {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Long id;
 @Persistent
 private String name;
 @Persistent
 private String country;
 @Persistent
 private int rank;
 public String getCountry() {
  return country;
 }
 public void setCountry(String country) {
  this.country = country;
 }
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public void setRank(int rank) {
  this.rank = rank;
 }
 public int getRank() {
  return rank;
 }
}
Its just POJO class with couple of annotations

@PersistenceCapable annotation is used to declare java class capable of being stored and retrieved from the datastore with JDO.

@Persistent annotation is used to declare a field as persistance.

@PrimaryKey annotation is used to specify column as primary key .

@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)is specified to automatically generate the id for long primary key.

An app interacts with JDO using an instance of the PersistenceManager class. You get this instance by instantiating and calling a method on an instance of the PersistenceManagerFactory class as shown below

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {
    private static final PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");
    private PMF() {}
    public static PersistenceManagerFactory get() {
        return pmfInstance;
    }
}
The main servlet code as show below .
package com.tutorials;

import java.io.IOException;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.servlet.http.*;
import javax.servlet.*;
import com.tutorials.PMF;
import com.tutorials.Brand;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@SuppressWarnings("serial")
public class DataStorage extends HttpServlet  {
 public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws ServletException ,IOException {
// create the persistence manager instance
PersistenceManager pm = PMF.get().getPersistenceManager();
if(req.getParameter("action").equals("brandCreate")) {
    resp.sendRedirect("/brandCreate.jsp");
}else
if(req.getParameter("action").equalsIgnoreCase("brandCreateDo"))
{
 Brand br = new Brand();
 br.setCountry(req.getParameter("country"));
 br.setName(req.getParameter("name"));
 br.setRank(new Integer(req.getParameter("rank")).intValue());
 // persist the entity
    try {
        pm.makePersistent(br);
    } finally {
        pm.close();
    }
    resp.sendRedirect("datastorage?action=brandList");
}else if (req.getParameter("action").equalsIgnoreCase("brandDisplay")){
 Key k = KeyFactory.createKey(Brand.class.getSimpleName(), new Integer(req.getParameter("brandId")).intValue());
 Brand brandDetails = pm.getObjectById(Brand.class, k);
 req.setAttribute("brandDetails", brandDetails);
 RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/brandDisplay.jsp");
 dispatcher.forward(req, resp);

}else if (req.getParameter("action").equalsIgnoreCase("brandList")){
 String query = "select from " + Brand.class.getName() ;
 List brandList = (List) pm.newQuery(query).execute();
 req.setAttribute("brandList", brandList);
 RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/brandList.jsp");
 dispatcher.forward(req, resp);

}else if (req.getParameter("action").equalsIgnoreCase("brandDelete")){
 Brand brandDetails = pm.getObjectById(Brand.class, new Integer(req.getParameter("brandId")).intValue());

  try {
         pm.deletePersistent(brandDetails);
   } finally {
         pm.close();
  }
    resp.sendRedirect("datastorage?action=brandList");
}
 }
}

You can download the whole source code at this url http://www.mediafire.com/?sharekey=0ce17dac893e449b7f7ec40ada4772a620fefd7da6dfe170c95965eaa7bc68bc

No comments:

Post a Comment