Select statements return an immutable Query[T] that
is itself a Queryable[T] and a lazy Iterable[T].
The laziness here means that the query is sent to the database only
when starting iteration, or in other words, when Iterable.iterator is called.
The select function takes any legal Scala expression whose
type determines the generic parameter of the Query[R]
The select expression will be evaluated for every row returned by the query.
It is also possible to select with alternative (shorter but less generic) syntax :
Note that the .lookup[K](k: K) i.e. lookup by key method on a Table[T] is only
available for Table[T] that are of the form : Table[KeyedEntity[K]]
The classes Artist and Song in this example are part of a one to many relation
that can be accessed via the methods.
For the next examples, the following query will be nested as an inner query
into other queries :
The from clause takes Queryable[T]’s, a trait of Table[T] View[T] and Query[T].
Notice the Query[Song] funkAndLatinJazz.songsInPlaylistOrder in the from clause :
Joins can also be nested in the where clause just like in SQL :
Doing a 3 level nested join is by no means necessary and serves
no other purposes than demonstration.
In addition to the in() operator, exists() and notExists() can be used in a
where clause. They correspond to EXISTS and NOT EXISTS in SQL. Any query
nested with in(), exists(), or notExists() can also refer to queries in an
The SQL generated for the above statement is :
Calling the .distinct method on a Query creates a copy of it that has a ‘distinct’ select clause :
Calling the .forUpdate method on a Query creates a copy of it that has a ‘forUpdate’ locking directive :