Anorm ist ein in Play2 enthaltenes Data Access Layer, mit dessen Hilfe sich schnell Models erstellen lassen. Für die Abfragen auf die Datenbank wird im Gegensatz zu anderen Ansätzen Plain SQL verwendet. Die Gründe hierfür möchten wir direkt aus der Play Dokumentation zitieren:
– Using JDBC is a pain, but we provide a better API
– You don’t need another DSL to access relational databases
– A type safe DSL to generate SQL is a mistake
– Take Control of your SQL code
http://www.playframework.com/
Die Funktionen Json.format, reads und writes dienen dazu, die Objekte des Models (hier ein einfacher User) mit dem in Play vorhandene Json Parser umzuwandeln. Für einige Datentypen wie zum Beispiel einen Anorm-Primärschlüssel muss ein impliziter Formatter implementiert werden. Siehe hierzu den Beitrag Play Framework 2 – Anorm PK Format.
package models import play.api.db._ import play.api.Play.current import play.api.libs.json._ import anorm._ import anorm.SqlParser._ import java.util.Date case class User(id: Pk[Long] = NotAssigned, username: String, email: String)
object User { implicit val userFormatter = Json.format[User] implicit val userReads = Json.reads[User] implicit val userWrites = Json.writes[User] val simple = { get[Pk[Long]]("id") ~ get[String]("username") ~ get[String]("email") map { case id ~ username ~ email => User( id, username, email) } } /* hic sunt CRUD methods */ }
Einmal CRUD, bitte
User anlegen.
def create(user: User): Option[Long] = { DB.withTransaction { implicit connection => SQL("insert into \"user\" (username, email) values ({username}, {email})") .on('username -> user.username, 'email -> user.email) .executeInsert() } }
User auslesen.
def findById(id: Long): Option[User] = { DB.withConnection { implicit connection => SQL("select * from \"user\" where id = {id}") .on('id -> id) .as(User.simple.singleOpt) } }
User aktualisieren.
def update(id: Long, user: User): Int = { DB.withConnection { implicit connection => SQL("update \"user\" set username = {username}, email = {email} where id = {id}") .on('username -> user.username, 'email -> user.email) .executeUpdate() } }
User löschen.
def delete(id: Long): Int = { DB.withConnection { implicit connection => SQL("delete from \"user\" where id = {id}") .on('id -> id) .executeUpdate() } }
Fertig!
Der Vollständigkeit halber noch die Liste aller im System existierenden User.
def list(): Seq[User] = { DB.withConnection { implicit connection => SQL("select * from \"user\"") .as(User.simple *) } }