我有两个班级:
class Apple {
Worm worm;
}
class Worm {
Apple apple;
}
它们以1:1的方式存储在db中:
table Apple(id, wormId)
table Worm(id)
每个苹果只有一种蠕虫,反之亦然。
在iBatis之外,我可以做到这一点:
Worm worm = new Worm();
Apple apple = new Apple();
worm.setApple(apple);
apple.setWorm(worm);
我怎样才能在ibatis中完成?
<resultMap id="Apple" type="Apple">
<result property="id" column="id"/>
<result property="worm" column="id" select="getWormByApple"/>
</resultMap>
<resultMap id="Worm" type="Worm">
<result property="id" column="id"/>
<result property="apple" column="id" select="getAppleByWorm"/>
</resultMap>
<select id="getApple" resultMap="Apple" parameterClass="java.lang.Long">
SELECT * FROM Apples where id=#value#
</select>
<select id="getWormByApple" resultMap="Worm" parameterClass="java.lang.Long">
SELECT * FROM Worms where appleId=#value#
</select>
所以,我希望能够做到:
Apple apple = foo.queryForObject("getApple", 42L);
Worm = worm.getApple();
Apple appleAgain = apple.getWorm().getApple();
// apple == appleAgain here
相反,我得到了StackOverFlowException,因为struts会永远调用getWormByApple / getApple。
我在这里只看到一个解决方案:
class Apple {
void setWorm(Worm worm){
this.worm = worm;
worm.setApple(this);
}
...并从Worm resultMap中删除“property =”apple“”。
但它很糟糕,因为我必须记住哪个setter更新参数而不是。它也很糟糕,因为当Worm的setter改变参数时可能导致无限循环。
我也不想用我的模型类“修复”iBatis泄漏(即我根本不想触摸我的模型bean)。
拥有某种“后处理器”会很高兴:
<resultMap id="Apple" type="Apple">
<result property="id" column="id"/>
<result property="worm" select="getWormByApple"/>
<result property="worm.apple" postProcessor="appleToWormSetter"/>
</resultMap>
但iBatis中没有任何内容。
我该如何解决? 感谢
答案 0 :(得分:0)
MyBatis自动解决循环引用。试试这个:
<select id="x" resultMap="appleResult">
select apple.id, worm.id from apple join worm on apple.worm_id = worm.id
</select>
这两个结果图如下:
<resultMap id="appleResult" type="Apple">
<id column="apple.id" property="id"/>
<association property="worm" resultMap="wormResult">
</resultMap>
<resultMap id="wormResult" type="Worm">
<id column="worm.id" property="id"/>
<association property="apple" resultMap="appleResult">
</resultMap>
请注意,在这种情况下,MyBatis将检测循环并将两个对象链接在一起。