【Mybatis】多表映射 第二期


一、多表映射概念

  • 多表关系:
    • 一对一
    • 一对多 | 多对一
    • 多对多
  • 一个 客户 对应 多个订单
  • 一个订单 对应 一个客户

举例:

对一 实体类设计:对一关系下,类中只要包含单个对方对象类型属性即可!

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 表
1

二、对一映射

  • 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();
    }
}

1

三、对多映射

  • 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());
        }
    }

1

四、多表映射总结

4.1 多表映射优化

mybatis-config.xml 全局设置 setting

setting属性属性含义可选值默认值
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。NONE, PARTIAL, FULLPARTIAL
<!--开启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标签内
  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道格维克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值