mybatisplus支持多表联查吗
时间: 2023-06-30 19:05:29 浏览: 133
是的,MyBatis-Plus可以支持多表联查。MyBatis-Plus提供了Lambda Query Wrapper和SQL Query Wrapper两种方式实现多表联查。
Lambda Query Wrapper方式:
```java
List<User> users = userMapper.selectList(new QueryWrapper<User>()
.select("user.id", "user.name", "order.order_no")
.eq("user.id", 1L)
.leftJoin("order", "user.id = order.user_id"));
```
SQL Query Wrapper方式:
```java
List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
.select(User::getId, User::getName, Order::getOrderNo)
.eq(User::getId, 1L)
.leftJoin(Order.class, Order::getUserId, User::getId));
```
以上示例中,我们以User和Order两张表为例进行多表联查,查询用户id为1的用户信息及其订单信息。
需要注意的是,多表联查时要注意表连接的顺序和类型(如inner join、left join等),以及查询结果的重复列问题。
相关问题
mybatisplus怎么三表联查
Mybatis Plus支持使用注解或XML配置实现三表联查。以下是使用注解实现三表联查的示例:
假设有三个表:user、order和order_item,它们的关系是:user和order是一对多的关系,order和order_item是一对多的关系。
1. 在UserMapper接口中添加方法:
```
@Select("SELECT u.*, o.*, oi.* FROM user u LEFT JOIN order o ON u.id = o.user_id LEFT JOIN order_item oi ON o.id = oi.order_id WHERE u.id = #{userId}")
List<Map<String, Object>> getUserOrderItem(Long userId);
```
2. 在OrderMapper接口中添加方法:
```
@Select("SELECT o.*, oi.* FROM order o LEFT JOIN order_item oi ON o.id = oi.order_id WHERE o.user_id = #{userId}")
List<Map<String, Object>> getOrderItem(Long userId);
```
3. 在OrderItemMapper接口中添加方法:
```
@Select("SELECT * FROM order_item WHERE order_id = #{orderId}")
List<OrderItem> getByOrderId(Long orderId);
```
4. 在UserService中调用方法:
```
public List<User> getUserOrderItem(Long userId) {
List<Map<String, Object>> result = userMapper.getUserOrderItem(userId);
Map<Long, User> userMap = new HashMap<>();
Map<Long, Order> orderMap = new HashMap<>();
List<OrderItem> orderItemList = new ArrayList<>();
for (Map<String, Object> map : result) {
Long userId = Long.valueOf(map.get("id").toString());
User user = userMap.get(userId);
if (user == null) {
user = new User();
user.setId(userId);
user.setUsername(map.get("username").toString());
userMap.put(userId, user);
}
Long orderId = Long.valueOf(map.get("o_id").toString());
Order order = orderMap.get(orderId);
if (order == null) {
order = new Order();
order.setId(orderId);
order.setUserId(userId);
order.setOrderNo(map.get("order_no").toString());
orderMap.put(orderId, order);
}
OrderItem orderItem = new OrderItem();
orderItem.setId(Long.valueOf(map.get("oi_id").toString()));
orderItem.setOrderId(orderId);
orderItem.setProductNo(map.get("product_no").toString());
orderItem.setQuantity(Integer.valueOf(map.get("quantity").toString()));
orderItemList.add(orderItem);
}
List<User> userList = new ArrayList<>(userMap.values());
for (User user : userList) {
List<Order> orderList = new ArrayList<>();
for (Order order : orderMap.values()) {
if (order.getUserId().equals(user.getId())) {
List<OrderItem> oiList = new ArrayList<>();
for (OrderItem oi : orderItemList) {
if (oi.getOrderId().equals(order.getId())) {
oiList.add(oi);
}
}
order.setOrderItemList(oiList);
orderList.add(order);
}
}
user.setOrderList(orderList);
}
return userList;
}
```
此时,调用getUserOrderItem方法可以获得一个User对象,其中包含该用户的所有订单以及每个订单的商品项。
mybatisplus中两表联查resultMap一对一怎么写
### MyBatis Plus 中 ResultMap 实现两表联查的一对一关系映射
在 MyBatis Plus 中,`ResultMap` 可以用来处理复杂的 SQL 查询结果映射问题。对于两表联查的 **一对一** 关系映射场景,可以通过 `@Results` 和 `@One` 注解来完成配置。
以下是具体的实现方法:
#### 1. 数据库设计假设
假设有两个表:`teacher` 表和 `department` 表,它们之间存在一对一的关系(即每个教师属于一个部门)。
- teacher 表结构:
```plaintext
id (主键), name, department_id (外键指向 department.id)
```
- department 表结构:
```plaintext
id (主键), dept_name
```
---
#### 2. Java 实体类定义
##### Teacher 类
```java
public class Teacher {
private Long id;
private String name;
// One-to-One 映射 Department 对象
@TableField(exist = false) // 声明该字段不在数据库表中
private Department department;
// Getter and Setter 方法省略...
}
```
##### Department 类
```java
public class Department {
private Long id;
private String deptName;
// Getter and Setter 方法省略...
}
```
---
#### 3. Mapper 接口配置
创建 `TeacherMapper` 接口并使用注解方式进行配置:
```java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.*;
@Mapper
public interface TeacherMapper extends BaseMapper<Teacher> {
@Results(id = "teacherResultMap", value = {
@Result(column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(property = "department", column = "department_id", one = @One(
select = "com.example.mapper.DepartmentMapper.selectById"
))
})
@Select("SELECT t.* FROM teacher t WHERE t.department_id = #{deptId}")
List<Teacher> findTeachersByDepartment(Long deptId);
}
```
上述代码中的关键点如下:
- 使用 `@Results` 定义了一个名为 `teacherResultMap` 的结果集映射规则。
- 在 `@Result` 中通过 `one` 属性指定了子查询逻辑,调用了 `DepartmentMapper` 的 `selectById` 方法[^1]。
- 主查询仅涉及 `teacher` 表的数据,而关联的 `department` 字段则由子查询动态加载。
---
#### 4. 子查询 Mapper 配置
为了支持上一步中的子查询操作,需要提供 `DepartmentMapper` 接口及其对应的查询方法:
```java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@Mapper
public interface DepartmentMapper extends BaseMapper<Department> {
@Select("SELECT * FROM department WHERE id = #{id}")
Department selectById(Long id);
}
```
此接口提供了基于 ID 查找单个 `Department` 记录的功能。
---
#### 5. 测试代码示例
编写测试代码验证功能是否正常工作:
```java
@Autowired
private TeacherMapper teacherMapper;
@Test
public void testFindTeachersByDepartment() {
Long deptId = 1L; // 假设查找部门ID为1的相关教师
List<Teacher> teachers = teacherMapper.findTeachersByDepartment(deptId);
for (Teacher teacher : teachers) {
System.out.println("Teacher Name: " + teacher.getName());
System.out.println("Department Name: " + teacher.getDepartment().getDeptName());
}
}
```
运行以上代码后,应能正确打印出每位教师的名字以及所属部门名称。
---
### 注意事项
- 如果希望减少多次数据库访问带来的性能开销,可以考虑使用嵌套结果的方式替代嵌套查询[^2]。
- 当前示例未启用全局配置项(如 `tablePrefix` 或者自定义填充器),实际项目可根据需求调整[^4]。
- 若需进一步优化实体类属性映射规则,可借助 `@TableName` 和其扩展参数进行定制化设置[^3]。
---
阅读全文
相关推荐















