ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Torsten Michelmann" <torsten.michelm...@gmx.de>
Subject Re: Re: Re: RE: Problem populating a List using groupBy
Date Sun, 02 Jul 2006 19:13:03 GMT
Hi Chris,
you were right, the RowHandler interface is the secret weapon of iBatis!

While I consider using RowHandler as kind of a last resort (because you have to code all mappings
versus the clean XML mapping approach that iBatis is promoting) it is nice having this solution
up in ones sleeves knowing that there is no mapping that is impossible!

While I understand that RowHandler allows all kind of dirty tricks I would nevertheless love
to see something along the example you kindly provided within the developers quide (perhaps
at the very end, so that nobody will discover it who is not desperately searching for it).



-------- Original-Nachricht --------
Datum: Tue, 27 Jun 2006 16:56:27 +0200
Von: Torsten Michelmann <torsten.michelmann@gmx.de>
An: user-java@ibatis.apache.org
Betreff: Re: Re: RE: Problem populating a List using groupBy

> Hi Chris,
> 
> thank you very much for the prompt response and the kind explanation.
> I will give this a try very soon.
> 
> -------- Original-Nachricht --------
> Datum: Tue, 27 Jun 2006 08:45:06 -0600
> Von: Chris Lamey <clamey@localmatters.com>
> An: user-java@ibatis.apache.org
> Betreff: Re: RE: Problem populating a List using groupBy
> 
> > Hello,
> > 
> > I had the exact same questions:)
> > 
> > Yes, the docs are out of date, the RowHandler interface has changed.
> > 
> > Here's an example of RowHandler usage:
> > 
> > public class WidgetRowHandler implement RowHandler {
> > 
> >     private List<Widgets> widgets = new ArrayList<Widgets>();
> > 
> >     public void handleRow(Object valueObject) {
> >         
> >     	Map resultMap = (Map) valueObject;
> >         Widget w = new Widget();        
> >         w.setID((String)resultMap.get("widget_id"));
> >         w.setName((String)resultMap.get("widget_name"));
> >         w.setParentID((String)resultMap.get("widget_parent_id"));
> >         
> >         widgets.add(w);
> >     }
> > 
> >     public List<Widget> getWidgets() {
> >         return this.widgets;
> >     }
> > }
> > 
> > Then in your DAO:
> > 
> > 
> >             Map<String, String> params = new HashMap<String, String>();
> >             params.put("category_id", categoryID);
> >             params.put("invoce_id", invoiceID);
> >             WidgetRowHandler wrh = new WidgetRowHandler();
> >             sqlMapClient.queryWithRowHandler(
> >                     "WIDGET.select_widgets",
> >                     params, wrh);
> >             return wrh.getWidgets();
> > 
> > It's a simple example, but the basic idea is that you can pull things
> > >from the result set via handleObject, keep them around in your
> > RowHandler instance, and other objects can find them there.
> > 
> > Of course, if you're dealing with large data sets, putting everything
> > into a List wouldn't scale all that well.  However, for large data sets
> > the RowHandler is very useful because you can process one row in your
> > result set at a time, which can be very efficient.
> > 
> > Cheers,
> > Chris
> > 
> > On Tue, 2006-06-27 at 16:11 +0200, Torsten Michelmann wrote:
> > > Hi Chris,
> > > 
> > > thank you for the pointer to the RowHandler interface.
> > > I had a look at the API and I have to admit that I don't completely
> get
> > it how I would have to implement a RowHandler that would create the
> List.
> > > Because my understanding is that the RowHandler is state- and context
> > less. This means that I would have to use some global static object to
> store
> > my results from the processed lines which I regard as highly
> undesirable.
> > > But most probably I am missing something, could you please shed some
> > more light on this topic?
> > > 
> > > Thanks a lot in advance.
> > > 
> > > 
> > > (P.S. I checked the Developer Guide and it seems that the RowHandler
> > example at p.59 is not completely up to date with regard to the current
> API as
> > it contains (Object,List) in the method signature of handleRow which
> does
> > not exist anymore (or is deprecated, not sure) in the current API.)
> > > 
> > > 
> > > -------- Original-Nachricht --------
> > > Datum: Fri, 23 Jun 2006 14:28:29 -0600
> > > Von: Chris Lamey <clamey@localmatters.com>
> > > An: user-java@ibatis.apache.org, user-java@ibatis.apache.org
> > > Betreff: RE: Problem populating a List using groupBy
> > > 
> > > > Heya,
> > > > 
> > > > This doesn't address your question directly, but is some background
> > for
> > > > you.  I am also using iBATIS for the first time in a small but
> > somewhat
> > > > complex schema.  Along the way I tried using the groupBy support in
> > the SqlMap
> > > > xml but gave up and went to the RowHandler callback.  The RowHandler
> > is so
> > > > much easier to work with because of the complete control over what
> > result
> > > > columns go into which object and what Collection gets which objects.
> > I've
> > > > got SQL that joins across multiple tables, recursive joins, outer
> > joins, and
> > > > other wacky stuff and the groupBy support was a little too imprecise
> > for
> > > > me.  There's also a bug in 2.1.7 with nested columns in a resultMap,
> > which I
> > > > think I hit...
> > > > 
> > > > Anyway, when I wrote to this list about my saga, I was directed at
> > > > RowHandler and it made my year.
> > > > 
> > > > Cheers,
> > > > Chris
> > > > 
> > > > 
> > > > -----Original Message-----
> > > > From: Torsten Michelmann [mailto:torsten.michelmann@gmx.de]
> > > > Sent: Fri 6/23/2006 8:54 AM
> > > > To: user-java@ibatis.apache.org
> > > > Subject: Problem populating a List using groupBy
> > > >  
> > > > Hi folks,
> > > > 
> > > > again me (seems that I am touching all the rather complicated topics
> > of
> > > > iBatis during my very first project).
> > > > The problem is appearing while I try to avoid an N+1 select for a
> 1:M
> > > > relationship (as described on p. 36 in the latest developer guide).
> > > > I think that I may be using the groupBy attribute in an incorrect
> way
> > but
> > > > I am not sure how it has to be done correctly. (I tried using
> > groupBy="ID"
> > > > as well as groupBy="id" but that returned the same error).
> > > > 
> > > > com.ibatis.common.jdbc.exception.NestedSQLException:   
> > > > --- The error occurred in global/persistence/mom/MOM_SqlMap.xml.  
> > > > --- The error occurred while applying a result map.  
> > > > --- Check the MOM.r_getCustomerOrder.  
> > > > --- The error happened while setting a property on the result
> object. 
> > > > --- Cause: com.ibatis.common.beans.ProbeException: Could not set
> > property
> > > > 'customerOrderItemsList' for
> > global.persistence.mom.CustomerOrderMapper. 
> > > > Cause: java.lang.NullPointerException
> > > > Caused by: java.lang.NullPointerException
> > > > Caused by: com.ibatis.common.beans.ProbeException: Could not set
> > property
> > > > 'customerOrderItemsList' for
> > global.persistence.mom.CustomerOrderMapper. 
> > > > Cause: java.lang.NullPointerException
> > > > Caused by: java.lang.NullPointerException
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:188)
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
> > > > 	at
> > > >
> >
> com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70)
> > > > 
> > > > 
> > > > //The mapping
> > > > 	<resultMap id="r_getCustomerOrder" class="CustomerOrderMapper"
> > > > groupBy="orderItemKey.articleKey.articleId">
> > > > 		<result property="objectId" column="ID" />
> > > > 		<result property="comment" column="COMMENT" />
> > > > 		<result property="mom" column="IS_MOM" />
> > > > 		<result property="kimStatus" column="KIMSTATUS" />
> > > > 		<result property="customerOrderKey.customerId"
> column="CUSTOMER_ID"
> > />
> > > > 		<result property="customerOrderKey.orderId" column="ORDERID" />
> > > > 		<result property="customerOrderKey.version" column="VERSION" />
> > > > 		<result property="customerOrderKey.moduleKey.moduleId"
> > > > column="MODULE_ID" />
> > > > 		<result property="customerOrderKey.collectionKey.seasonId"
> > > > column="SAISON" />
> > > > 		<!-- <result
> > > > property="customerOrderKey.collectionKey.collectionCategoryId"
> > column="SEGMENT" />  not existant within MOM-->
> > > > 		<result property="customerOrderKey.collectionKey.segmentId"
> > > > column="SEGMENT" />
> > > > <!-- 	<result property="customerOrderItemsList" column="{id=ID}"
> > > > select="getCustomerOrderItem" />  -->
> > > > 		<result property="customerOrderItemsList"
> > > > resultMap="MOM.r_getCustomerOrderItem" /> 
> > > > 	</resultMap>
> > > > 	<resultMap id="r_getOrderItemBase" class="OrderItemBase">
> > > > 		<!-- <result property="objectId" column="" />  -->
> > > > 		<!-- <result property="salesPrice" column="" />  -->
> > > > 		<!-- <result property="recommendedRetailPrice" column="" />
 -->
