在 MyBatis-Plus 中實現表關聯查詢、嵌套查詢和子查詢,通常需要結合 XML 映射文件或 @Select
注解編寫自定義 SQL。以下是具體示例演示:
示例場景
假設有兩張表:
- 用戶表
user
CREATE TABLE user (id BIGINT PRIMARY KEY,name VARCHAR(50),age INT );
- 訂單表
order
CREATE TABLE order (id BIGINT PRIMARY KEY,user_id BIGINT, -- 關聯用戶IDamount DECIMAL(10,2),status INT );
1. 表關聯查詢(JOIN)
目標:查詢訂單信息并關聯用戶名
使用 XML 方式實現:
<!-- OrderMapper.xml -->
<select id="selectOrdersWithUser" resultType="map">SELECT o.id, o.amount, u.name AS userNameFROM `order` oLEFT JOIN `user` u ON o.user_id = u.idWHERE o.status = 1
</select>
2. 嵌套查詢(Nested Query)
目標:查詢用戶及其所有訂單(一對多)
使用 @Select
注解和 @Result
映射:
// UserMapper.java
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({@Result(property = "id", column = "id"),@Result(property = "orders", column = "id", many = @Many(select = "selectOrdersByUserId"))
})
User selectUserWithOrders(Long id);@Select("SELECT * FROM `order` WHERE user_id = #{userId}")
List<Order> selectOrdersByUserId(Long userId);
3. 子查詢(SubQuery)
目標:查詢訂單金額超過平均金額的訂單
使用 QueryWrapper
實現:
// 子查詢:計算平均金額
QueryWrapper<Order> avgWrapper = new QueryWrapper<>();
avgWrapper.select("AVG(amount)");// 主查詢:篩選大于平均金額的訂單
QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.gt("amount", avgWrapper); // 直接嵌入子查詢List<Order> orders = orderMapper.selectList(wrapper);
生成的 SQL:
SELECT * FROM `order`
WHERE amount > (SELECT AVG(amount) FROM `order`)
4. EXISTS 子查詢
目標:查詢有訂單的用戶
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.exists("SELECT 1 FROM `order` WHERE user_id = user.id");List<User> users = userMapper.selectList(wrapper);
生成的 SQL:
SELECT * FROM user
WHERE EXISTS (SELECT 1 FROM `order` WHERE user_id = user.id)
5. IN 子查詢
目標:查詢狀態為1的訂單所屬用戶
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "SELECT user_id FROM `order` WHERE status = 1");List<User> users = userMapper.selectList(wrapper);
生成的 SQL:
SELECT * FROM user
WHERE id IN (SELECT user_id FROM `order` WHERE status = 1)
關鍵點總結
查詢類型 | 實現方式 |
---|---|
關聯查詢 | 使用 JOIN + XML/注解手動映射結果 |
嵌套查詢 | 通過 @Result(many=@Many) 或 @Result(one=@One) 關聯其他 Mapper 方法 |
子查詢 | 利用 QueryWrapper 的 gt/inSql/exists 等方法直接嵌入子查詢 SQL |
復雜子查詢 | 在 XML 中手寫完整的 SQL 語句(推薦復雜場景) |
注意:
- MyBatis-Plus 的 Wrapper 僅支持簡單子查詢,復雜關聯查詢建議使用 XML/注解。
- 嵌套查詢可能引發 N+1 問題,大數據量時慎用。
- 表名/字段若為 SQL 關鍵字(如
order
),需用反引號`
包裹。