首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何根据MyBatis中的列值动态选择resultMap

如何根据MyBatis中的列值动态选择resultMap
EN

Stack Overflow用户
提问于 2018-08-01 11:04:22
回答 1查看 1.8K关注 0票数 1

我有一个来自DB的resultSet,它返回两条记录,如下所示

代码语言:javascript
复制
TRANID Type Name Amount
1      B    ABC  100.00
1      S    XYZ  -100.00

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

现在我需要将上面的结果集映射到MyBatis,这样它就会以下面的结构返回一个事务对象。

代码语言:javascript
复制
Transaction :{
    id : 1,
    buyer:{
       name : "ABC",
       Amt : "100.00"
    },
    seller: {
       name: "XYZ",
       Amt: "-100.00"
    }
}

如果DB在一行中返回数据,并且买方和卖方数据都在一个维度中,例如

代码语言:javascript
复制
TRANID BNAME BAMOUNT SNAME SAMOUNT
1      ABC   100.00  XYZ   -100.00

然后,我可以使用如下所示的结果图

代码语言:javascript
复制
<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是确定该行属于卖方还是买方的鉴别器,我如何才能获得相同的结果。

我尝试为用户定义一个resultMap,比如

代码语言:javascript
复制
<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>

上面的结果映射将不起作用,因为为买方和卖方定义的相同列名和数据将被复制。

有什么建议吗。

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-08-02 16:30:47

如果不修改查询,就不可能在mybatis 3.4.6中映射这一点。

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

自加入

可以将原始查询转换为通过事务id列进行自连接。这样,您将为每个事务分配一行,并可以按照您的问题中的描述进行映射。

列重命名

可以映射跨越多行的关联。对象数据可以跨多行。Mybatis使用id映射元素将行数据映射到对象,即具有相同id值的行属于同一对象,因此来自这些行的数据用于填充构造的对象(无论它是属于集合还是关联的从属项)。

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

关于包装,我的意思是这样的:

代码语言:javascript
复制
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
)

并像这样映射它:

代码语言:javascript
复制
<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

这将选择一个正确设置了buyerseller属性的Transaction对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51624822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档