> > > > 		<!-- <result property="currency" column="" />  -->
> > > > 		<result property="orderItemKey.articleKey.articleId"
> > > > column="ARTICLE_NUM" />
> > > > 		<result property="orderItemKey.articleColourKey.articleColourId"
> > > > column="COLOUR" />
> > > > 		
> > > > 	</resultMap>
> > > > 	<resultMap id="r_getOrderItem" class="OrderItem"
> > > > extends="r_getOrderItemBase">
> > > > 		<result property="orderedQuantity" column="ORDERED_QUANTITY"/>
> > > > 	</resultMap>
> > > > 	<resultMap id="r_getCustomerOrderItem" class="CustomerOrderItem"
> > > > extends="r_getOrderItem">
> > > > 		<result property="size" column="ARTICLE_SIZE" />
> > > > 		<result property="length" column="ARTICLE_LENGTH" />
> > > > 	</resultMap>
> > > > 
> > > > //The query 
> > > > 			SELECT c.ID, c.COMMENT, c.KIMSTATUS, c.CUSTOMER_ID, c.ORDERID,
> > > > c.VERSION, c.MODULE_ID, c.SAISON, c.SEGMENT, c.IS_MOM,
> a.ARTICLE_NUM,
> > d.COLOUR,
> > > > d.ORDERED_QUANTITY,e.ARTICLE_SIZE, e.ARTICLE_LENGTH
> > > > 			FROM
> > > > 				MENU.ARTICLE a inner join MENU.ARTICLE2MENUORDER b on
> > > > a.ARTICLE_NUM=b.ARTICLE_NUM
> > > > 	            inner join MENU.MENUORDER c on b.MENUORDER_ID=c.ID
> > > > 	            left outer join MENU.COLOUR2ARTICLE d on
> d.ART2MO_ID=b.ID
> > > > 	            left outer join MENU.SIZE2ARTICLE e on d.ART2MO_ID=b.ID
> > > > 	        WHERE 
> > > > 	        	c.ID=#objectId#			
> > > > 
> > > > 
> > > > //Customer Order is providing only methods access an Array, thus the
> > > > Wrapper. I have provided this class in order to allow you to ensure
> > that I am
> > > > not missing anything in here.
> > > > public class CustomerOrderMapper extends CustomerOrder {
> > > >     public void setCustomerOrderItemsList(List
> pCustomerOrderItemList)
> > {
> > > >         if (pCustomerOrderItemList.size() > 0) {
> > > >             CustomerOrderItem[] coi= (CustomerOrderItem[])
> > > > pCustomerOrderItemList.toArray(new
> > CustomerOrderItem[pCustomerOrderItemList.size()]);
> > > >             setCustomerOrderItems(coi);
> > > >         }
> > > >     }
> > > > 
> > > >     public List getCustomerOrderItemsList() {
> > > >         if(getCustomerOrderItems()==null)
> > > >         {
> > > >             return new ArrayList();
> > > >         }
> > > >         else
> > > >         {
> > > >             return Arrays.asList(getCustomerOrderItems());
> > > >         }
> > > >     }
> > > > }
> > > > 
> > > > 
> > > > 
> > > > 
> > > > -- 
> > > > Gruß
> > > > Torsten Michelmann
> > > > 
> > > > "Feel free" - 10 GB Mailbox, 100 FreeSMS/Monat ...
> > > > Jetzt GMX TopMail testen: http://www.gmx.net/de/go/topmail
> > > > 
> > > 
> 
> -- 
> Gruß
> Torsten Michelmann
> 
> Echte DSL-Flatrate dauerhaft für 0,- Euro*!
> "Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl

-- 
Greetings
Torsten

Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

Mime
View raw message