如何基于MyBatis中的列值动态选择resultMap

时间:2018-08-01 03:04:22

标签: mybatis

我有一个来自数据库的resultSet,它返回如下两条记录

TRANID Type Name Amount
1      B    ABC  100.00
1      S    XYZ  -100.00

以上数据代表涉及卖方和买方的交易。

现在,我需要将上述结果集映射到MyBatis,以便它在以下结构中返回我一个交易对象。

Transaction :{
    id : 1,
    buyer:{
       name : "ABC",
       Amt : "100.00"
    },
    seller: {
       name: "XYZ",
       Amt: "-100.00"
    }
}

如果数据库已在一行中返回了数据,而买方和卖方数据都在一个维度上,例如

TRANID BNAME BAMOUNT SNAME SAMOUNT
1      ABC   100.00  XYZ   -100.00

然后我可以使用类似下面的结果图

<resultMap id="transactionRM" type="Transaction">
 <id property="id" column="TRANID"/>
 <association property="buyer" type="User">
   <result property="name" column="BNAME"/>
   <result propert="amt" column="BAMT"/>
 </association>
 <association property="seller" type="User">
   <result property="name" column="SNAME"/>
   <result propert="amt" column="SAMT"/>
 </association>
</resultMap>

我将能够实现自己想要的目标,因为对于买卖双方,我拥有唯一的别名/列名。

但是,如果结果出现在两行中,其中一个是买方和卖方,而type是一个判别器,则我将如何获得相同的结果,该标识符确定该行是属于卖方还是买方。

我试图为User定义一个resultMap,例如

<resultMap id ="buyerRM" type ="User">
   <result property="name" column="Name"/>
   <result property="amt" column="Amount"/>
</resultMap>

<resultMap id ="sellerRM" type ="User">
   <result property="name" column="Name"/>
   <result property="amt" column="Amount"/>
</resultMap>

<resultMap id="transacionRM" type="Transaction">
  <association property="buyer" resultMap="buyerRM" type="User"/>
  <association property="seller" resultMap="sellerRM" type="User">
</resultMap>

上面的结果图不起作用,因为为买卖双方定义的列名称相同,并且数据将重复。

任何建议。

谢谢。

2 个答案:

答案 0 :(得分:1)

关联仅适用于单行。您可以使用收藏与您所需要的东西最接近。

<resultMap id="transactionRM" type="Transaction">
 <id property="id" column="TRANID"/>
 <collection property="users" type="User">
   <result property="type" column="Type"/>
   <result property="name" column="Name"/>
   <result property="amt" column="Amount"/>
 </collection>
</resultMap>

这将返回具有属性id和属性users单个对象。后者是List<User>,在这种情况下,它将具有两个元素(每行一个)。不完全是您想要的,而是关闭。

您需要将List<User>转换为两个单独的属性。

答案 1 :(得分:1)

未经查询修改就无法在mybatis 3.4.6中映射它。

如果您要修改查询,则有几个选项。

自我加入

可以将原始查询转换为通过事务ID列进行自我连接。这样,您将在每笔交易中排成一行,并可以按照问题中的描述进行映射。

列重命名

可以映射跨越多行的关联。对象数据可能跨越多行。 Mybatis使用id映射元素将行数据映射到对象,也就是说,具有相同id值的行属于同一对象,因此,来自它们的数据将用于填充构造的对象(是否为从属项目)属于收藏或协会)。

如果您可以包装原始查询或直接对其进行修改以根据类型将值设置到不同的列中,则可以这样做。

通过包装,我的意思是:

select
    TRANID,
    case Type when 'S' then Name else null end as seller_name,
    case Type when 'S' then Amount else null end as seller_amount,
    case Type when 'B' then Name else null end as buyer_name,
    case type when 'B' then Amount else null end as buyer_amount
from (
   -- original query goes here
)

并像这样映射它:

<resultMap id ="userRM" type ="User">
   <result property="name" column="name"/>
   <result property="amount" column="amount"/>
</resultMap>

<resultMap type="Transaction" id="twoRowMap">
    <id column="TRANID" property="id"/>
    <association property="buyer" resultMap="userRM" columnPrefix="BUYER_"/>
    <association property="seller" resultMap="userRM" columnPrefix="SELLER_"/>
</resultMap>

请注意,由于mybatis中的错误,您需要在映射中使用大写字母指定columnPrefix

这将选择一个具有正确设置的Transactionbuyer属性的seller对象。

相关问题