Moved wiki docs into main project.
Why have them separate? Github allows reading docs right in the main tree.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
_Describes various example queries._
|
||||
|
||||
Depot queries are constructed using a builder-pattern.
|
||||
|
||||
## Whole record queries
|
||||
|
||||
A basic query to select all rows from a table looks like so:
|
||||
|
||||
```java
|
||||
from(PersonRecord.class).select();
|
||||
```
|
||||
|
||||
Note that the above query and the others in these examples will use the `PersonRecord` from the
|
||||
SimpleCodeExample page.
|
||||
|
||||
Various query clauses may be added to the basic query above to do filtering, ordering and the like.
|
||||
Here's a query with a simple where clause:
|
||||
|
||||
```java
|
||||
// selects all records with age <= 25
|
||||
from(PersonRecord.class).where(PersonRecord.AGE.lessEq(25)).select();
|
||||
```
|
||||
|
||||
One can also order and limit the results:
|
||||
|
||||
```java
|
||||
// selects the first ten records in ascending alphabetic order on name
|
||||
from(PersonRecord.class).ascending(PersonRecord.NAME).limit(10).select();
|
||||
```
|
||||
|
||||
More complex orderings are also possible:
|
||||
|
||||
```java
|
||||
OrderBy order = OrderBy.ascending(PersonRecord.NAME).thenDescending(PersonRecord.AGE);
|
||||
from(PersonRecord.class).orderBy(order).select();
|
||||
```
|
||||
|
||||
## Ad-hoc queries
|
||||
|
||||
Instead of selecting whole rows from the database, one can select individual columns, or the
|
||||
results of aggregate and other functions. Here's a simple projection:
|
||||
|
||||
```java
|
||||
List<Tuple2<Integer,String>> results =
|
||||
from(PersonRecord.class).select(PersonRecord.ID, PersonRecord.NAME);
|
||||
```
|
||||
|
||||
Depot annotates the `ColumnExp` constants generated in your `PersistentRecord` classes with their
|
||||
type so that queries like the above can be done in a type-safe manner. `Tuple` classes are provided
|
||||
up to `Tuple5` for such ad-hoc queries.
|
||||
|
||||
As an alternative to a `Tuple` class, you can use a type-safe builder to receive the results of
|
||||
your query like so:
|
||||
|
||||
```java
|
||||
public class IdName {
|
||||
public static Builder2<IdName, Integer, String> IDNAME_BUILDER =
|
||||
new Builder2<IdName, Integer, String>() {
|
||||
public IdName build (Integer a, String b) {
|
||||
return new IdName(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
public int id;
|
||||
public String name;
|
||||
public IdName (int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
List<IdName> results =
|
||||
from(PersonRecord.class).select(IDNAME_BUILDER, PersonRecord.ID, PersonRecord.NAME);
|
||||
```
|
||||
|
||||
Such queries will result in compile time error if the types of the columns do not match the types
|
||||
expected by the builder. The `BuilderN` interfaces are also only available up to arity-5.
|
||||
|
||||
For situations where type-safety is not a major concern, and for cases where you wish to select
|
||||
more than five columns, you can use `selectInto` which uses reflection to construct results:
|
||||
|
||||
```java
|
||||
public class NameCount {
|
||||
public String name;
|
||||
public int count;
|
||||
public NameCount (String name, int count) {
|
||||
this.name = name;
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
List<NameCount> results =
|
||||
from(PersonRecord.class).groupBy(PersonRecord.NAME).selectInto(
|
||||
NameCount.class, PersonRecord.NAME, Funcs.countStar());
|
||||
```
|
||||
|
||||
Note that the class supplied to the `selectInto` method must have exactly one public constructor,
|
||||
and the arguments to that constructor must match __in order__, the columns specified in the
|
||||
`selectInto` call. The types of the selected columns (or expressions) must be convertible to the
|
||||
type needed by the constructor (which means they will be widened or unboxed, but not converted from
|
||||
`float` to `int` or other non-automatic conversions). These requirements are unfortunately not
|
||||
checkable at compile time, and instead result in a runtime error when violated. Fortunately,
|
||||
testing tends to catch any such errors before they make it into the wild.
|
||||
|
||||
## Count queries
|
||||
|
||||
The `selectCount` method exists for when you wish to simply select the count of rows that match
|
||||
your query. For example:
|
||||
|
||||
```java
|
||||
int youngins = from(PersonRecord.class).where(PersonRecord.AGE.lessEq(12)).selectCount();
|
||||
```
|
||||
|
||||
You may also wish to group by certain columns and select the counts of rows that match each group.
|
||||
This is done with an ad-hoc query:
|
||||
|
||||
```java
|
||||
List<Tuple2<String,Integer>> results =
|
||||
from(PersonRecord.class).groupBy(PersonRecord.NAME).
|
||||
select(PersonRecord.NAME, Funcs.countStar());
|
||||
```
|
||||
|
||||
## Other functions
|
||||
|
||||
A variety of other functions are defined in
|
||||
[Funcs](http://depot.googlecode.com/svn/apidocs/com/samskivert/depot/Funcs.html),
|
||||
[StringFuncs](http://depot.googlecode.com/svn/apidocs/com/samskivert/depot/StringFuncs.html),
|
||||
[DateFuncs](http://depot.googlecode.com/svn/apidocs/com/samskivert/depot/DateFuncs.html), and
|
||||
[MathFuncs](http://depot.googlecode.com/svn/apidocs/com/samskivert/depot/MathFuncs.html). These can
|
||||
be used in queries, like so:
|
||||
|
||||
```java
|
||||
List<PersonRecord> eldest =
|
||||
from(PersonRecord.class).where(PersonRecord.AGE.eq(Funcs.max(PersonRecord.AGE))).select();
|
||||
```
|
||||
|
||||
And you can select the value of a function in an ad-hoc query:
|
||||
|
||||
```java
|
||||
// note that load() can be used for selections that will only ever return one row
|
||||
Number maxAge = from(PersonRecord.class).load(Funcs.max(PersonRecord.AGE));
|
||||
|
||||
// alternatively
|
||||
List<Number> maxAge = from(PersonRecord.class).load(Funcs.max(PersonRecord.AGE));
|
||||
assert(maxAge.size() == 1);
|
||||
|
||||
// here's a more complex (if somewhat nonsensical) query that groups people by the first
|
||||
// letter of their name and selects the sum of all ages of the people in those groups
|
||||
SQLExpression<String> firstLetter = StringFuncs.substring(PersonRecord.NAME, 0, 1);
|
||||
List<String,Integer> results = from(PersonRecord.class).groupBy(firstLetter).
|
||||
select(firstLetter, Funcs.sum(PersonRecord.AGE));
|
||||
```
|
||||
Reference in New Issue
Block a user