
mybatisnet - issue #6
Support for inclusion of <result> fragments into <resultMap> elements
What version of the MyBatis.NET are you using? IBatis.DataMapper.1.6.2
Please describe the problem. Unit tests are best! This is an enhancement request. I would like iBATIS to support <include/> kind of functionality for the <resultMap/> and <parameterMap/> elements -- Something similar to what iBATIS already provides for <statement/> tags family via <sql/> and <include/> tags.
What is the expected output? What do you see instead?
Please provide any additional information below. There are use cases where I have to map the results of different SELECT queries into objects which do not form any inheritance hierarchy, though these objects do share some properties (and unfortunately, their inheritance line cannot be changed), and this leads to a lot of repetition of <result/> elements in different <resultMap/>s. If I could have a feature similar to <sql/> and <include/> working for result/parameter maps as well, then it will really help in keeping the XML concise.
Comment #1
Posted on Aug 31, 2010 by Happy WombatYou can extend one with another, just like you can Inherit from another object in code.
I do this all the time and there is normally very little to no repetition of objects.
Comment #2
Posted on Sep 1, 2010 by Quick Wombat@consultcory: Your solution requires that the mapped classes should form an inheritance hierarchy. As I mentioned in the description, it is not always possible to put the mapped objects into a hierarchy.
Comment #3
Posted on Sep 1, 2010 by Happy WombatIt's not necessarily true that the mapped classes are required to be part of an inheritance hierarchy. Sometimes I'll have a result map (a) that only sets some of the properties of an object, where another result map (b) that extends (a) sets more properties depending on the result of the query. Both (a) and (b) map to the same class.
I don't think your situation is typical. Are you trying to map to classes that you can't modify or don't have control over?
Comment #4
Posted on Sep 2, 2010 by Quick WombatLets say I have a class hierarchy that is similar to the one below:
ProductDetails -productId -name -foo -bar
ProductSearchInput : ProductDetails -stockCode -units
ProductSearchResultItem : ProductSearchInput -serialNum -storeId
This hierarchy cannot be changed due to various reasons. Now, we have different queries whose results (which have different columns for each query) need to be mapped to different classes from the above hierarchy. In such a situation, the resultMap extension mechanism won't work as you suggest.
A feature similar to the and would work well in such a case.
Comment #5
Posted on Sep 2, 2010 by Happy WombatI guess I don't entirely understand the need for what you're asking. In your case I would have the following SQL map:
<alias>
<typeAlias alias="ProductDetails" type="Company.Project.Domain.ProductDetails" />
<typeAlias alias="ProductSearchInput" type="Company.Project.Domain.ProductSearchInput" />
<typeAlias alias="ProductSearchResultItem" type="Company.Project.Domain.ProductSearchResultItem" />
</alias>
<resultMaps>
<resultMap id="ProductDetails" class="ProductDetails">
<result property="productId" column="ProductId" />
<result property="name" column="Name" />
<result property="foo" column="Foo" />
<result property="bar" column="Bar" />
</resultMap>
<resultMap id="ProductSearchInput" class="ProductSearchInput" extends="Product.ProductDetails">
<result property="stockCode" column="StockCode" />
<result property="units" column="Units" />
</resultMap>
<resultMap id="ProductSearchResultItem" class="ProductSearchResultItem" extends="Product.ProductSearchInput">
<result property="serialNum" column="SerialNum" />
<result property="storeId" column="StoreId" />
</resultMap>
</resultMaps>
<statements>
<select id="SelectProductDetails" parameterClass="int" resultMap="ProductDetails">
<!-- Query that returns columns or column aliases "ProductId," "Name," "Foo," and "Bar." -->
</select>
<select id="SelectProductSearchInput" parameterClass="ProductDetails" resultMap="SelectProductSearchInput">
...
</select>
<select id="SelectProductSearchResultItem" parameterClass="ProductSearchInput" resultMap="ProductSearchResultItem">
...
</select>
</statements>
The ProductSearchInput result map, when extending the Product.ProductDetails result map, will allow you to map to the four fields from the ProductDetails map and the two from the ProductSearchInput map, just as your ProductSearchInput class has access to the four fields from ProductDetails.
Likewise with the third result map. The ProductSearchResultItem will actually have all eight fields available to map to, not just the two you see in the map, because it extends the ProductSearchInput map which extends the ProductDetails map.
I didn't have to repeat any result properties anywhere in the SQL map. Maybe some sample queries would help clear things up for me, or maybe I'm just way off the path here. Help me help you :)
Comment #6
Posted on Sep 3, 2010 by Quick WombatThanks consultcory! What you mentioned works well (and such I have used) for situations where queries don't change much. Consider the following queries:
SELECT prod_id, name, foo, bar FROM products WHERE name LIKE '%CPU%'
SELECT p., s. FROM products p, store_items s WHERE p.prod_id=s.prod_id
Now, if I need to add (select) an additional property/column to ProductDetails (i.e. the query "FindDetails"), then all my queries where I use result maps deriving from the one used in "FindDetails" would break, unless I select the additional columns in all those "child queries" as well. Having something like , would provide a cleaner solution to "refactor" the result maps, because it would allow the reuse of fragments without the need of inheritance of and the mapped classes. I hope this clarifies the situation better.
Status: New
Labels:
Type-Defect
Priority-Low