对iBatis的循环敬意

时间:2012-03-06 17:12:04

标签: java ibatis mybatis

我有两个班级:

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中没有任何内容。

我该如何解决? 感谢

1 个答案:

答案 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将检测循环并将两个对象链接在一起。