Mybits-plus 表关联查询,嵌套查询,子查询示例演示
在 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
),需用反引号`
包裹。