C
chvid
I have an idea, that I have currently implemented in C# (.NET 1.1), for
interfacing with a database.
I would like to discuss whether it is possible to do a similar thing in
Java 5 using generics and annotations.
The basic idea is that you define a set of methods, that wraps simple
SQL statements, in an interface like this:
(C# pseudo code)
inteface MyDBLayer {
[SQL("SELECT COUNT(*) FROM users")]
public int countUsers();
[SQL("SELECT * FROM users WHERE name = @name LIMIT 1")]
public User getUserByName(String name);
[SQL("SELECT * FROM users", typeof(User))]
public List allUsers();
}
You give the above interface to my framework and it returns a proxy
implementation, that does the following:
For the method public int countUsers() it fires the SQL statement
SELECT COUNT(*) FROM users and reads the first row and first column,
and converts the result to an int. (Becuase the return type of the
method is "int").
For the method public User getUserByName(String name) it fires the SQL
statement SELECT * FROM users WHERE name = @name LIMIT 1, where @name
is the string provided in the name parameter and reads the first row,
creates an object of type User (the method's return type), and calls
its setter properties, according to the attribute names of the SQL
result table, with the values of the first row.
For the method public List allUsers() it creates an implementation of
return type List, fires the SQL statement and maps the resulting rows
in to User objects (where the type User is provided as a parameter).
The advantages of this approach is that you get strong typing without
code generation.
The user code will be simple and clear like this:
MyDBLayer myDBLayer =
(MyDBLayer)framework.createLayer(typeof(MyDBLayer), "db parameters");
int userCount = myDBLayer.countUsers();
User christian = myDBLayer.getUserByName("Christian Hvid");
etc. etc.
Ideally I want to do the following in Java 5 - like this:
inteface MyDBLayer {
@SQL("SELECT COUNT(*) FROM users")
public int countUsers();
@SQL("SELECT * FROM users WHERE name = @name LIMIT 1")
public User getUserByName(String name);
@SQL("SELECT * FROM users")
public List<User> allUsers();
}
But I think I run into the following problems:
1. The parameter name "name" is not available thru reflection in method
public User getUserByName(String name).
2. The type List<User> is "erased" to List in public List<User>
allUsers().
Any suggestions for workarounds?
Any comments on the overall design?
-- Christian
Please use the email-address on my homepage:
http://vredungmand.dk
interfacing with a database.
I would like to discuss whether it is possible to do a similar thing in
Java 5 using generics and annotations.
The basic idea is that you define a set of methods, that wraps simple
SQL statements, in an interface like this:
(C# pseudo code)
inteface MyDBLayer {
[SQL("SELECT COUNT(*) FROM users")]
public int countUsers();
[SQL("SELECT * FROM users WHERE name = @name LIMIT 1")]
public User getUserByName(String name);
[SQL("SELECT * FROM users", typeof(User))]
public List allUsers();
}
You give the above interface to my framework and it returns a proxy
implementation, that does the following:
For the method public int countUsers() it fires the SQL statement
SELECT COUNT(*) FROM users and reads the first row and first column,
and converts the result to an int. (Becuase the return type of the
method is "int").
For the method public User getUserByName(String name) it fires the SQL
statement SELECT * FROM users WHERE name = @name LIMIT 1, where @name
is the string provided in the name parameter and reads the first row,
creates an object of type User (the method's return type), and calls
its setter properties, according to the attribute names of the SQL
result table, with the values of the first row.
For the method public List allUsers() it creates an implementation of
return type List, fires the SQL statement and maps the resulting rows
in to User objects (where the type User is provided as a parameter).
The advantages of this approach is that you get strong typing without
code generation.
The user code will be simple and clear like this:
MyDBLayer myDBLayer =
(MyDBLayer)framework.createLayer(typeof(MyDBLayer), "db parameters");
int userCount = myDBLayer.countUsers();
User christian = myDBLayer.getUserByName("Christian Hvid");
etc. etc.
Ideally I want to do the following in Java 5 - like this:
inteface MyDBLayer {
@SQL("SELECT COUNT(*) FROM users")
public int countUsers();
@SQL("SELECT * FROM users WHERE name = @name LIMIT 1")
public User getUserByName(String name);
@SQL("SELECT * FROM users")
public List<User> allUsers();
}
But I think I run into the following problems:
1. The parameter name "name" is not available thru reflection in method
public User getUserByName(String name).
2. The type List<User> is "erased" to List in public List<User>
allUsers().
Any suggestions for workarounds?
Any comments on the overall design?
-- Christian
Please use the email-address on my homepage:
http://vredungmand.dk