多表查询有哪些情况

Mybatis 支持多表查询,常见的多表查询方式包括使用嵌套查询和关联查询

嵌套查询

嵌套查询是指在 SQL
语句中嵌套另外一个查询语句,可以用于在一个表中查询与另一表相关的数据。例如,在一个订单表中同时需要查询该订单所属用户的信息,可以使用嵌套查询。

假设我们有两个表,orders 表和 user 表,orders 表中有一个 user_id 字段,对应着 user 表中的 id 字段,下面是查询某个订单和对应的用户信息的 SQL 语句:

SELECT o.*, u.*
FROM orders o
INNER JOIN user u ON u.id = o.user_id
WHERE o.order_no = '001'

这里使用了 INNER JOIN 进行内连接,将 orders 表和 user 表连接在一起,查询条件为 o.order_no = ‘001’。SELECT 语句中指定了要返回的字段,由于两个表中可能有重复的字段,所以用 o.* 和 u.* 表示要返回的所有字段

在 Mybatis 中实现嵌套查询可以使用 resultMap 标签来定义查询结果映射,下面是一个示例:

<resultMap id="orderUserMap" type="Order">
    <id property="id" column="id"/>
    <result property="orderNo" column="order_no"/>
    <!-- 其他订单相关字段 -->
    <association property="user" javaType="User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <!-- 其他用户相关字段 -->
    </association>
</resultMap>

<select id="selectOrderWithUser" resultMap="orderUserMap">
    SELECT o.*, u.*
    FROM orders o
    INNER JOIN user u ON u.id = o.user_id
    WHERE o.order_no = #{orderNo}
</select>

其中, 定义了 Order 类和 User 类的属性映射,关键字 id 表示主键property 指定类属性名column 指定字段对应的列名

在 resultMap 中使用 标签来表示一个查询结果需要关联另外一个对象,这里用于关联订单和用户。property 指定类属性名,javaType 指定关联对象的类型,其他属性映射同上。

最后,在 中使用 resultMap 属性绑定映射关系,#{orderNo} 表示动态参数。

关联查询

关联查询是常用的一种多表查询方式,可以使用 Mybatis 提供的关联标签来实现。

假设我们有两个表,orders 表和 user 表,orders 表中有一个 user_id 字段,对应着 user 表中的 id 字段,下面是查询所有订单及对应用户的 SQL 语句:

SELECT o.*, u.*
FROM orders o
LEFT JOIN user u ON u.id = o.user_id

这里使用 LEFT JOIN 进行左连接,将 orders 表和 user 表连接在一起,查询所有记录。由于有可能存在订单没有对应用户,所以需要使用左连接进行查询。

在 Mybatis 中实现关联查询可以使用 association 和 collection 标签,它们分别用于表示一对一关联和一对多关联关系。下面我们分别来看一下:

一对一关联查询

首先定义 Order 类和 User 类,其中 Order 类中有一个 user 属性:

public class Order {
    private Integer id;
    private String orderNo;
    private Integer userId;
    private User user;
    // 省略 getter/setter
}

定义 OrderMapper 接口:

public interface OrderMapper {
    List<Order> selectAllOrdersWithUser();
}

然后在 OrderMapper.xml 文件中实现多表查询:

<select id="selectAllOrdersWithUser" resultMap="orderWithUserMap">
    SELECT o.*, u.*
    FROM orders o
    LEFT JOIN user u on u.id = o.user_id
</select>

<resultMap type="Order" id="orderWithUserMap">
    <id column="id" property="id"/>
    <result column="order_no" property="orderNo"/>
    <!-- 其他订单相关字段 -->
    <association property="user" column="user_id" javaType="User" select="selectUserById"/>
</resultMap>

<select id="selectUserById" parameterType="int" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

其中,resultMap 定义了 Order 类的属性映射使用 <association> 标签表示一对一关联column 表示关联条件字段select 表示关联查询的 SQL 语句

在上述示例中,我们定义了 selectUserById 这个查询语句,用于根据用户 id 查询用户信息。在 association 标签中指定了 select 属性后,Mybatis 会自动根据这个语句进行关联查询。

最后,我们只需要在 OrderMapper 接口中调用 selectAllOrdersWithUser() 方法即可完成多表查询:

List<Order> orders = orderMapper.selectAllOrdersWithUser();

一对多关联查询

在一对多关联查询中,需要定义一个中间表来存储两个实体之间的关联,例如定义 Order 类OrderItem 类,中间表是 order_item

首先定义 OrderItem 类和 Order 类,其中 Order 类中有一个 orderItems 属性

public class OrderItem {
    private Integer id;
    private Integer orderId;
    private String itemName;
    private Double itemPrice;
}

public class Order {
    private Integer id;
    private String orderNo;
    private List<OrderItem> orderItems;
    // 省略 getter/setter
}

定义 OrderMapper 接口:

public interface OrderMapper {
    List<Order> selectAllOrdersWithItems();
}

然后在 OrderMapper.xml 文件中实现多表查询:

<select id="selectAllOrdersWithItems" resultMap="orderWithItemsMap">
    SELECT o.*, oi.*
    FROM orders o
    LEFT JOIN order_item oi on oi.order_id = o.id
</select>

<resultMap type="Order" id="orderWithItemsMap">
    <id column="id" property="id"/>
    <result column="order_no" property="orderNo"/>
    <!-- 其他订单相关字段 -->
    <collection property="orderItems" ofType="OrderItem" >
        <id column="id" property="id"/>
        <result column="item_name" property="itemName"/>
        <result column="item_price" property="itemPrice"/>
        <association property="order" column="order_id" javaType="Order" select="selectAllOrdersWithItems"/>
    </collection>
</resultMap>

其中,resultMap 定义了 Order 类的属性映射,使用 <collection> 标签表示一对多关联,column 表示关联条件字段,select 表示关联查询的 SQL 语句。

在上述示例中,我们定义了 selectAllOrdersWithItems 这个查询语句,用于查询所有订单和订单明细信息。在 <collection> 标签中指定了 select 属性后,Mybatis 会自动根据这个语句进行关联查询。

最后,我们只需要在 OrderMapper 接口中调用 selectAllOrdersWithItems() 方法即可完成多表查询:

List<Order> orders = orderMapper.selectAllOrdersWithItems();

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