Author: gbayon
Date: Sat Jan 20 11:31:19 2007
New Revision: 498157
URL: http://svn.apache.org/viewvc?view=rev&rev=498157
Log:
- Added N+1 select doc with groupBy attribute
Modified:
ibatis/trunk/cs/docs/dataAccessGuide/src/en/index.xml
ibatis/trunk/cs/docs/dataMapperGuide/src/en/index.xml
ibatis/trunk/cs/docs/dataMapperGuide/src/en/introduction.xml
ibatis/trunk/cs/docs/dataMapperGuide/src/en/working.xml
ibatis/trunk/cs/docs/doc.build
Modified: ibatis/trunk/cs/docs/dataAccessGuide/src/en/index.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/docs/dataAccessGuide/src/en/index.xml?view=diff&rev=498157&r1=498156&r2=498157
==============================================================================
--- ibatis/trunk/cs/docs/dataAccessGuide/src/en/index.xml (original)
+++ ibatis/trunk/cs/docs/dataAccessGuide/src/en/index.xml Sat Jan 20 11:31:19
2007
@@ -13,8 +13,8 @@
<bookinfo>
<title>iBATIS.NET - Data Access Objects Application Framework</title>
<subtitle>Data Access Objects Developer Guide</subtitle>
- <releaseinfo>Version 1.8.1</releaseinfo>
- <pubdate>July 2006</pubdate>
+ <releaseinfo>Version 1.9.0</releaseinfo>
+ <pubdate>January 2007</pubdate>
<authorgroup>
<author>
<firstname>Gilles</firstname>
Modified: ibatis/trunk/cs/docs/dataMapperGuide/src/en/index.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/docs/dataMapperGuide/src/en/index.xml?view=diff&rev=498157&r1=498156&r2=498157
==============================================================================
--- ibatis/trunk/cs/docs/dataMapperGuide/src/en/index.xml (original)
+++ ibatis/trunk/cs/docs/dataMapperGuide/src/en/index.xml Sat Jan 20 11:31:19
2007
@@ -14,8 +14,8 @@
<bookinfo>
<title>iBATIS.NET - DataMapper Application Framework</title>
<subtitle>DataMapper Developer Guide</subtitle>
- <releaseinfo>Version 1.5.1</releaseinfo>
- <pubdate>July 2006</pubdate>
+ <releaseinfo>Version 1.6.0</releaseinfo>
+ <pubdate>January 2007</pubdate>
<authorgroup>
<author>
<firstname>Ted</firstname>
Modified: ibatis/trunk/cs/docs/dataMapperGuide/src/en/introduction.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/docs/dataMapperGuide/src/en/introduction.xml?view=diff&rev=498157&r1=498156&r2=498157
==============================================================================
--- ibatis/trunk/cs/docs/dataMapperGuide/src/en/introduction.xml (original)
+++ ibatis/trunk/cs/docs/dataMapperGuide/src/en/introduction.xml Sat Jan 20
11:31:19 2007
@@ -42,6 +42,19 @@
</sect1>
<sect1>
+ <title>Release change log</title>
+
+ <sidebar>
+ <para><emphasis>Version 1.6.0</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ Resolution of N+1 select problem using groupBy attribute
+ </listitem>
+ </itemizedlist>
+ </sidebar>
+ </sect1>
+
+ <sect1>
<title>License Information</title>
<para>iBATIS.NET is licensed according to the terms of the Apache License,
Modified: ibatis/trunk/cs/docs/dataMapperGuide/src/en/working.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/docs/dataMapperGuide/src/en/working.xml?view=diff&rev=498157&r1=498156&r2=498157
==============================================================================
--- ibatis/trunk/cs/docs/dataMapperGuide/src/en/working.xml (original)
+++ ibatis/trunk/cs/docs/dataMapperGuide/src/en/working.xml Sat Jan 20 11:31:19
2007
@@ -1504,6 +1504,12 @@
result map to inherit all of the properties of the "super" resultMap
that it extends.</para>
</sect3>
+
+ <sect3>
+ <title>groupBy</title>
+
+ <para>The optional <parameter>groupBy</parameter> attribute specifies
a list of .NET properties names of the result object build by the resultMap.
Thera are used to identify unique rows in the returned result set. Rows with
equal values for the specified properties will only generate one result object.
Use groupBy in combination with nested resultMaps to solve the N+1 query
problem. Exemple : "Id" or "Desciption, Date".(see paragraph 3.5.13).</para>
+ </sect3>
</sect2>
<sect2>
@@ -2639,7 +2645,7 @@
large lists of data.</para>
<example>
- <title>N+1 Select Lists (1:M and M:N)</title>
+ <title>N+1 Select Lists (1:M and M:N), example of problem</title>
<programlisting>
<resultMaps>
@@ -2647,10 +2653,10 @@
<resultMap id="select-category-result" class="Category">
<result property="Id" column="CAT_ID"/>
<result property="Description" column="CAT_DESCRIPTION"/>
- <emphasis role="blue"><result property="ProductList" column="CAT_ID"
select="selectProductsByCatId"/></emphasis>
+ <emphasis role="blue"><result property="ProductList" column="CAT_ID"
select="selectProductsByCatId"/></emphasis>
</resultMap>
- <resultMap id="select-product-result" class="Product">
+ <resultMap id="Product-result" class="Product">
<result property="Id" column="PRD_ID"/>
<result property="Description" column="PRD_DESCRIPTION"/>
</resultMap>
@@ -2671,9 +2677,54 @@
</statements></programlisting>
</example>
- <para>1:N & M:N Solution? Currently the feature that resolves this
- issue not implemented, but the development discussions are active, and
- we expect it to be included in a future release.</para>
+ <para>iBATIS fully solves the N+1 selects problem. Here is the same
example solved :</para>
+
+ <example>
+ <title>N+1 Select Lists (1:M and M:N) resolution</title>
+
+ <programlisting>
+<sqlMap namespace="ProductCategory">
+<resultMaps>
+
+ <resultMap id="Category-result" class="Category" <emphasis
role="blue">groupBy="Id"</emphasis>>
+ <result property="Id" column="CAT_ID"/>
+ <result property="Description" column="CAT_DESCRIPTION"/>
+ <emphasis role="blue"><result property="ProductList"
resultMapping="ProductCategory.Product-result"/></emphasis>
+ </resultMap>
+
+ <resultMap id="Product-result" class="Product">
+ <result property="Id" column="PRD_ID"/>
+ <result property="Description" column="PRD_DESCRIPTION"/>
+ </resultMap>
+<resultMaps>
+
+<statements>
+
+ <emphasis role="comment"><!-- This statement executes 1 time
--></emphasis>
+ <statement id="SelectCategory" parameterClass="int"
resultMap="Category-result">
+ select C.CAT_ID, C.CAT_DESCRIPTION, P.PRD_ID, P.PRD_DESCRIPTION
+ from CATEGORY C
+ left outer join PRODUCT P
+ on C.CAT_ID = P.PRD_CAT_ID
+ where CAT_ID = #value#
+ </statement>
+
+</programlisting>
+ </example>
+
+<para>When you call...</para>
+<programlisting>IList myList = sqlMap.QueryForList("SelectCategory",
1002);</programlisting>
+<para>...the main query is executed, and the results are stored in the myList
variable containing .NET type
+"Category" element . Each object in that List will have a "ProductList"
property that is also a List
+populated from the same query, but using the "Product-result" result map to
populate the element in the child
+list. So, you end up with a list containing sub-lists, and only one database
query is executed.</para>
+<para>The important items here are the...</para>
+<para><emphasis role="term"><emphasis
role="blue">groupBy="Id"</emphasis></emphasis></para>
+<para>...attribute and the...</para>
+<para><emphasis role="term"><result property="ProductList" <emphasis
role="blue">resultMapping="ProductCategory.Product-result"</emphasis>/></emphasis></para>
+<para>...property mapping in the "Category-result" result map. One other
important detail is that the result mapping
+for the ProductList property is namespace aware - had it been simply
"Product-result" it would not work.
+Using this approach, you can solve any N+1 problem of any depth or
breadth.</para>
<sidebar>
<para><emphasis>Lazy Loading vs. Joins (1:M and M:N)</emphasis></para>
Modified: ibatis/trunk/cs/docs/doc.build
URL:
http://svn.apache.org/viewvc/ibatis/trunk/cs/docs/doc.build?view=diff&rev=498157&r1=498156&r2=498157
==============================================================================
--- ibatis/trunk/cs/docs/doc.build (original)
+++ ibatis/trunk/cs/docs/doc.build Sat Jan 20 11:31:19 2007
@@ -1,8 +1,8 @@
<?xml version="1.0" ?>
<project name="iBATIS.NET reference" default="refDoc" >
- <property name="project.dao.version" value="1.8.1"
unless="${property::exists('project.dao.version')}" />
- <property name="project.sqlMap.version" value="1.5.1"
unless="${property::exists('project.sqlMap.version')}" />
+ <property name="project.dao.version" value="1.9.0"
unless="${property::exists('project.dao.version')}" />
+ <property name="project.sqlMap.version" value="1.6.0"
unless="${property::exists('project.sqlMap.version')}" />
<property name="project.name" value="Data Access Guide" />