In addition to Paul Draper's excellent answer, this post is meant to tell you about what Play developers usually do in practice.
TL;DR: use Slick
Play is less opinionated than Rails and gives the user many more choices for their data storage backend. Many people use Play as a web layer for very complex existing backend systems. Many people use Play with a NoSQL storage backend (e.g. MongoDB). Then there's also people using Play for traditional web-service-with-SQL applications. Generalizing a bit too much, one can recognize two people using Play with relational databases.
"Traditional web developers"
They are used to standard Java technologies or are part of an organization that uses them. The Java Persistence API and its implementations (Hibernate, EclipseLink, etc...) are their ORM. You can do so too. There are also appear to be Scala ORMs, but I'm less familiar with those.
Note that Java/Scala ORMs are still different ORMs in style when compared to Rails' ActiveRecord. Ruby is a dynamic language that allows/promotes loads of monkey patching and method_missing
stuff, so there is MyObject.finder_that_I_didnt_necessarily_have_to_write_myself()
. This style of ORM is called the active record pattern. This style is impossible to accomplish in pure Java and discouraged in Scala (as it violates type safety), so you have to get used to writing a more traditional style using service layers and data access objects.
"Scala web developers"
Many Scala people think that ORMs are a bad abstraction for database access. They also agree that using raw SQL is a bad idea, and that an abstraction is still in order. Luckily Scala is an expressive compiled language, and people have found a way to abstract database access that does not rely on the object oriented language paradigm as ORMs do, but mostly on the functional language paradigm. This is quite a similar idea to the LINQ query language Microsoft has made for their .NET framework languages. The core idea is that you don't have an ORM to perform query magic, nor write queries in SQL, but write them in Scala itself. The advantages of this approach are twofold:
- You get a more fine grained control over what your queries actually execute when compared to ORMs.
- Queries are checked for validity by the Scala compiler, so you don't get runtime errors for invalid SQL you wrote yourself. If it is valid Scala, it is translated to a valid SQL statement for you.
Two major libraries exist for accomplishing this. The first is Squeryl. The second is Slick. Slick appears to be the most popular one, and there are some examples floating around the web that show how you are supposed to make it work with Play. Also check out this video that serves as an introduction to Slick and which compares it to the ORM approach.