GAE Datastore using Native Low Level DataStore API (in Java)
Clearing the Datastore on LocalHost ---running on LocalHostThe development web server uses a local version of the Datastore for testing your application, using local files. The data persists as long as the temporary files exist, and the web server does not reset these files unless you ask it to do so. The file is named local_db.bin, and it is created in your application's WAR directory, in the WEB-INF/appengine-generated/ directory. To clear the Datastore, delete this file. |
|
How to get DataStore and put Entity in itSTEP 1: Create instance of DataStore (ds) for this application
|
|
How to get stored data (use Query and datastore.prepare(query)Query query = new Query("Greeting", guestbookKey).addSort("date", Query.SortDirection.DESCENDING);
see the Datastore reference.
|
|
GAE Datastore Indexes
Our guest book example below, which filters results by ancestor and orders by date, uses an ancestor query and a sort order.
|
Example 1 -- Book database -- ONLY storage of book Entity
(remember you can also access with higher level API like JPA and JDO)
package booklowlevel;
import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.SimpleTimeZone; import javax.servlet.http.*; import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.DatastoreServiceFactory; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.KeyFactory;
@SuppressWarnings("serial") public class GAE_booklowlevelServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp)throws IOException { resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS"); //STEP 1: Create Datastoreservice
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
//STEP 2: Create Entity Entity book = new Entity("Book"); //STEP 3: setup properties of Entity
book.setProperty("title", "The Grapes of Wrath"); book.setProperty("author", "John Steinbeck"); book.setProperty("copyrightYear", 1939); Date authorBirthdate = new GregorianCalendar(1902, Calendar.FEBRUARY, 27).getTime(); book.setProperty("authorBirthdate", authorBirthdate); //STEP 4: put Entity in DataStore
ds.put(book);
out.println("<p>Added a Book entity to the datastore via the low-level API, key: " + KeyFactory.keyToString(book.getKey()) + "</p>");
fmt.setTimeZone(new SimpleTimeZone(0, "")); out.println("<p>The time is: " + fmt.format(new Date()) + "</p>"); } }
result of running above code (locally)
Example 2 --- Guestbook DataStore storage(user,date,content) AND retrieval
package guestbook;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SignGuestbookServlet extends HttpServlet {
private static final Logger log =
Logger.getLogger(SignGuestbookServlet.class.getName());
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
// We have one entity group per Guestbook with all Greetings residing
// in the same entity group as the Guestbook to which they belong.
// This lets us run an ancestor query to retrieve all Greetings for a
// given Guestbook. However, the write rate to each Guestbook should be
// limited to ~1/second.
String guestbookName = req.getParameter("guestbookName");
Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
String content = req.getParameter("content");
Date date = new Date(); //STEP 2&3: create Entity and set properties
Entity greeting = new Entity("Greeting", guestbookKey);
greeting.setProperty("user", user); //storing for Greeting Entity - user,date,content --user passed by authentication,
greeting.setProperty("date", date); //date is generated above
greeting.setProperty("content", content); //content is from request data
//STEP 1: get DataStore
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); //STEP 4: put Entity in DataStore
datastore.put(greeting);
resp.sendRedirect("/guestbook.jsp?guestbookName=" + guestbookName);
}
}
guestbook.jsp contains how to get stored data ALSO contains form that will call servlet passing date and content info
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>
<%@ page import="com.google.appengine.api.datastore.DatastoreServiceFactory" %>
<%@ page import="com.google.appengine.api.datastore.DatastoreService" %>
<%@ page import="com.google.appengine.api.datastore.Query" %>
<%@ page import="com.google.appengine.api.datastore.Entity" %>
<%@ page import="com.google.appengine.api.datastore.FetchOptions" %>
<%@ page import="com.google.appengine.api.datastore.Key" %>
<%@ page import="com.google.appengine.api.datastore.KeyFactory" %>
<html>
<head>
<link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
</head>
<body>
<%
String guestbookName = request.getParameter("guestbookName");
if (guestbookName == null) {
guestbookName = "default";
}
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
} else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
}
%>
<%
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
// Run an ancestor query to ensure we see the most up-to-date
// view of the Greetings belonging to the selected Guestbook.
Query query = new Query("Greeting", guestbookKey).addSort("date", Query.SortDirection.DESCENDING);
List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));
if (greetings.isEmpty()) {
%>
<p>Guestbook '<%= guestbookName %>' has no messages.</p>
<%
} else {
%>
<p>Messages in Guestbook '<%= guestbookName %>'.</p>
<%
for (Entity greeting : greetings) {
if (greeting.getProperty("user") == null) {
%>
<p>An anonymous person wrote:</p>
<%
} else {
%>
<p><b><%= ((User) greeting.getProperty("user")).getNickname() %></b> wrote:</p>
<%
}
%>
<blockquote><%= greeting.getProperty("content") %></blockquote>
<%
}
}
%>
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Post Greeting" /></div>
<input type="hidden" name="guestbookName" value="<%= guestbookName %>"/>
</form>
</body>
</html>