mybatis嵌套结果使用

好记性不如烂笔头,好久不写mapper文件,都不会写了,还要现查,所以还是记下来的好。

嵌套结果:2表关联,在sql中,可能是2条或多条记录,然后mybatis自己组装,返回结果集可能只有1条。
嵌套结果优点,应用层组装,只查一次,而非嵌套多次查询。

继承的话,如果用lombok的@Data话,记得用上@ToString(callSuper = true),要不然在集合类中,toString()可能出问题,默认的toString()方法只有子类的属性,没有父类属性
domain

import lombok.Data;
import lombok.ToString;

@Data
@ToString(callSuper = true)
public class InnerTxDo extends InnerTx implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    private String bizType;
	...
    private List<InnerItem> innerItemList;
}
@Data
public class InnerItem implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long       id;
    private Long       innerTxId;
    ...
    private BigDecimal amount;
}

@Data
public class InnerTxParam implements Serializable {
    private static final long serialVersionUID = 1L;
    private String       startTime;
    private String       endTime;
    private List<String> fromAddressList;
}

mapper.java

public interface InnerTxMapper extends BaseMapper<InnerTx> {
    List<InnerTxDo> queryInnerTxList(InnerTxParam innerTxParam);
}

mapper.xml

<mapper namespace="com.*.dao.InnerTxMapper">
    <resultMap id="BaseResultMap" type="com.*.domain.InnerTxDo">
        <id column="id" jdbcType="BIGINT" property="id"/>
        <result column="biz_type" jdbcType="VARCHAR" property="bizType"/>
        <result column="amount" jdbcType="NUMERIC" property="amount"/>
        <collection property="innerItemList" ofType="com.*.domain.InnerItem">
            <result column="inner_item_id" jdbcType="VARCHAR" property="id"/>
            <!-- 两张表中都有amount字段,如果不起别名的话,会取值错误 -->
            <result column="inner_item_amount" jdbcType="NUMERIC" property="amount"/>
        </collection>
    </resultMap>

    <select id="queryInnerTxList" resultMap="BaseResultMap"
            parameterType="com.*.domain.InnerTxParam">
        SELECT t.id,t.biz_type,t.amount,ii.id inner_item_id, ii.pay_type,ii.amount inner_item_amount
        FROM t_inner_tx t Left JOIN t_inner_item ii on t.id=ii.inner_tx_id
        WHERE t.chain = #{chain}
        <if test="startTime !=null and startTime !='' ">
            and t.create_time  <![CDATA[>= ]]>  #{startTime}
        </if>
        <if test="endTime !=null and endTime!='' ">
            and t.create_time <![CDATA[ <= ]]> #{endTime}
        </if>
        <if test="fromAddressList != null and fromAddressList.size()>0">
            AND  t.from_address IN
            <foreach item="item" index="index" collection="fromAddressList" open="("
                     separator="," close=")">
                #{item}
            </foreach>
        </if>
    </select>

</mapper>
### MyBatis嵌套查询与嵌套结果的区别 #### 嵌套查询 嵌套查询是指在一个 SQL 查询中执行另一个独立的 SQL 查询来获取关联数据。这种方式通常用于处理复杂的一对多或多对多关系,其中每次都需要单独发起额外的数据库请求。 ```java @Test public void testOrderWithUser(){ // 获取会话对象并创建 Mapper 接口实例 try(SqlSession sqlSession = MybatisUtils.getSession()){ OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); // 调用带有嵌套查询的方法 List<Orders> orders = mapper.findAllWithUser1(); // 输出订单及其对应的用户信息 for (Orders order : orders) { System.out.println(order); } } } ``` 此代码片段展示了如何通过 `findAllWithUser1` 方法实现基于用户的订单列表查询[^4]。每当需要加载某个特定实体的相关联实体时,都会触发新的 SQL 请求去检索这些子项的数据。 然而需要注意的是,这种做法可能会导致 N+1 的问题——即初始查询加上针对每一行记录所发出的附加查询,从而增加了不必要的网络往返次数和整体延迟时间[^2]。 #### 嵌套结果 相比之下,嵌套结果则是指利用单一 SQL 语句完成所有必要的连接操作,并一次性返回完整的结构化数据集给应用程序层面上的应用逻辑进行解析。这有助于减少对外部资源(如 RDBMS)的压力以及提高响应速度。 ```xml <!-- resultMap 定义 --> <resultMap id="orderResultMap" type="com.example.Orders"> <!-- 主表字段映射 --> <id property="orderId" column="ORDER_ID"/> <!-- 关联对象映射 --> <association property="user" javaType="com.example.User"> <id property="userId" column="USER_ID"/> ... </association> </resultMap> <select id="findOrdersWithUsers" resultMap="orderResultMap"> SELECT o.*, u.* FROM Orders o JOIN Users u ON o.USER_ID = u.ID; </select> ``` 上述 XML 片段定义了一个名为 `orderResultMap` 的 Result Map 来描述怎样把来自两个不同表格 (`Orders`, `Users`) 的列组合成 Java 类型的对象属性。这里使用了 `<association>` 标签指定一对一的关系;而对于一对多的情形,则可以采用类似的 `<collection>` 元素[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值