Class Query<T>
A query named in the entity's own terms.
List<Note> recent = notes.query()
.eq("author", author)
.gt("created", cutoff)
.orderBy("created", false)
.limit(20)
.list();
Every name here is a JAVA FIELD of the entity, which is what makes the query portable: the builder maps it to the column the entity declared and quotes it for the engine, so a field called createdAt works on PostgreSQL, which folds an unquoted name to lower case, exactly as it works on the other two. A name that is not a field of this entity is refused immediately, naming the ones that are, rather than reaching the server as a column it does not have.
Values are bound, never interpolated. A Date becomes epoch milliseconds and a boolean becomes 0 or 1, which is how an entity stores them, so what the query compares is what the table holds.
Conditions are joined with AND, in the order they were added. OR and grouping
are deliberately absent: the moment a query needs them it is past what naming
fields expresses clearly, and Dao.find(String, Object[]) takes the SQL that says it.
-
Method Summary
Modifier and TypeMethodDescriptionlongcount()How many rows match.intdelete()Deletes every matching row and answers how many.field = value, or field IS NULL when the value is null.first()The first matching row, or null.field > value.field >= value.field IN (...).field IS NOT NULL.field IS NULL.field LIKE pattern, with the engine's own wildcards: % for any run of characters and _ for one.limit(int count) At most this many rows.list()The matching rows, as entities.field < value.field <= value.field <> value, or field IS NOT NULL when the value is null.offset(int count) Skips this many rows.Orders by a field, ascending or descending.toString()The conditions as SQL, for a message or for a statement built around them.
-
Method Details
-
eq
-
ne
-
gt
-
gte
-
lt
-
lte
-
like
-
isNull
-
isNotNull
-
in
-
orderBy
-
limit
-
offset
-
list
-
first
The first matching row, or null.
Asks the database for one row rather than reading them all and taking the first: the limit is part of the statement.
- Throws:
IOException
-
count
How many rows match.
The ordering and the limit are left off, because neither changes an answer that is one number -- and because MySQL refuses ORDER BY in some places where a count is legal.
- Throws:
IOException
-
delete
Deletes every matching row and answers how many.
ONE statement rather than a read followed by deletes, which is both faster and atomic -- and which is why it is here rather than left to the caller: written by hand it is a loop that can be interrupted halfway.
A query with NO conditions deletes the whole table, exactly as the SQL it builds would. That is the reading with no surprises in it, and it is what makes this the idiomatic way to empty a table in a test.
The ordering and the limit are not part of it: MySQL alone accepts a LIMIT on a DELETE, so honouring one here would mean a query that behaves differently on the engine it was not developed against.
- Throws:
IOException
-
toString
-