Monday, May 31, 2010

Implementing multiple SQL IN clauses in a complex query using IBatis/MyBatis

There are couple of good posts which explain implementing SQL IN clause in a query using iBatis/MyBatis. (Incase, you are not aware, iBatis now has a new home and new name.)

http://binodsuman.blogspot.com/2009/03/how-to-use-in-clause-in-ibatis.html
http://stackoverflow.com/questions/1637825/how-to-use-an-in-clause-in-ibatis

But, they don't discuss about how to do this for a complex query which has multiple IN clauses or a query which has IN clause and some other parameters also.

For example, let's take a query like this:

select firstname, lastname, nickname, hobby from users WHERE nickname=? and lastname IN (?,?,?) AND hobby IN (?,?,?)

In this case, we could have both the list of lastnames and hobbies in two lists and put the two lists in a map and pass that as param to the query.

List lastNameList= new ArrayList();
lastNameList.add("Smith");
lastNameList.add("Sharma");
lastNameList.add("Sherman");

hobbiesList= new ArrayList();
hobbiesList.add("Cricket");
hobbiesList.add("Football");
hobbiesList.add("Tennis");

Map params = new HashMap();
params.put("nickName", "Nick");
params.put("lastNames", lastNameList);
params.put("hobbies", hobbiesList);
return this.clientProvider.get().queryForList("getUsersByLastNamesListAndHobbiesList", params);

In iBatis/MyBatis side, you can use the two lists in different IN clauses like this:

<select id="getUsersByLastNamesListAndHobbiesList" parameterClass="map" resultClass="UserBean">
SELECT firstname, lastname, nickname, hobby from users
where nickname=#nickName#
<dynamic>
<iterate prepend="and lastname IN" property="lastNameList" open="(" close=")" conjunction=",">
#lastnameList[]#
</iterate>
<iterate prepend="and hobby IN" property="hobbiesList" open="(" close=")" conjunction=",">
#hobbiesList[]#
</iterate>
</dynamic>
</select>

Hope this helps you in implementing SQL IN clauses in a complex query using iBatis/MyBatis.

Saturday, May 22, 2010

New Features in Java 7 (Dolphin)

There are many interesting features coming up in Java 7 code named as Dolphin. Below, I will discuss about some of these features (in no priority order) which I came across. This is not a complete list and some of these features are still in implementation and may not make it to the final release.

Multi-Catch:

Current way:

try {
// Say some file parser code here...
} catch (IOException ex) {
// log and rethrow exception
} catch (ParseException ex) {
// log and rethrow exception
} catch (ClassNotFoundException ex) {
// log and rethrow exception
}

This can now become...

try {
// Say some file parser code here...
} catch (IOException ex | ParseException ex | ClassNotFoundException ex) {
// log and rethrow exception
}

Much more simple right? We can just put all the exceptions in the same line separated by |. Ofcourse, this is only convenient if we take the same action for all exceptions. If we want to do different actions for different exceptions (which would be a more common case), then we still have to catch them individually.

Final Rethrow:

Let's say that we have a method like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
// code which throws IOException and ParseException
}

Now, if we want to do some operation (say log the exception) upon catching these exceptions and before rethrowing them, we could modify the above method like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
try {
// code which throws IOException and ParseException
} catch (Exception ex) {
// Log exception
throw ex;
}
}

But, the problem with this is, compiler will not like this since the method does not throw Exception (It only throws IOException and ParseException, which are subtypes of Exception). We are now forced to add Exception to method signature, but we may not be able to do this if testFinalRethrow overrides a method which does not declare throwing Exception.

In Java7, we could simplify this by adding final keyword in catch block. We could modify the above method to look like this:

private void testFinalRethrow(final int a) throws IOException, ParseException {
try {
// code which throws IOException and ParseException
} catch (final Exception ex) { // Look at final keyword here
// Log exception
throw ex;
}
}

Using final keyword in catch block allows us to throw the exact exception subtype which happened. For example, if IOException happened, then IOException would be thrown, if ParseException happened, then ParseException would be thrown (instead of Exception being thrown). Final keyword allows us to throw the exact exception which happened without the need to add Exception to method signature.

Strings in switch:

Before we talk about strings in switch, do you know what are the types allowed in switch now? We could use byte, short, char, int and enum in Switches. With Java 7, Strings could also be used.

private void testStringSwitch(final String key) {
final String value = "test;
String value2 = "test2"
switch (key) {
case value:
break;
case "foo":
break;
case value2: // Non-final variables are not allowed
break;
case getStringValue(): // Method calls not allowed
break;
}
}

As the comment says, non-final variables and method calls cannot be used in Switch case.

Improved Type Inference:

Old Way: List<Integer> list = new ArrayList<Integer>()
Google collections: List<Integer> list = Lists.newArrayList()
New Way: List<String> list = new ArrayList<>(); (Look at <>).

Let's take a look at complex example:

Old Way:
List<Map<String, List<Double>>> myList =
new ArrayList<Map<String, List<Double>>>();
New Way:
List<Map<String, List<Double>>> myList = new ArrayList<>();

