Hi Clinton, thanks for your detailed answer.
I agree with you, although leaving aside the SQLUtils varargs proposal, I tend to priorize the unconstrained java mapper interface issue over the parameter naming issue, because (i) the interface defines a contract for the rest of the application and maps or a myriad of dtos don't feel like a good interface design at the application level (previously with ibatis 2 I simply implemented dao interfaces at my pleasure on top of SQLUtils, now I can avoid the boilerplate but at the price of modifying the signatures, this is intrusive from the part of ibatis). (ii) because most methods will in fact take just one argument, while a few will take two, or maybe three. The name-positional mapping is ugly, although there is no huge unmaintainable number of ? placeholders here but just a couple of ordinal arguments, so most of the references will still be done by name to the properties of the args and not to the args themselves: arg1.name,arg2.id,arg1.age,arg2.password,... vs ?,?,?,?,... That *makes* a difference. With respect to obtaining the parameters names at runtime, until java 8 not even 7 afaik) the only way to go is to compile with debug info an access the bytecode with asm (not sure if javassist can do this trick also). It's not that hard, but you have to generate debug info for the class and introduce a dependency on asm. I could implement this, if you're interested. Best regards -- Carlos On Sun, Aug 30, 2009 at 08:44:45AM -0600, Clinton Begin wrote: > I love the idea, and I think we even have it on the wiki... > > However, I attempted the implementation and could not land on a design that > was nice. The biggest problem is that Java lacks introspection on method > parameter names. What I would really love is: > > @Select("select * from employee where first_name = #{firstName}" and > last_name = #{lastName}) > Employee findEmployeeLike(String firstName, String lastName); > > That would truly be awesome (of course complex types would work too). This > is perfectly possible in C#, where I can get the names of the parameters. > However in Java, there is no such means. So that leaves us with pretty much > two options: > > 1) Ordinal -- I don't like this, because it's akin to the ordinal ? params > in standard JDBC prepared statements. By supporting multiple params, the > value of the feature should increase with more params, but here, adding more > params makes the SQL less readable and harder to change later (i.e. > refactoring to add a new param in the middle of the method signature). > Doesn't bode well for this feature. > > @Select("select * from employee where first_name = #{1} and last_name = > #{2}) > Employee findEmployeeLike(String firstName, String lastName); > > 2) Annotations -- We could add annotations to the parameters... this just > ended up looking silly. > > @Select("select * from employee where first_name = #{firstName} and > last_name = #{lastName}) > Employee findEmployeeLike(@Param("firstName") String firstName, > @Param("lastName") String lastName); > > An alternative was to use a single annotation... > > @Select("select * from employee where first_name = #{firstName} and > last_name = #{lastName}) > @Params("firstName","lastName") > Employee findEmployeeLike(String firstName, String lastName); > > But that kind of repetition makes me sad. :-( > > At the end of the day I gave up, because all of these were so repetitive, > hard to maintain (due to the alignment and ordinal positioning) and don't > read well. > > I really wish Java made this easier. One thought I had to submit to the JCP > was to add introspection on parameter names by having the compiler > automatically create annotations for the parameter names. > > For example, given the method: > > Employee findEmployeeLike(String firstName, String lastName); > > The compiler would automatically create @MethodParameterName annotation (or > something similar) for each parameter. Then I could either use the regular > annotation API to fetch them, or a cleaner API like String[] > method.getParameterNames(). > > But I decided by the time that made it into the framework we'd be at JDK 9 > and who knows where iBATIS would be. :-) > > I'm open to more ideas... but the goals have to be: > > 1) No repetition > 2) No ordinal positioning > 3) Descriptive SQL > 4) Easy to maintain > > Thoughts? > > Cheers, > Clinton > > On Sun, Aug 30, 2009 at 3:30 AM, <carlosjosep...@gmail.com> wrote: > > > > It just requires a trivial modification in MapperMethod and a simple > > > mechanism to access positional parameters to get it working. For > > > example, MapperMethod could create a Map and put the first argument > > > under the key "first", the second one under "second", etc. That is, > > > positional access "by name". Of course, in case the number of > > > arguments were only one, the usual mechanism would follow. > > > > > > Another possibility is to take advantage of java 5 varargs feature and > > allow SqlSession methods to accept multiple parameters with Object...: > > > > Object selectOne(String statement, Object... parameters); > > > > (Of course, the currently overloaded selectOne: > > > > Object selectOne(String statement); > > Object selectOne(String statement, Object parameter); > > > > would be merged into the single method above). > > > > As before, when length > 1 the varargs will be automatically stored into > > a Map under "positional" keys like "arg1", "arg2", etc (I'm not sure if > > the shorter "1", "2", etc are compatible with javabeans as in "bean.1", > > "bean.2"). > > > > This way MapperMethod will just forward its Object[] args to the SqlSession > > method selectOne, selectList, etc. > > > > Notice that any change that I have proposed is absolutely backwards > > compatible: > > > > 1) Object... still can take single arguments. > > 2) If just one argument is given the { "arg1": arg1, "arg2": arg2, ...} > > map will not be created at all. > > 3) Sql expecting one argument won't need to be modified. > > > > However, SqlSession won't compile with java 1.4 or older due to the > > introduction of varargs. I don't know if this is a concern for ibatis 3. > > In that case, the proposal of my previous post doesn't suffer the same > > inconvenience, althought it is more limited. > > > > I would like to hear your opinion about it. > > > > Best regards > > -- > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: user-java-unsubscr...@ibatis.apache.org > > For additional commands, e-mail: user-java-h...@ibatis.apache.org > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: user-java-unsubscr...@ibatis.apache.org For additional commands, e-mail: user-java-h...@ibatis.apache.org