这个问题是ibatis的内部实现就是这样的,不过如果想得到你的效果的话很简单只需在Category类中的setProductList方法中写一个转换即可,如下
public void setProductList(Collection<Product> productList) {
if(productList!=null && productList.isEmpty())
productList= null;
this.productList= productList;
}
public void setProductList(Collection<Product> productList) {
if(productList!=null && productList.isEmpty())
productList= null;
this.productList= productList;
}
你为什么要使用left join呢?
<select id=”getCategory” parameterClass=”int” resultMap=”categoryResult”>
select C.CAT_ID, C.CAT_DESCRIPTION
from CATEGORY where CAT_ID = #value#
</select>这样就可以了,因为有<result property=”productList” resultMap=”ProductCategory.productResult“/>
这句话,所以你得到的Category对象中的productList属性会自动添充。
所以你的解决方案不管用。<resultMap id=”productResult” class=”com.ibatis.example.Product”>
<result property=”id” column=”PRD_ID”nullValue="0"/>
<result property=”description” column=”PRD_DESCRIPTION”nullValue="" />
</resultMap>
看你的查询语句得到的查询结果,你用left join的话,右侧没有对应的肯定是null,而你设置nullValue="0",结果会转化为0
那返回的值里面肯定包括0这个product的ID,你既然不想要结果,为何还要nullValue="0",这岂不是自相矛盾,去掉nullValue="0"
如果不加nullValue的话就报错了
还有一个问题,我数据库用的是mysql,在使用上面方法时使用了limit 0, 20。他们同时使用是有问题的,因为我想限制的是Catalog的记录,这个问题大家有什么好的解决方法?
给你个例子<sqlMap namespace="catelog">
<resultMap id="catelogResult" class="Catelog">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="catelogAttributeList" column="id"
select="catelogAttribute.findCatelogAttributeByCatelogId" />
</resultMap><select id="findCatelogById" parameterClass="int"
resultMap="catelogResult">
select id as id, name as name from CATELOG where id=#id#
</select></sqlMap>----------------------------------------------------------------------<sqlMap namespace="catelogAttribute"><resultMap id="catelogAttributeResult" class="CatelogAttribute">
<result property="id" column="id" />
<result property="catId" column="catId" />
<result property="attributeId" column="attributeId" />
</resultMap><select id="findCatelogAttributeByCatelogId"
parameterClass="int" resultMap="catelogAttributeResult">
select id as id, catId as catId, attributeId as attributeId from
CATELOGATTRIBUTE where catId = #catId#
</select>
</sqlMap>
<resultMap id="catelogResult" class="Catelog">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="catelogAttributeList" column="id"
select="catelogAttribute.findCatelogAttributeByCatelogId" />
</resultMap><select id="findCatelogById" parameterClass="int"
resultMap="catelogResult">
select id as id, name as name from CATELOG where id=#id#
</select></sqlMap>----------------------------------------------------------------------<sqlMap namespace="catelogAttribute"><resultMap id="catelogAttributeResult" class="CatelogAttribute">
<result property="id" column="id" />
<result property="catId" column="catId" />
<result property="attributeId" column="attributeId" />
</resultMap><select id="findCatelogAttributeByCatelogId"
parameterClass="int" resultMap="catelogAttributeResult">
select id as id, catId as catId, attributeId as attributeId from
CATELOGATTRIBUTE where catId = #catId#
</select>
</sqlMap>
如果一个Catelog包含n多的CatelogAttribute的时候,会执行n+1条sql语句
导致到n+1的问题,严重影响性能!
的确存在这个问题,特别是Product数量多的时候.<select id="findCatelogById" parameterClass="int"
resultMap="catelogResult">
select id as id, name as name from CATELOG where id=#id#
</select>
我比较喜欢在findCatelogById方法中,调用findProductListByCatelogId,然后set给Catelog的productList属性.个人习惯问题,我不喜欢写复杂的sql,如果必须要写的话,就建个视图吧.