Features

This aims to be a fairly complete feature list of EoD SQL... it could be missing a few things though.

Loose Object Mapping

Where most OR mapping layers complain terribly when there is a column missing from the ResultSet, EoD SQL simply leaves that field blank. This loose mapping also works the other way around: when there are extra columns in the ResultSet that cannot be mapped to a field in the data object, they are simply ignored. This means that you can have EoD SQL fetch just part of the data object for you.

Connected and Disconnected DataSet's

By default, a DataSet returned from a query method (annotated by @Select) is connected to the database. That is: it hold onto the ResultSet and doesn't let go of it until it's close() method is called. You can specify in the @Select annotation that the returned DataSet should simply load all the returned data, and release the database resources instead:
@Select(sql="SELECT * FROM users WHERE id = ?1",disconnected=true)
public DataSet<User> getUserById(int id);
As an additional feature, EoD SQL allows you to disconnect a connected DataSet using it's disconnect() method, which causes it to load the unfetched data into a cache, and release the database resources it is holding.

More complex query strings

While EoD SQL query strings are compatible with those of the EoD API from Java 6, EoD SQL also allows you to query complex objects for data to go into the SQL Query. This avoids you having to pass in each of the fields to your query method, and allows you to instead pass in a single POJO that can be inspected for it's data. Mostly this feature is useful in @Update annotated query methods.

Checked and Unchecked exception support

EoD SQL checkes the signature of your query methods for throws SQLException, if found, the method will throw a normal, checked SQLException. However, if no such throws clause is found, EoD SQL will wrap any SQLException thrown in a RuntimeException and throw that instead.

No SQL parsing

EoD SQL neither generates, nor parses the SQL given to it, in fact, as long as the database underneath supports JDBC, EoD SQL doesn't care what you type in the @Select and @Update query strings. This means that any SQL extensions your database may have can be used, and you don't have to stress about "does the OR layer support database X".

No config files or compile time enhancers

EoD SQL has no special config files, since all the information is stored in the annotations. EoD SQL also makes use of the Proxy class to generate the implementations of the query classes at runtime, so you don't have to do anything special at build/compile time. The use of the Proxy class means it's also safe to use from a sandboxed environment, since it doesn't need to do any fancy classloading of it's own.

Objects can be JavaBeans not just POJO's

EoD SQL's @ResultColumn annotation can be used to annotate JavaBeans setter methods. So you're not forced to declare fields as public, you can instead annotate their setter methods (which can be any name you choose), and the columns will be mapped for you.
@ResultColumn("username")
public void setUserName(String username) {
    assert username != null;
    this.username = username;
}

Select methods don't have to return DataSet

If you are only returning one object (or null), then just declare the method to return that single object. If you want the data in a disconnected collection type, such as a java.util.List on an array, then return it. Bare in mind that DataSet does extend java.util.List though.

Type mapping is done based on Java types

As of EoD SQL 0.7-beta, mapping of basic data-types within the API has been taken over. Where EoD SQL used to reply on the JDBC driver to return the correct data-type to be put in your class, it now has it's own TypeMapper interface. Using custom TypeMapper objects you can map any SQL data into any Java type that you want. If, for example you had your own Password type, you could create a TypeMapper that read a CHAR column from the ResultSet and turned it into your Password type. Look at the Javadocs for TypeMapper for more information.

Support for Rubberstamping

Most Database applications don't need to (and often shouldn't) store the objects they fetch from the database for any length of time due to memory performance. EoD SQL supports rubberstamping to make your application even more memory efficient. Only one data object is instantiated for an Iterator and is then reused each time you invoke next().
@Select(sql="SELECT * FROM users ORDER BY username",rubberstamp=true)
public DataIterator>User< getUsers();
The above code will result in only one User object being instantiated into memory. Each time you call DataIterator.next() it modifies the fields / calls setters and returns the same object.