问题描述
我有两节课:
class Apple {
Worm worm;
}
class Worm {
Apple apple;
}
它们以1:1方式存储在db中:
They are stored in db in 1:1 fashion:
table Apple(id, wormId)
table Worm(id)
每个苹果只有一个蠕虫,反之亦然.
Each apple has only one worm and vice versa.
使用iBatis,我可以轻松做到这一点:
With out of iBatis I can do it simply:
Worm worm = new Worm();
Apple apple = new Apple();
worm.setApple(apple);
apple.setWorm(worm);
我该如何在ibatis中做这件事?
How can I do it in 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>
所以,我希望能够做到:
So, I want to be able to do:
Apple apple = foo.queryForObject("getApple", 42L);
Worm = worm.getApple();
Apple appleAgain = apple.getWorm().getApple();
// apple == appleAgain here
相反,我得到StackOverFlowException,因为struts永远调用getWormByApple/getApple.
Instead, I get StackOverFlowException because struts calls getWormByApple / getApple forever.
我在这里只看到一种解决方案:
I see only one solution here:
class Apple {
void setWorm(Worm worm){
this.worm = worm;
worm.setApple(this);
}
...并从蠕虫resultMap中删除"property ="apple".
...and remove "property="apple"" from Worm resultMap.
但是很糟糕,因为我必须记住哪个设置器更新参数,而with不是.这也很糟糕,因为如果Worm的setter更改参数,可能会导致无限循环.
But it sucks because I would have to remember which setters update argument and with is not. It also bad because may lead to infinite loop in case when Worm's setter would change argument.
我也不想用我的模型类修复" iBatis泄漏(即,我根本不想碰我的模型bean).
I also do not want to "fix" iBatis leaks with my model classes (i.e. I do not want to touch my model beans at all).
最好有某种后处理器":
It would be nice to have some kind of "post processor":
<resultMap id="Apple" type="Apple">
<result property="id" column="id"/>
<result property="worm" select="getWormByApple"/>
<result property="worm.apple" postProcessor="appleToWormSetter"/>
</resultMap>
但是iBatis中没有任何内容.
but there is no any in iBatis.
我该如何解决?谢谢
推荐答案
MyBatis自动解决循环引用.试试这个:
MyBatis solves circular references automatically. Try this:
<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将检测循环并将两个对象链接在一起.
Note that in this case MyBatis will detect the cycle and link both objects together.
这篇关于iBatis中的循环敬拜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!