Monday, September 5, 2011

The Play Framework - Part 2 - Database

The Play Framework is a MVC web application framework for Java that focuses on being light-weight and easy to use--two qualities that you don't see very often in the Java web application world.


To connect your application to a database, modify the "db.*" settings in the "conf/application.conf" file. To get up and running quickly, uncomment the "db=mem" line to create an in-memory database (all changes will be lost, of course, when the application ends).

To save data to the database, start by creating entity classes inside the "model" package. An entity class is a plain Java bean class that has JPA (Java Persistence Architecture) annotations. Each entity class represents a table in the database, each instance of the class represents a row in the table, and each field in the instance represents a column in the row (getter and setter methods aren't needed for the fields--Play generates them automatically). By default, the table name is the same as the class name. To change the table name, use the @Table annotation.

Each entity class can also optionally extend Play's Model class, which gives it access to utility methods for saving and retrieving data. For example, to insert a new row into the table, simply create a new instance of the class and call the save() method:

User user = new User("Bob", "bob@gmail.com");
user.save();

To retrieve data, call the static find() method:

List<User> users = User.find("byNameAndEmail", "Bob", "bob@gmail.com").fetch();

You don't need to write any SQL code to interact with the database. Play uses Hibernate for its persistence layer, so HQL (Hibernate Query Language) can be used for more complex queries.

The Model class also automatically generates an "id" primary key column for you (something that every table should have). So basically, you should always extend this class.

Here's an example of an entity class. It represents a blog post:

package models;
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;

@Entity
@Table(name="blog_posts")
public class Post extends Model {
  public String title;
  public Date postedAt;

  @Lob
  //large amount of text
  public String content;

  @ManyToOne
  //many Posts can belong to one User
  public User author;

  //a list of all comments that belong to this post
  //(the comments are in a separate table)
  //CascadeType.ALL = the post's comments will be automatically deleted when the post is deleted
  @OneToMany(mappedBy="post", cascade=CascadeType.ALL)
  public List<Comment> comments;

  public Post(User author, String title, String content) {
    comments = new ArrayList<Comment>();
    this.author = author;
    this.title = title;
    this.content = content;
    postedAt = new Date();
  }

  public Post addComment(String author, String content){
    Comment newComment = new Comment(this, author, content).save();
    comments.add(newComment);
    save();
    return this;
  }
}

The Fixtures class provides more utility methods for interacting with the database. For example, to delete the entire database, call the deleteDatabase() method. It can also execute SQL code contained in a file or persist the data in a specially-formatted YAML file (YAML is a new standard for representing structured data. Its aim is to provide a better alternative to XML).

No comments: