Without going into too much depth here is the way to do it. The challenge faced were SimpleJdbcTemplate has a no-arg constructor. In future the intent of this interceptor is to detect N+1 query problem by using a light weight instrumentation framework plugged in instead of logging query times in log file.
public void setDataSource(DataSource dataSource) {
final SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(
dataSource);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SimpleJdbcTemplate.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method,
Object[] args, MethodProxy proxy) throws Throwable {
try{
String methodName = method.getName();
if (methodName.startsWith("query")
|| methodName.startsWith("batchUpdate")
|| methodName.startsWith("update")) {
String query = (String) args[0];
String prefix = extractQueryName(query);
long start = System.currentTimeMillis();
Object result = method.invoke(simpleJdbcTemplate,
args);
logger.info("Query {} took {} msec", prefix,
(System.currentTimeMillis() - start));
return result;
} else {
return method.invoke(simpleJdbcTemplate, args);
}
} catch(InvocationTargetException e) {
throw e.getTargetException();
}
}
private String extractQueryName(String query) {
//with xml based property files I am externalizing queries into a xml file and then when reading them back I am appending query name as a comment before qeury so a query look like below and I extract query name here.
/*getPerson*/ select * from person
}
});
this.jdbcTemplate = (SimpleJdbcTemplate) enhancer.create(new Class[]{DataSource.class}, new Object[]{dataSource});
}
Comments
Post a Comment