Open GoogleCodeExporter opened 8 years ago
You can extend one <resultMap> with another, just like you can Inherit from
another object in code.
<resultMap id="BaseClassMap" class="YourClass">
<result property="ID" column="ID" />
<result property="Name" column="Name" />
</resultMap>
<resultMap id="ExtendedClassMap" class="YourClass2" extends="BaseClassMap">
<result property="PhoneNumber" column="PhoneNumber" />
</result>
I do this all the time and there is normally very little to no repetition of
<result> objects.
Original comment by consultc...@gmail.com
on 31 Aug 2010 at 6:47
@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.
Original comment by sodhi.b@gmail.com
on 1 Sep 2010 at 1:15
It'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?
Original comment by consultc...@gmail.com
on 1 Sep 2010 at 6:44
Lets 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 <sql/> and <include/> would work well in such a case.
Original comment by sodhi.b@gmail.com
on 2 Sep 2010 at 2:49
I guess I don't entirely understand the need for what you're asking. In your
case I would have the following SQL map:
<sqlMap namespace="Product">
<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>
</sqlMap>
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 :)
Original comment by consultc...@gmail.com
on 2 Sep 2010 at 7:58
Thanks consultcory! What you mentioned works well (and such I have used) for
situations where queries don't change much. Consider the following queries:
<select id="FindDetails" parameterClass="string" resultMap="ProductDetails">
SELECT prod_id, name, foo, bar FROM products WHERE name LIKE '%CPU%'
</select>
<select id="Search2" parameterClass="ProductSearchInput"
resultMap="ProductSearchResultItem">
SELECT p.*, s.* FROM products p, store_items s WHERE p.prod_id=s.prod_id
<dynamic prepend='AND'>
<!-- Dynamic conditions go here -->
</dynamic>
</select>
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
<sql/>, <include/> would provide a cleaner solution to "refactor" the result
maps, because it would allow the reuse of <result/> fragments without the need
of inheritance of <resultMap/> and the mapped classes. I hope this clarifies
the situation better.
Original comment by sodhi.b@gmail.com
on 3 Sep 2010 at 4:15
Original issue reported on code.google.com by
sodhi.b@gmail.com
on 7 Aug 2010 at 2:34