Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.
public final class Query<T>
- Object
- Query
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 takes the SQL that says it.
Methods
Inherited methods
Method details
eq
public Query<T> eq(String field, Object value)ne
public Query<T> ne(String field, Object value)gt
public Query<T> gt(String field, Object value)gte
public Query<T> gte(String field, Object value)lt
public Query<T> lt(String field, Object value)lte
public Query<T> lte(String field, Object value)like
public Query<T> like(String field, String pattern)isNull
public Query<T> isNull(String field)isNotNull
public Query<T> isNotNull(String field)in
public Query<T> in(String field, Object[] values)orderBy
public Query<T> orderBy(String field, boolean ascending)limit
public Query<T> limit(int count)offset
public Query<T> offset(int count)list
public List<T> list()
throws IOExceptionThrows
first
public T first()
throws IOExceptionThe 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
count
public long count()
throws IOExceptionHow 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
delete
public int delete()
throws IOExceptionDeletes 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
toString
public String toString()