Development patterns in EoD SQL 2.0

EoD SQL has always been focused on flexability, and EoD SQL 2.0 is taking that concept even further.

To introduce this topic, I have some important points (some of which may already be known):

  • EoD SQL understands Connection pooling
    • Creating a Query instance with a DataSource is completely different to creating one with a Connection
  • EoD SQL allows you to declare the type you want to return
  • EoD SQL does not mangle your SQL, ever!
    • You tell your database exactly what you want to

Here is a little example of some code that uses some of EoD SQL’s more advanced tricks:

public class User {
  private static final UserQuery QUERY = QueryTool.getQuery(UserQuery.class);

  @AutoGeneratedKeys
  private Long id = null;

  private String email;

  private String password;

  @ResultColumn( "display_name" )
  private String displayName;

  private User() {}

  public User(String email, String password, String displayName) {
    this.email = email;
    this.password = password;
    this.displayName = displayName;
  }

  public Long getId() {
    return id;
  }

  public String getEmailAddress() {
    return email;
  }

  public void setEmailAddress(String emailAddress) {
    this.email = emailAddress;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getDisplayName() {
    return displayName;
  }

  public void setDisplayName(String displayName) {
    this.displayName = displayName;
  }

  public synchronized void save() throws SQLException {
    if(id == null) {
      id = QUERY.insert(this);
    } else {
      QUERY.update(this);
    }
  }

  public static User getUser(long id) throws SQLException {
    return QUERY.selectById(id);
  }

  public static User getUser(String email) throws SQLException {
    return QUERY.selectByEmail(email);
  }
}

The things to note in the above code:

And then the Query declaration:

public interface UserQuery extends BaseQuery {
  @Select( "SELECT * FROM users WHERE id = ?1 LIMIT 1" )
  public User selectById(long id) throws SQLException;

  @Select( "SELECT * FROM users WHERE email = ?1 LIMIT 1" )
  public User selectByEmail(String email) throws SQLException;

  @Update( sql="INSERT INTO users (email, password, display_name) " +
    "VALUES (?{1.email}, ?{1.password}, ?{1.displayName})",
    keys=GeneratedKeys.RETURNED_KEYS_FIRST_COLUMN )
  public long insert(User user) throws SQLException;

  @Update( "UPDATE users SET email = ?{1.email}, password = ?{1.password}," +
    "display_name = ?{1.displayName} WHERE id = ?{1.id}" )
  public void update(User user) throws SQLException;
}

Things to note in the above code:

  1. The UserQuery instance QUERY in the User class is declared “static final”
    1. Because it is created with a DataSource, EoD SQL will automatically pull a Connection from the pool each time you run a query
    2. You need never close one of these Query objects, since the Connection is returned to the pool when you are no longer using it automatically
  2. Returning Database-Generated-Keys has become much easier in EoD SQL 2.0 as you can see from the “insert” method of the Query interface
  3. You are not forced to return a DataSet<User> in EoD SQL, you can return any type that EoD SQL understands (and it knows about quite a few)
    1. All the Java primitives and their wrapper classes
    2. Arrays
    3. UUID
    4. Any class you write that could be returned in a DataSet
    5. Many of the Collections types
      1. Collection
      2. List
      3. Set
      4. SortedSet

EoD SQL 2.0-beta is up and about

Thanks to a lot of bug reports and feature requests, I’ve released EoD SQL 2.0-beta. What’s changed? Not a massive amount is visible, besides a long list of bug fixes:

  • QueryTool.select is now working again, and includes a new variant that uses a Connection instead of a DataSource.
  • Added “char” and “Character” as default primitive types
  • The Java primitive TypeMappers (short, int, long, boolean, etc.) now use valueOf instead of new

Some of the bug-fixes are very important, so if you’re using EoD SQL 2.0-alpha you’ll want to download this new version asap.

How to use the Accessible Flag in Java

I have long held to the belief that Java’s reflection mechanism is one of it’s most powerful aspects. Sure many languages today have similar features, but to me Java still stands head and shoulders above the rest.

My first language was Java, I then went on to learn C/C++ and a host of other languages. The unfortunate part for me: I use reflection in my sleep. When working with GWT, I find reflection strongly influencing the way I write code, even though GWT doesn’t have it.

The one part of reflection I haven’t played with until recently was the Accessible Flag. It’s a little flag of each Field; Method and Constructor that allows you to suppress the accessibility checks (protected, package-protected and private). Sounds like an awful thing, doesn’t it. Well, in typical Java fashion: it’s protected by a Security check (to make sure the administrator has allowed your code to tamper in such ways). The Accessibility flag is in fact how the ObjectOutputStream and ObjectInputStream classes access your private fields for Serialization.

Take a look at the JavaDocs for AccessibleObject to see the various methods available to you. The only trick when using the Accessible flag is: it is only set for the Class that actually sets it, therefore: you must setAccessible from the same class that will invoke the methods that require the flag to be set.

  • If you have class A and class B
  • Class A invokes setAccessible(true) on a Field object and passes it to class B
  • Class A invokes doOperation() on class B
  • doOperation in class B invokes Field.set on the Field object passed be class A
  • Field.set will throw an IllegalAccessException

In order to make the structure above work, either class A must be the one to invoke Field.set, or class B must be the one to invoke setAccessible.