Binary Literals:

Do you know how to convert binary number to decimal in Java6?

You could do it this way:
Integer.parseInt("101010", 2);
But this is verbose, slow and could throw runtime exceptions.

New way:
int binary = 0b101010; // Much easier right?

Underscores in Numbers:

int phoneNumber = 123_555_1212;
long creditCardNumber = 1234_5678_9012_4456L;
long socialSecurityNumber = 123_45_6789L;

These are all valid declarations in Java7.
Underscores are ignored by compiler
int result = (1_2 + 23_8) / 5_0 (Result would be 5)

Automatic resource management:

Current Way:
static String readLineFromFile(String path)
throws IOException {
BufferedReader br = new BufferedReader(
new FileReader(path))
try {
return br.readLine();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

As you can see, this is verbose and this is what we do now.

New Way:
static String readLineFromFile(String path) throws IOException {
try (Reader fin = new FileReader(path);
BufferedReader br = new BufferedReader(fin)) {
return br.readLine();
}

Both fin and br would be automatically managed in Java7.

Immutable Collections:

Current way: We use Collections.unmodifiableList, Collections.unmodifiableSet, Collections.unmodifiableMap etc.,

New way: (groovy like syntax)

List myList = [ "foo", "bar", "value" ];
Set mySet = { "foo", "bar", "value" };
Map myMap =
{ "foo" : 1, "bar" : 2, "value" : 3 };

New way is more elegant and straightforward.

Retrieving elements from collection:

Current Way:

myList.get(0);
myMap.get("foo");

New Way:

myList[0];
myMap["foo"];

Null Handling:

This is one of my favorites. java.util.Objects class has 9 useful static methods.
Javadoc for this class: http://download.java.net/jdk7/docs/api/java/util/Objects.html

nonNull - Similar to google preconditions
toString methods- Handles null automatically
hash and hashCode methods - Does hashCode for single or multiple objects. Returns 0 if object is null.
equals and deepEquals - Handles null automatically. Deep equals handles arrays also.

This post talks about them in more detail - http://www.baptiste-wicht.com/2010/04/java-7-the-new-java-util-objects-class/

Monitor changes in file system:

This feature is very useful if your application needs to know about the changes in file system and update itself accordingly. Look at these classes in Java7:

WatchKey - http://java.sun.com/javase/7/docs/api/java/nio/file/WatchKey.html

Project JIGSAW:

As we all know, JDK is huge and the goal of this project is to modularize the JDK. Here is the home page of the project - http://openjdk.java.net/projects/jigsaw/. I hope this would help in reducing the footprint of the application which we ship to our users.

Concurrency:

Java7 has updates to handling concurrency and one of the new things is Fork/Join framework. This post discusses about it in detail - http://www.baptiste-wicht.com/2010/04/java-7-more-concurrency/

Dropped features:

No Swing application framework - It was originally intended to remove boilerplate code

Not adding JXDatePicker API to platform

IDE Support:

Both IDEA and Eclipse support JDK7 at compile level only i.e they can compile the source but advanced features like code complete etc., won't work

NetBeans 6.9 Beta has much better support for JDK7

Release Schedule:

Milestone 7 is the latest release
Milestone 8 to be released in June 2010
Final release will be (hopefully) in September 2010

Saturday, May 8, 2010

Creating a consistent RCP GUI

We are developing an RCP application and after sometime we realized that our views/editors are not consistent in the common functionalities they provide to the user. I came up with a style/consistency guide to address this.

Views/Editors: (Some apply to dialog/wizards also)

1) Make sure all fields have tooltips
2) Make sure tab functionality works
3) Make sure field validation is done for text fields (no characters in number fields, no numbers in character fields etc.,)
4) Make sure to set initial focus to a primary field
5) Make sure to add a dynamic free text filter for all explorer trees and tables/tree tables
6) Make sure to add sorting functionality for all tables
7) Make sure to do long running operations in background thread. If it is a big operation use jobs framework, else use BusyIndicator so that user has clue of what is going on.
8) Make sure all strings are externalized. If not applicable, make sure to add //$NON-NLS-1$ comment
9) Make sure to add context sensitive id to views/editors so that Context sensitive help works
10) Make sure to add cheat sheet for the new view/editor
11) Make sure to dispose resources in dispose() method
12) In the case of editors, make sure that equals/hashCode for editor input is done right so that multiple editors do not open when opening the same element
13) In the case of editors, make sure that editor has input factory so that the editor is persisted properly
14) Make sure to develop the view/editor using MVP pattern
15) Make sure to put model/presenter in core (non UI) bundle and add test cases for them

We normally don't find these requirements in a user story, since user story would normally talk about business functionality. I think this would help in creating a consistent UI and also make the code better. This would also help the testers to know what to look for in every view/editor and raise a bug if a particular one does not support it. Even though this mainly addresses RCP GUI, many of these points would apply for any GUI.

Do you have any comments on these or have more to add? Your comments are welcome.