襄阳手机网站建设网页搜索
多表查询有哪些情况
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 oINNER JOIN user u ON u.id = o.user_idWHERE 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 oLEFT 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 oLEFT 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();