mybatis多表查询
对之前的mybatis多表查询做xml方式的补充
多表查询有哪些情况
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();
更多推荐



所有评论(0)