文章目录
- 一、多表映射概念
- 二、对一映射
- 三、对多映射
- 四、多表映射总结
- 4.1 多表映射优化
- 4.2 多表映射总结
一、多表映射概念
- 多表关系:
- 一对一
- 一对多 | 多对一
- 多对多
- 一个 客户 对应 多个订单
- 一个订单 对应 一个客户
举例:
对一 实体类设计:对一关系下,类中只要包含单个对方对象类型属性即可!
public class Customer {
private Integer customerId;
private String customerName;
}
public class Order {
private Integer orderId;
private String orderName;
private Customer customer;// 体现的是对一的关系
}
对多 实体类设计:对多关系下,类中只要包含对方类型集合属性即可!
public class Customer {
private Integer customerId;
private String customerName;
private List<Order> orderList;// 体现的是对多的关系
}
public class Order {
private Integer orderId;
private String orderName;
private Customer customer;// 体现的是对一的关系
}
多表结果实体类设计小技巧:
- 对一,属性中包含对方对象
- 对多,属性中包含对方对象集合
- 只有真实发生多表查询时,才需要设计和修改实体类,否则不提前设计和修改实体类!
- 无论多少张表联查,实体类设计都是两两考虑!
- 在查询映射的时候,只需要关注本次查询相关的属性!例如:查询订单和对应的客户,就不要关注客户中的订单集合!
实际开发时,一般在开发过程中,不给数据库表设置外键约束。
原因是避免调试不方便。
一般是功能开发完成,再加外键约束检查是否有bug。
案例准备:
CREATE TABLE `t_customer` (`customer_id` INT NOT NULL AUTO_INCREMENT, `customer_name` CHAR(100), PRIMARY KEY (`customer_id`) );
CREATE TABLE `t_order` ( `order_id` INT NOT NULL AUTO_INCREMENT, `order_name` CHAR(100), `customer_id` INT, PRIMARY KEY (`order_id`) );
INSERT INTO `t_customer` (`customer_name`) VALUES ('c01');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o1', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o2', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o3', '1');
t_customer 表 与 t_order 表
二、对一映射
- pojo
@Data
public class Order {
private int orderId;
private String orderName;
private int customerId;
// 一个订单对应一个客户
private Customer customer;
}
- 接口
public interface OrderMapper {
/**
* 根据ID查询订单和对应客户
* @param id
* @return
*/
Order queryOrderById(Integer id);
}
- xml
<mapper namespace="com.wake.mapper.OrderMapper">
<!-- 自定义映射关系,定义嵌套对象的映射关系 -->
<resultMap id="orderMap" type="order">
<!-- 第一层属性 order对象-->
<!-- order的主键 id标签 -->
<id column="order_id" property="orderId"/>
<!-- 普通列 -->
<result column="order_name" property="orderName"/>
<result column="customer_id" property="customerId"/>
<!--
对象属性赋值:
property="customer" order 实体类内的属性名字
javaType="customer" 对象类型
-->
<association property="customer" javaType="customer">
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
</association>
</resultMap>
<!-- Order queryOrderById(Integer id);
根据ID查询订单和对应客户
-->
<select id="queryOrderById" resultMap="orderMap">
select order_id,order_name,tor.customer_id,customer_name
from t_order tor
JOIN t_customer tus
ON tor.customer_id = tus.customer_id
WHERE order_id = #{id};
</select>
</mapper>
- 测试:
public class MybatisTest {
private SqlSession sqlSession;
@BeforeEach
public void init() throws IOException {
sqlSession = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("Mybatis-config.xml"))
.openSession();
}
@Test
public void testToOne(){
// 查询订单和对应客户
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
Order order = orderMapper.queryOrderById(2);
System.out.println(order);
System.out.println(order.getCustomer());
}
@AfterEach
public void clean(){
sqlSession.close();
}
}
三、对多映射
- pojo
@Data
public class Customer {
private int customerId;
private String customerName;
// 一个客户 多个订单
private List<Order> orderList;
}
- mapper 接口
public interface CustomerMapper {
/**
* 查询所有客户订单
* @return
*/
List<Customer> queryList();
}
- xml
<mapper namespace="com.wake.mapper.CustomerMapper">
<resultMap id="customerMap" type="customer">
<id column="customer_id" property="customerId"/>
<result column="customer_name" property="customerName"/>
<collection property="orderList" ofType="order">
<id column="order_id" property="orderId"/>
<result column="order_name" property="orderName"/>
<result column="customer_id" property="customerId"/>
</collection>
</resultMap>
<select id="queryList" resultMap="customerMap">
select *
from t_order tor
JOIN t_customer tur
ON tor.customer_id = tur.customer_id;
</select>
</mapper>
- 测试
@Test
public void testToMulti(){
// 根据客户ID 查询所有订单
CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class);
List<Customer> customers = customerMapper.queryList();
System.out.println(customers);
for (Customer customer : customers) {
System.out.println(customer.getOrderList());
}
}
四、多表映射总结
4.1 多表映射优化
mybatis-config.xml 全局设置 setting
setting属性 | 属性含义 | 可选值 | 默认值 |
---|---|---|---|
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
<!--开启resultMap自动映射-->
<setting name="autoMappingBehavior" value="FULL"/>
只用写 id部分 <collection
<resultMap id="customerMap" type="customer">
<id column="customer_id" property="customerId"/>
<!-- <result column="customer_name" property="customerName"/>-->
<collection property="orderList" ofType="order">
<id column="order_id" property="orderId"/>
<!-- <result column="order_name" property="orderName"/>-->
<!-- <result column="customer_id" property="customerId"/>-->
</collection>
</resultMap>
4.2 多表映射总结
关联关系 | 配置项关键词 | 所在配置文件和具体位置 |
---|---|---|
对一 | association标签/javaType属性/property属性 | Mapper配置文件中的resultMap标签内 |
对多 | collection标签/ofType属性/property属性 | Mapper配置文件中的resultMap标签内 |