Hibernate::
|
Hibernate and iBatis working togetherLast update: Jan-05-2006
Sometimes we need to use SQL heavily to optimize DB access. We have multiple options for that:
Why yet another framework? - Because it is good at what it does: optimizing mundane and error prone JDBC code. Why Hibernate support for SQL is not enough? - In many cases it is enough, but sometimes iBatis mappings are simpler. In the future Hiberante might improve support for native SQL and then there will be less reasons to use any complementary solutions. For now it might make sense to use iBatis in places where we
would like to use JDBC. Benefits: The simplest way is to configure them separately and work with
them as every framework suggests, but it might be not quite optimal
because we would have actions performed in different transactions,
which might be undesirable. The next simple solution would be to let those frameworks operate on the same JDBC connection and manage transactions on JDBC connection level. This solution can be really simple if we will use AOP like techniques and let runtime proxies take care of plumbing code. Let's demonstrate how this can be done with Spring framework AOP capabilities. We will create a simple interceptor (Around advice ) that will provide necessary environment for our code to work within. In simple words that interceptor will initialize thread local variables with necessary Hibernate and iBatis sessions.
Therefore our code can simply use those sessions how we see fit and that around advice will take care of proper session finalization (read more about such technique here). 19 20 public void runIBatisQueryAndGetObjectsViaHibernate() throws SQLException { 21 List list = CallContext.getSqlMapClient().queryForList("summary", null); 22 for (Iterator j = list.iterator(); j.hasNext();) { 23 Object o = j.next(); 24 System.out.println("o = " + o + "|" + o.getClass()); 25 Map map = ((Map) o); 26 System.out.println("o.total = " +map.get("total") ); 27 Object ho = CallContext.getSession().get( VeryComplexDataClass.class, (Serializable) map.get( "id") ); 28 System.out.println("ho = " + ho ); 29 System.out.println("ho.getDependents() = " + ((VeryComplexDataClass)ho).getDependents()); 30 } 31 } As we can see at line #21 we use iBatis session to get list of rows, and then at row #27 we use Hibernate session to load entire object. If we take a glance at iBatis mapping file we could see that getting the same information without SQL with Hibernate (or any ORM solution for that matter) would be possible, but much much less performant. Hibernate SQL support allows us to do almost the same thing, just slightly less conveniently. iBatis mapping looks as following: 1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 <!DOCTYPE sqlMap 4 PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" 5 "http://www.ibatis.com/dtd/sql-map-2.dtd"> 6 7 <sqlMap namespace="summary"> 8 9 10 <select id="summary" resultClass="java.util.HashMap"> 11 select M.id, M.name, sum( C.subtot) as total 12 from hpib_objects M, hpib_dep_objects C 13 where m.id = C.ref_obj_id 14 group by M.id, M.name 15 </select> 16 17 </sqlMap> |
© Copyright 2003-2006 SourceLabs, Inc. All Rights Reserved.
411 First Ave S. Ste 403, Seattle, WA 98104 | 206.322.0099 | info@sourcelabs.com