Below is a simple example of how to use Space4J. Note how we use Space4J commands to modify our Space (org.space4j.Space) and how we directly access our in-memory map to list and search for User objects.
The complete source code for the PhoneBook application can be downloaded here: PhoneBook.java. Make sure the space4j.jar is in your classpath before compiling and executing.
package org.space4j.examples.phonebook;
// imports here...
public class PhoneBook {
// This would be equivalent to a table name...
protected static final String MAP_NAME = "phonenumbers";
// This is a sequence (like Oracle) used to create unique ids...
protected static final String SEQ_NAME = "phone_seq";
protected Space4J space4j = null;
// The space is where all our data is located...
protected Space space = null;
protected Map<Integer, User> users = null;
public PhoneBook(Space4J space4j) throws Exception {
this.space4j = space4j;
// Start the system...
space4j.start();
// Grab the space where all data resides...
space = space4j.getSpace();
/*
* If this is the first time, create our map that will hold our
* User objects. Space4J comes with many ready-to-use commands.
* One of them is the CreateMapCmd, that will create our initial
* empty map that to hold our objects.
*/
if (!space.check(MAP_NAME)) {
space4j.exec(new CreateMapCmd<Integer, User>(MAP_NAME));
}
/*
* Save the map reference, so that we don't have to
* get it from the Space every time.
*/
users = space.get(MAP_NAME);
/*
* If this is the first time, create the sequence for the unique ids
* using the Space4J CreateSequenceCmd.
*/
if (!space.check(SEQ_NAME)) {
space4j.exec(new CreateSequenceCmd(SEQ_NAME));
}
}
public void executeSnapshot() throws Exception {
space4j.executeSnapshot();
}
/*
* Increment the sequence and return it,
* by using the <i>IncrementSeqCmd</i> command.
*/
protected int getNextId() throws Exception {
return space4j.exec(new IncrementSeqCmd(SEQ_NAME));
}
/*
* Create a new User object and insert it in our map.
*
* We will use the <i>PutCmd</i> for doing that.
*/
public int addNumber(String first, String last, String phone, int age) throws Exception {
int id = getNextId();
User user = new User(id, first, last, phone, age);
int x = space4j.exec(new PutCmd(MAP_NAME, id, user));
if (x == 1) {
return id;
}
return -1;
}
/*
* Find an User by last name. Notice here that we are not using
* any kind of indexing, in other words, we are iterating through
* all our records to find what we want. This is equivalent to a
* full table scan in a relational database.
*/
public Collection<User> findUsers(String last) {
Collection<User> results = new LinkedList<User>();
Iterator<User> iter = space.getIterator(MAP_NAME);
while (iter.hasNext()) {
User u = iter.next();
if (u.last.indexOf(last) != -1) {
results.add(u);
}
}
return results;
}
/*
* Find a list of users between minAge and maxAge. Note
* again that we are not using any index, in other words,
* a full table scan is being performed.
*
*/
public Collection<User> findUsers(int minAge, int maxAge) {
Collection<User> results = new LinkedList<User>();
Iterator<User> iter = space.getIterator(MAP_NAME);
while (iter.hasNext()) {
User u = iter.next();
if (u.getAge() >= minAge && u.getAge() <= maxAge) {
results.add(u);
}
}
return results;
}
/*
* Remove an user by its id from our map.
*
* We will use the <i>RemoveCmd</i> command to do that.
*/
public boolean delUser(int id) throws CommandException, LoggerException {
int x = space4j.exec(new RemoveCmd(MAP_NAME, id));
return x > 0;
}
/*
* Get an iterator so that we can iterate through
* all our objects inside our map. This is equivalent
* to a <i>select * from Users</i> in a relational
* database.
*/
public Iterator<User> getUsers() {
return space.getIterator(MAP_NAME);
}
/*
* Our User object. Remember that it must be serializable.
*/
public static class User implements Serializable {
private static final long serialVersionUID = 1;
private int id;
private String first;
private String last;
private String phone;
private int age;
public User(int id, String first, String last, String phone, int age) {
this.id = id;
this.first = first;
this.last = last;
this.phone = phone;
this.age = age;
}
public String toString() {
StringBuilder sb = new StringBuilder(64);
sb.append(id).append(": ").append(first).append(" ").append(last);
sb.append(" (").append(age).append("): ").append(phone);
return sb.toString();
}
public int getId() {
return id;
}
public String getFirstName() {
return first;
}
public String getLastName() {
return last;
}
public String getPhoneNumber() {
return phone;
}
public int hashCode() {
return id;
}
public int getAge() {
return age;
}
public boolean equals(Object obj) {
if (obj instanceof User) {
User u = (User) obj;
if (u.id == this.id) {
return true;
}
}
return false;
}
}
/**
* Just some simple logic for a minimal PhoneBook application.
* NOTE: This is java code, not Space4J code!
*/
public static void run(PhoneBook book) throws Exception {
// omitted for clarity!
}
public static void main(String[] args) throws Exception {
PhoneBook book = new PhoneBook(new SimpleSpace4J("PhoneBook"));
run(book);
}
}