play2-crud
simple CRUD & DAO implementation with REST interface for play framework 2.0 and 2.1
Sample
Here is a full featured sample.
HOW-TO
This HOW-TO has been separated into several sections:
HOW-TO use simple CRUD
Follow these steps to use play2-crud. You can also use it partially just for DAO or CRUD controllers. If you think any part needs further explanation, please report a new issue.
Define model
- Model class have to implement
play.utils.dao.BasicModel
with the type parameter indicating the type of the@Id
field.
@Entity
public class Sample extends Model implements BasicModel<Long> {
@Id
private Long key;
@Basic
@Required
private String name;
public Long getKey() {
return key;
}
public void setKey(Long key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- Here the
Sample
model class implementsBasicModel<Long>
wherekey
field indicated with@Id
isLong
.
Define DAO
- DAO class extends
play.utils.dao.BasicDAO
with two type parameters: One for the key type and one for the Model type - Alternatively,
play.utils.dao.CachedDAO
cn be used to cache fetched data. - Classes implementing both
BasicDAO
orCachedDAO
should override the constructor with key ad model class type parameters.
public class SampleDAO extends BasicDAO<Long, Sample> {
public SampleDAO() {
super(Long.class, Sample.class);
}
}
- Here the
SampleDAO
extendsBasicDAO<Long, Sample>
withLong
key type, andSample
model type - and overrides the super class constructor with
super(Long.class, Sample.class)
Define Controller
- Controller classes extend
play.utils.crud.CRUDController
with key and model type parameters as in DAO classes. - Controllers should override the constructor by providing
- DAO implementation
- A Form class
- Key type
- Model type
- Page size (used for paging lists)
- Sorting field as string (might be in the form of
"fieldName [asc]/[desc]"
)
- Template file name prefixes for List/Form and Show pages
- A Call to the index page, indicating the call to return after CRUD operations
import static play.data.Form.*;
import play.mvc.Call;
public class SampleController extends CRUDController<Long, Sample> {
public SampleController(SampleDAO dao) {
super(dao, form(Sample.class), Long.class, Sample.class, 10, "name");
}
protected String templateForList() {
return "sampleList";
}
protected String templateForForm() {
return "sampleForm";
}
protected String templateForShow() {
return "sampleShow";
}
@Override
protected Call toIndex() {
return routes.Application.sampleList();
}
}
Associate Controller
public class Application extends Controller {
private static SampleDAO sampleDAO = new SampleDAO();
private static SampleController sampleController = new SampleController(sampleDAO);
public static Result index() {
return ok(views.html.index.render());
}
public static Result sampleList() {
return sampleController.listAll();
}
public static Result sampleNewForm() {
return sampleController.newForm();
}
public static Result sampleCreate() {
return sampleController.create();
}
public static Result sampleEditForm(Long key) {
return sampleController.editForm(key);
}
public static Result sampleUpdate(Long key) {
return sampleController.update(key);
}
public static Result sampleDelete(Long key) {
return sampleController.delete(key);
}
public static Result sampleShow(Long key) {
return sampleController.show(key);
}
}
define routes
# Home page
GET / controllers.Application.index()
# productScrap CRUD
GET /sample controllers.Application.sampleList()
POST /sample controllers.Application.sampleCreate()
GET /sample/new controllers.Application.sampleNewForm()
GET /sample/:key/edit controllers.Application.sampleEditForm(key: Long)
POST /sample/:key/update controllers.Application.sampleUpdate(key: Long)
GET /sample/:key/delete controllers.Application.sampleDelete(key: Long)
GET /sample/:key controllers.Application.sampleShow(key: Long)
define templates
... and voila!
HOW-TO use DAO Listeners
This part introduces how to use DAO listeners
Additions to the model
- Define an additional attribute in your Model, which will be updated by the listener.
- Let's define a new
int randomValue
field, that will be randomly updated on creation and when the model is updated.
- Let's define a new
public class Sample extends Model implements BasicModel<Long> {
...
@Basic
private int randomValue;
...
public int getRandomValue() {
return randomValue;
}
public void setRandomValue(int randomValue) {
this.randomValue = randomValue;
}
...
DAOListener
Create a new - Create a
DAOListener
that updates therandomValue
field before create and update operations:
public class SampleDAOListener implements DAOListener<Long, Sample> {
Random random = new Random();
@Override
public void beforeCreate(Sample m) {
m.setRandomValue(random.nextInt());
}
@Override
public void beforeUpdate(Sample m) {
m.setRandomValue(random.nextInt());
}
@Override
public void afterCreate(Long key, Sample m) {
}
@Override
public void afterRemove(Long key, Sample m) {
}
@Override
public void afterUpdate(Sample m) {
}
@Override
public void beforeRemove(Long key) {
}
}
DAOListener
to the DAO
Register the - Add the
SampleDAOListener
inSampleDAO
constructor:
public SampleDAO() {
super(Long.class, Sample.class);
addListener(new SampleDAOListener());
}
Make changes in your templates
- Make some changes (e.g. list template) if you want to display the new field in the templates.
HOW-TO use REST Controllers
This part introduces how to use DAO listeners
Define a REST controller
- Define a REST controller extending
APIController
- The REST controller has to implement the create() method for creating the entity.
- There are several helper methods like
checkRequired
andjsonText
that can be used in the REST controller.
import static play.libs.Json.toJson;
import com.google.common.collect.ImmutableMap;
import models.Sample;
import models.dao.SampleDAO;
import play.mvc.Result;
import play.utils.crud.APIController;
public class SampleRestController extends APIController<Long, Sample> {
public SampleRestController(SampleDAO dao) {
super(dao);
}
@Override
public Result create() {
Result check = checkRequired("name");
if (check != null) {
if (log.isDebugEnabled())
log.debug("check : " + check);
return check;
}
String name = jsonText("name");
Sample m = new Sample();
m.setName(name);
Long key = dao.create(m);
if (log.isDebugEnabled())
log.debug("key : " + key);
return created(toJson(ImmutableMap.of("status", "OK", "key", key)));
}
}
Associate REST Controller
- Associate in the existing Application Controller
public class Application extends Controller {
...
private static SampleRestController restController = new SampleRestController(sampleDAO);
...
public static Result restList() {
return restController.list();
}
public static Result restCreate() {
return restController.create();
}
public static Result restUpdate(Long key) {
return restController.update(key);
}
public static Result restDelete(Long key) {
return restController.delete(key);
}
public static Result restGet(Long key) {
return restController.get(key);
}
}
define routes
...
# REST API
GET /api/sample controllers.Application.restList()
GET /api/sample/:key controllers.Application.restGet(key:Long)
PUT /api/sample/:key controllers.Application.restUpdate(key:Long)
POST /api/report/ controllers.Application.restCreate()
DELETE /api/sample/:key controllers.Application.restDelete(key:Long)