多表映射

实体类设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Data
public class Customer {

private Integer customerId;
private String customerName;
private List<Order> orderList;// 体现的是对多的关系

}

@Data
public class Order {
private Integer orderId;
private String orderName;
private Customer customer;// 体现的是对一的关系

}

对一映射

  • 需求说明
    根据ID查询订单,以及订单关联的用户的信息

  • OrderMapper接口

    1
    2
    3
    public interface OrderMapper {
    Order selectOrderWithCustomer(Integer orderId);
    }
  • OrderMapper.xml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <!-- 创建resultMap实现“对一”关联关系映射 -->
    <!-- id属性:通常设置为这个resultMap所服务的那条SQL语句的id加上“ResultMap” -->
    <!-- type属性:要设置为这个resultMap所服务的那条SQL语句最终要返回的类型 -->
    <resultMap id="selectOrderWithCustomerResultMap" type="order">

    <!-- 先设置Order自身属性和字段的对应关系 -->
    <id column="order_id" property="orderId"/>

    <result column="order_name" property="orderName"/>

    <!-- 使用association标签配置“对一”关联关系 -->
    <!-- property属性:在Order类中对一的一端进行引用时使用的属性名 -->
    <!-- javaType属性:一的一端类的全类名 -->
    <association property="customer" javaType="customer">

    <!-- 配置Customer类的属性和字段名之间的对应关系 -->
    <id column="customer_id" property="customerId"/>
    <result column="customer_name" property="customerName"/>

    </association>

    </resultMap>

    <!-- Order selectOrderWithCustomer(Integer orderId); -->
    <select id="selectOrderWithCustomer" resultMap="selectOrderWithCustomerResultMap">

    SELECT order_id,order_name,c.customer_id,customer_name
    FROM t_order o
    LEFT JOIN t_customer c
    ON o.customer_id=c.customer_id
    WHERE o.order_id=#{orderId}

    </select>
  • junit测试程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    @Slf4j
    public class MyBatisTest {

    private SqlSession session;
    // junit会在每一个@Test方法前执行@BeforeEach方法

    @BeforeEach
    public void init() throws IOException {
    session = new SqlSessionFactoryBuilder()
    .build(
    Resources.getResourceAsStream("mybatis-config.xml"))
    .openSession();
    }

    @Test
    public void testRelationshipToOne() {

    OrderMapper orderMapper = session.getMapper(OrderMapper.class);
    // 查询Order对象,检查是否同时查询了关联的Customer对象
    Order order = orderMapper.selectOrderWithCustomer(2);
    log.info("order = " + order);

    }

    // junit会在每一个@Test方法后执行@@AfterEach方法
    @AfterEach
    public void clear() {
    session.commit();
    session.close();
    }
    }

对多映射

  • 需求说明
    查询客户和客户相关联的信息

  • CustomerMapper接口

    1
    2
    3
    4
    5
    public interface CustomerMapper {

    Customer selectCustomerWithOrderList(Integer customerId);

    }
  • CustomerMapper.Xml文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <!-- 配置resultMap实现从Customer到OrderList的“对多”关联关系 -->
    <resultMap id="selectCustomerWithOrderListResultMap"

    type="customer">

    <!-- 映射Customer本身的属性 -->
    <id column="customer_id" property="customerId"/>

    <result column="customer_name" property="customerName"/>

    <!-- collection标签:映射“对多”的关联关系 -->
    <!-- property属性:在Customer类中,关联“多”的一端的属性名 -->
    <!-- ofType属性:集合属性中元素的类型 -->
    <collection property="orderList" ofType="order">

    <!-- 映射Order的属性 -->
    <id column="order_id" property="orderId"/>

    <result column="order_name" property="orderName"/>

    </collection>

    </resultMap>

    <!-- Customer selectCustomerWithOrderList(Integer customerId); -->
    <select id="selectCustomerWithOrderList" resultMap="selectCustomerWithOrderListResultMap">
    SELECT c.customer_id,c.customer_name,o.order_id,o.order_name
    FROM t_customer c
    LEFT JOIN t_order o
    ON c.customer_id=o.customer_id
    WHERE c.customer_id=#{customerId}
    </select>

多表映射优化

我们可以将autoMappingBehavior设置为full,进行多表resultMap映射的时候,可以省略符合列和属性命名映射规则(列名=属性名,或者开启驼峰映射也可以自定映射)的result标签!

  • 修改mybati-sconfig.xml:

    1
    2
    <!--开启resultMap自动映射 -->
    <setting name="autoMappingBehavior" value="FULL"/>
  • 修改CustomerMapper.Xml文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <resultMap id="selectCustomerWithOrderListResultMap"

    type="customer">

    <!-- 映射Customer本身的属性 -->
    <id column="customer_id" property="customerId"/>
    <!-- 开启自动映射,并且开启驼峰式支持!可以省略 result!-->
    <!-- <result column="customer_name" property="customerName"/> -->

    <collection property="orderList" ofType="order">

    <!-- 映射Order的属性 -->
    <id column="order_id" property="orderId"/>

    <!-- <result column="order_name" property="orderName"/> -->

    </collection>

    </resultMap>