Over a million developers have joined DZone.

Integrating Play 2.1 with Slick 1.0.0 Database Query DSL

· Java Zone

Discover how AppDynamics steps in to upgrade your performance game and prevent your enterprise from these top 10 Java performance problems, brought to you in partnership with AppDynamics.

For people in hurry here is the code and the steps to setup.

Refer this blog on Play 2.0: Building Web Application using Scala for details on Play and Scala.

In the next few blogs I will be writing enterprise class web application using Play and Scala. I will be covering topics like Database modelling and Security. Now officially Scala has adopted Slick as the Database query DSL. But when you create a new Play application and add Slick library as mentioned in this blog, it is not working. It gives a strange error like No suitable driver found in tests.

I also found slick-play2-example, this sample expect us to create a DAL layer, but we cannot directly play with slick in our test code.

After much further research I came across this plugin. I tried integrating this with my Play application and it worked like a charm.

We will define a Coffee class and a Supplier class. One Coffee has multiple Suppliers. The class design is as below,

case class Coffee(name: String, supID: Int, price: Double, sales: Int, total: Int)

object Coffees extends Table[Coffee]("COFFEES") {
def name = column[String]("COF_NAME", O.PrimaryKey)
def supID = column[Int]("SUP_ID")
def price = column[Double]("PRICE")
def sales = column[Int]("SALES")
def total = column[Int]("TOTAL")
def * = name ~ supID ~ price ~ sales ~ total <> (Coffee.apply _, Coffee.unapply _)
// A reified foreign key relation that can be navigated to create a join
def supplier = foreignKey("SUP_FK", supID, Suppliers)(_.id)
}

case class Supplier(id: Int, name: String, street: String, city: String, state: String, zip: String)

// Definition of the SUPPLIERS table
object Suppliers extends Table[Supplier]("SUPPLIERS") {
def id = column[Int]("SUP_ID", O.PrimaryKey) // This is the primary key column
def name = column[String]("SUP_NAME")
def street = column[String]("STREET")
def city = column[String]("CITY")
def state = column[String]("STATE")
def zip = column[String]("<a class="zem_slink" title="ZIP (file format)" href="http://en.wikipedia.org/wiki/ZIP_%28file_format%29" target="_blank" rel="wikipedia">ZIP</a>")
// Every table needs a * projection with the same type as the table's type parameter
def * = id ~ name ~ street ~ city ~ state ~ zip <> (Supplier.apply _, Supplier.unapply _)
}

Below is the ScalaTest to test various capabilities of Slick,

DB.withSession{ implicit session =>

//Populate sample data
val testSuppliers = Seq(
Supplier(101, "Acme, Inc.",      "99 Market Street", "Groundsville", "CA", "95199"),
Supplier( 49, "Superior Coffee", "1 Party Place",    "Mendocino",    "CA", "95460"),
Supplier(150, "The High Ground", "100 Coffee Lane",  "Meadows",      "CA", "93966")
)
Suppliers.insertAll( testSuppliers: _*)

val testCoffees= Seq(
Coffee("Colombian",         101, 7.99, 0, 0),
Coffee("French_Roast",       49, 8.99, 0, 0),
Coffee("Espresso",          150, 9.99, 0, 0),
Coffee("Colombian_Decaf",   101, 8.99, 0, 0),
Coffee("French_Roast_Decaf", 49, 9.99, 0, 0)
)
Coffees.insertAll( testCoffees: _*)

//Assert coffee data equals to the test list of coffee
Query(Coffees).list must equalTo(testCoffees)

//List all coffee less than $10
val q1 = for { c <- Coffees if c.price < 10.0 } yield (c.name)

q1 foreach println
println("**************");

//return all suppliers for coffee less than $9.0
val q2 = for { c <- Coffees if c.price < 9.0
s <- c.supplier } yield (c.name, s.name)

q2 foreach println
println("**************");

//return all suppliers for coffee using zip
val q3 = for {
(c, s) <- Coffees zip Suppliers
} yield (c.name, s.name)

q3 foreach println
println("**************");

//Union
val q4 = Query(Coffees).filter(_.price < 8.0)
val q5 = Query(Coffees).filter(_.price > 9.0)
val unionQuery = q4 union q5
unionQuery foreach println
println("**************");

//Union second approach
val unionAllQuery = q4 unionAll q5
unionAllQuery foreach println
println("**************");

//Group by
val r = (for {
c <- Coffees
s <- c.supplier
} yield (c, s)).groupBy(_._1.supID)

//Aggregation
val r1 = r.map { case (supID, css) =>
(supID, css.length, css.map(_._1.price).avg)
}

r1 foreach println
}

In my next blog, I will take a real example and implement using Slick. I hope this blog helped.


 

The Java Zone is brought to you in partnership with AppDynamics. AppDynamics helps you gain the fundamentals behind application performance, and implement best practices so you can proactively analyze and act on performance problems as they arise, and more specifically with your Java applications. Start a Free Trial.

Topics:

Published at DZone with permission of Krishna Prasad , DZone MVB .

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}