2010-09-28

Querying with Scala

Scala support for Querydsl has been on the roadmap for some time, and with the Querydsl 2.0 release we got initial support for using Querydsl in Scala applications released.

The goal was to use the Query interfaces as such, and to provide an alternative expression DSL better suited for Scala usage. With most Querydsl modules APT is used for code generation. As there is no equivalent for Scala we didn't try to provide code generation features for Scala domain models.

Instead we combined the Alias-feature of the Querydsl Core module with the Scala expression DSL. The result is in our opinion quite compact and readable.

For the moment Querydsl with Scala can be used with JPA, JDO and Mongodb. To get started, you will need the additional querydsl-scala dependency in your project in addition to the dependencies for your Querydsl backend support. Querydsl for Scala has been tested against Scala 2.8.0.

Using Maven you would need to declare the following additional dependency :

<dependency>
      <groupId>com.mysema.querydsl</groupId>
      <artifactId>querydsl-scala</artifactId>
      <version>${querydsl.version}</version>
</dependency>

Here is a minimal example with JPA/Hibernate :

Domain model :

@Entity
class User {
  @BeanProperty
  @Id
  var id: Integer = _;
  @BeanProperty
  var userName: String = _;
  @BeanProperty
  @ManyToOne
  var department: Department = _;
}

@Entity
class Department {
  @BeanProperty
  @Id
  var id: Integer = _;
  @BeanProperty
  var name: String = _;
}

And here are some query examples

import com.mysema.query.scala.Conversions._
import com.mysema.query.jpa.impl.JPAQuery

import com.mysema.query.types.path._
import org.junit.Test

class JPAQueryTest {

  val person = alias(classOf[Person])

  @Test
  def Various() {
    // list
    query from person where (person.firstName $like "Rob%") 
      .list person

    // unique result
    query from person where (person.firstName $like "Rob%") 
      .unique person

    // long where
    query from person 
      .where (person.firstName $like "Rob%", person.lastName $like "An%") 
      .list person

    // order
    query from person orderBy (person.firstName asc) list person

    // not null 
    query from person 
      .where (person.firstName $isEmpty, person.lastName $isNotNull) 
      .list person
  }

  def query() = new JPAQuery(entityManager)

}

The main import for Querydsl Scala integration is the following

import com.mysema.query.scala.Conversions._

The factory method for query creation is

def query() = new JPAQuery(entityManager)

In addition to queries you need variables which can be created like this

var person = alias(classOf[Person])

The person variable is a proxy instance of the the Person class which can be used in queries. Now you can construct your queries, populate them via from-where-...-orderBy calls and get the projection out via list/uniqueResult/listResults calls.

Querydsl expressions are constructed via method calls starting with the "$" sign.

With the Querydsl Java API a simple like expression would be constructed like this :

person.firstName.like("Rob%")

Using the Scala API it is

person.firstName $like "Rob%"

For more examples see src/test/scala in SVN.

No comments:

Post a Comment