2.8. Querying in Scala

Generic support for Querydsl usage in Scala is available via querydsl-scala module. To add it to your Maven build, use the following snippet :

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

2.8.1. DSL expressions for Scala

Querydsl for Scala provides an alternative DSL for expression construction. The Scala DSL utilizes language features such as operator overloading, function pointers and implicit imports for enhanced readability and conciseness.

Here is an overview of the main alternatives :

//Standard              Enhanced

expr isNotNull          expr is not(null)
expr isNull             expr is null
expr eq "Ben"           expr === "Ben"
expr ne "Ben"           expr !== "Ben"
expr append "X"         expr + "X"
expr isEmpty            expr is empty
expr isNotEmpoty        expr not empty

// boolean
left and right          left && right
left or right           left || right
expr not                !expr

// comparison
expr lt 5               expr < 5
expr loe 5              expr <= 5
expr gt 5               expr > 5
expr goe 5              expr >= 5
expr notBetween(2,6)    expr not between (2,6)
expr negate             -expr
 
// numeric
expr add 3              expr + 3
expr subtract 3      	expr - 3
expr divide 3           expr / 3
expr multiply 3         expr * 3
expr mod 5              expr % 5

// collection
list.get(0)             list(0)
map.get("X")            map("X")

2.8.2. Querying with SQL

Like with Querydsl SQL for Java you need to generate Query types to be able to construct your queries. The following two unit test methods show how this is done :

  
  @Test
  def Generation_without_Beantypes() {
    val namingStrategy = new DefaultNamingStrategy();
    val exporter = new MetaDataExporter();
    exporter.setNamePrefix("Q");
    exporter.setPackageName("test");
    exporter.setTargetFolder(new File("target/gen1"));
    exporter.setSerializerClass(classOf[ScalaMetaDataSerializer]);
    exporter.setCreateScalaSources(true);
    exporter.setTypeMappings(ScalaTypeMappings.create);
    exporter.export(connection.getMetaData);
  }

  @Test
  def Generation_with_Beantypes() {
    val namingStrategy = new DefaultNamingStrategy();
    val beanSerializer = new ScalaBeanSerializer();
    val exporter = new MetaDataExporter();
    exporter.setNamePrefix("Q");
    exporter.setPackageName("test");
    exporter.setTargetFolder(new File("target/gen2"));
    exporter.setSerializerClass(classOf[ScalaMetaDataSerializer]);
    exporter.setBeanSerializer(beanSerializer)
    exporter.setCreateScalaSources(true);
    exporter.setTypeMappings(ScalaTypeMappings.create);
    exporter.export(connection.getMetaData);
  }  

2.8.3. Querying with other backends

When querying with other backends the Expression model has to be created manually or alternatively the alias functionality can be used.

Here is a minimal example with JPA/Hibernate :

  
@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%"