(9) MyBatis from entry to soil-lazy loading, discriminator and inheritance

This is the ninth article in mybatis series. Before reading the previous suggestions, go to the [Java Tsukuba Fox] public account to view the previous article, which is convenient for understanding and grasping. In the last article, we introduced how to open and use MyBatis's automatic mapping. I think everyone has an understanding of this knowledge.

What I want to bring to you today is mainly the knowledge and content of MyBatis lazy loading and discriminator related aspects.

Lazy loading

Introduction to Lazy Loading

The so-called lazy loading is to postpone the timing of data loading, and a typical application is to postpone the timing of execution of nested queries.

Because related queries are often used in mybatis, but it is not always necessary to return related query results immediately. For example, to query order information, it is not necessary to return the user information or order details corresponding to the order in time, so when we encounter this situation, we need a mechanism. When we need to view the associated data, we will execute the corresponding The query returns the desired result.

This kind of demand can be implemented in mybatis using a lazy loading mechanism.

Two setting methods for delayed loading

MyBatis provides two setting methods for lazy loading, namely:

  • Global configuration
  • How to configure in sqlmap

Judging from the names of these two methods, you can find the difference between these two kinds of lazy loading. The first method is effective for all related queries, while the second method is only effective for queries with related settings.

Let's take a look at the two ways of using lazy loading.

Global configuration lazy loading

In order to realize the global configuration delay loading, it is necessary to pass the configuration file of mybatis.

The mybatis configuration file uses the following two attributes to control delayed loading:

<settings>
    <!--打开延迟加载的开关  -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  • lazyLoadingEnabled: This property is easier to understand, whether to enable lazy loading, the default is false, if you need to enable lazy loading, set it to true
  • aggressiveLazyLoading: When true, call any deferred property, and all deferred properties will be loaded. If it is false, only the specified property will be loaded when a certain property is called.

This is the description of the global configuration lazy loading. Let's use a specific example to illustrate how the global configuration lazy loading is used.

demand

This time we want to use MyBatis to achieve the demand is to query various information of the order through the order id, such as: order user information, order detail list. Among them, order user information and order detail information are obtained by lazy loading.

mybatis configuration

According to the previous introduction, the first step is to set it up through the configuration file of mybatis. As follows:

<settings>
    <!--打开延迟加载的开关  -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>

OrderMapper.xml

After setting up the global configuration, we proceed to our normal development approach. The first is to write an xml file and write our sql statement in the xml file.

<resultMap id="orderModelMap1" type="com.zhonghu.chat09.demo5.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!--  通过订单中user_id作为条件,查询下单人信息 -->
    <association property="userModel" select="com.zhonghu.chat09.demo5.mapper.UserMapper.getById1" column="user_Id"/>
    <!--  通过订单id作为条件,查询详情列表 -->
    <collection property="orderDetailModelList" select="com.zhonghu.chat09.demo5.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById1" resultMap="orderModelMap1">
    <![CDATA[
    SELECT
        a.id ,
        a.user_id,
        a.create_time,
        a.up_time
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

There are two related queries under the orderModelMap1 element above, let's also write about them.

UserMapper.xml

<!-- 根据用户id查询用户信息 -->
<select id="getById1" resultType="com.zhonghu.chat09.demo5.model.UserModel">
    <![CDATA[
    SELECT id,name FROM user where id = #{user_id}
    ]]>
</select>

OrderDetailMapper.xml

<!-- 根据订单di查询订单明细列表 -->
<select id="getListByOrderId1" resultType="com.zhonghu.chat09.demo5.model.OrderDetailModel">
    <![CDATA[
    SELECT
        a.id,
        a.order_id AS orderId,
        a.goods_id AS goodsId,
        a.num,
        a.total_price AS totalPrice
    FROM
        order_detail a
    WHERE
        a.order_id = #{order_id}
    ]]>
</select>

Corresponding 3 Model

We wrote three xml above, then we will write the Model corresponding to xml.

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderModel {
    private Integer id;
    private Integer userId;
    private Long createTime;
    private Long upTime;
    private UserModel userModel;
    //订单详情列表
    private List<OrderDetailModel> orderDetailModelList;
}

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserModel {
    private Integer id;
    private String name;
}

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderDetailModel {
    private Integer id;
    private Integer orderId;
    private Integer goodsId;
    private Integer num;
    private Double totalPrice;
}

Test case

After writing the Model, our code is basically done. Next, let's take a look at the effect of lazy loading.

com.zhonghu.chat09.demo5.Demo5Test#getById1
@Test
public void getById1() throws IOException {
    //指定mybatis全局配置文件
    mybatisConfig = "demo5/mybatis-config.xml";
    this.before();
    OrderModel orderModel = null;
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        orderModel = mapper.getById1(1);
    }
    log.info("-------分割线--------");
    log.info("{}", orderModel.getUserModel());
}

Run output

01:55.343 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
01:55.372 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
01:55.431 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <==      Total: 1
01:55.431 [main] INFO  c.j.chat05.demo5.Demo5Test - -------分割线--------
01:55.432 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==>  Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ? 
01:55.432 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Parameters: 1(Integer)
01:55.435 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <==      Total: 2
01:55.439 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==>  Preparing: SELECT id,name FROM user where id = ? 
01:55.439 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Parameters: 2(Integer)
01:55.441 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==      Total: 1
01:55.441 [main] INFO  c.j.chat05.demo5.Demo5Test - UserModel(id=2, name=Java冢狐)

It can be seen from the log that there are 3 queries in total, and the next 2 queries appear after the dividing line, indicating that orderModel.getUserModel() is called to trigger the next 2 query actions.

What we call in the code is to get user information, and the order list information is also loaded. This is mainly because aggressiveLazyLoading is set to true. When a delayed-loading attribute is used, other delayed-loading attributes will also be used together. Loaded, so 2 related queries were triggered.

Let's take a look at the effect of setting aggressiveLazyLoading to false

<settings>
    <!--打开延迟加载的开关  -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

Run the test case output again

12:19.236 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
12:19.268 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
12:19.336 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <==      Total: 1
12:19.337 [main] INFO  c.j.chat05.demo5.Demo5Test - -------分割线--------
12:19.338 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==>  Preparing: SELECT id,name FROM user where id = ? 
12:19.338 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Parameters: 2(Integer)
12:19.340 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==      Total: 1
12:19.341 [main] INFO  c.j.chat05.demo5.Demo5Test - UserModel(id=2, name=Java冢狐)

Through these two comparisons, we can easily see the difference in the effect of whether lazy loading is enabled or not.

Lazy loading in sqlmap

In the above space, we introduced how the global lazy loading works and how to use it. The global approach will take effect on all related queries, and the scope of influence is relatively large. Mybatis also provides a way to set related queries, which will only take effect on the currently set related queries.

Associated query, generally we use association and collection, these two elements have an attribute fetchType, through this attribute can specify the loading method of the associated query.

fetchType has two values

  • eager: load immediately
  • lazy: lazy loading

Let's implement a requirement: we still use the order id to query the order information, and get the associated user information and order detailed list. The user information is required to be loaded immediately, and the order details are required to be loaded later.

mapper xml is as follows

<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo5.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!--  通过订单中user_id作为条件,查询下单人信息 -->
    <association property="userModel" fetchType="eager" select="com.zhonghu.chat09.demo5.mapper.UserMapper.getById1" column="user_Id"/>
    <!--  通过订单id作为条件,查询详情列表 -->
    <collection property="orderDetailModelList" fetchType="lazy" select="com.zhonghu.chat09.demo5.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
    <![CDATA[
    SELECT
        a.id ,
        a.user_id,
        a.create_time,
        a.up_time
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

Pay attention to the fetchType attributes of the two elements of association and collection in the above configuration. eager means immediate loading, and lazy means delayed loading.

Test case

com.zhonghu.chat09.demo5.Demo5Test#getById2
@Test
public void getById2() throws IOException {
    //指定mybatis全局配置文件
    mybatisConfig = "demo5/mybatis-config2.xml";
    this.before();
    OrderModel orderModel = null;
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        orderModel = mapper.getById2(1);
    }
    log.info("-------分割线--------");
    log.info("{}", orderModel.getOrderDetailModelList());
}

Run output

36:54.284 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
36:54.321 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 1(Integer)
36:54.385 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====>  Preparing: SELECT id,name FROM user where id = ? 
36:54.385 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
36:54.387 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <====      Total: 1
36:54.389 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <==      Total: 1
36:54.390 [main] INFO  c.j.chat05.demo5.Demo5Test - -------分割线--------
36:54.392 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==>  Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ? 
36:54.392 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Parameters: 1(Integer)
36:54.397 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <==      Total: 2
36:54.398 [main] INFO  c.j.chat05.demo5.Demo5Test - [OrderDetailModel(id=1, orderId=1, goodsId=1, num=2, totalPrice=16.00), OrderDetailModel(id=2, orderId=1, goodsId=1, num=1, totalPrice=16.00)]

Pay attention to the dividing line in the output, it can be analyzed that the user information is immediately found together with the order information, and the order details are lazily loaded when we call orderModel.getOrderDetailModelList() to get the order list.

Discriminator

Sometimes, a database query may return multiple different result sets (but there is still a certain connection in general), the discriminator element is designed to deal with this situation, the concept of discriminator is well understood ——It is very similar to the switch statement in the Java language.

The two commonly used attributes of discriminator tags are as follows:

  • column: This attribute is used to set the column whose value is to be discriminated and compared.
  • javaType: This attribute is used to specify the type of the column to ensure that the same java type is used to compare values.

The discriminator tag can have one or more case tags. The case tag has a more important attribute:

  • value: This value is the value that the discriminator specifies the column to use for matching. When it matches, the result will follow the mapping associated with this case.

We use the discriminator to implement a function: query the order information through the order id, when the incoming order id is 1, get the order information and the information of the person who placed the order; when the incoming order id is 2, get the order information, Order information, order detail information; in other cases, only order information is queried by default.

OrderMapper.xml

<resultMap id="orderModelMap1" type="com.zhonghu.chat09.demo6.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!-- 鉴别器 -->
    <discriminator javaType="int" column="id">
        <case value="1">
            <!--通过用户id查询用户信息-->
            <association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
        </case>
        <case value="2">
            <!--通过用户id查询用户信息-->
            <association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
            <!--通过订单id查询订单列表-->
            <collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
        </case>
    </discriminator>
</resultMap>
<select id="getById1" resultMap="orderModelMap1">
    <![CDATA[
    SELECT
        a.id ,
        a.user_id,
        a.create_time,
        a.up_time
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

Pay attention to the discriminator above. This part is the key. The case inside the discriminator will be matched with the id field in the query result of each row. If the matching is successful, the associated query inside the case will be executed. If it is not matched, only the discriminator will be defaulted. The configured mapping mapping rules.

UserMapper.xml

<!-- 通过用户id查询用户信息 -->
<select id="getById1" resultType="com.zhonghu.chat09.demo6.model.UserModel">
    <![CDATA[
    SELECT id,name FROM user where id = #{user_id}
    ]]>
</select>

OrderDetailMapper.xml

<!-- 通过订单id查询订单明细列表 -->
<select id="getListByOrderId1" resultType="com.zhonghu.chat09.demo6.model.OrderDetailModel">
    <![CDATA[
    SELECT
        a.id,
        a.order_id AS orderId,
        a.goods_id AS goodsId,
        a.num,
        a.total_price AS totalPrice
    FROM
        order_detail a
    WHERE
        a.order_id = #{order_id}
    ]]>
</select>

The corresponding 3 Model classes

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderModel {
    private Integer id;
    private Integer userId;
    private Long createTime;
    private Long upTime;
    //用户信息
    private UserModel userModel;
    //订单详情列表
    private List<OrderDetailModel> orderDetailModelList;
}

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserModel {
    private Integer id;
    private String name;
}

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderDetailModel {
    private Integer id;
    private Integer orderId;
    private Integer goodsId;
    private Integer num;
    private Double totalPrice;
}

Test case

com.zhonghu.chat09.demo6.Demo6Test#getById1
@Test
public void getById1() throws IOException {
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        //查询订单为1的
        OrderModel orderModel = mapper.getById1(1);
        log.info("{}", orderModel);
        log.info("------------------------------------------------------------");
        //查询订单为2的
        orderModel = mapper.getById1(2);
        log.info("{}", orderModel);
        log.info("------------------------------------------------------------");
        //查询订单为3的
        orderModel = mapper.getById1(3);
        log.info("{}", orderModel);
    }
}

Run output

58:16.413 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
58:16.457 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
58:16.481 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====>  Preparing: SELECT id,name FROM user where id = ? 
58:16.481 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
58:16.488 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <====      Total: 1
58:16.489 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <==      Total: 1
58:16.489 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=1, userId=2, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=2, name=Java冢狐), orderDetailModelList=null)
58:16.491 [main] INFO  c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
58:16.491 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
58:16.492 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 2(Integer)
58:16.493 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====>  Preparing: SELECT id,name FROM user where id = ? 
58:16.493 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 1(Integer)
58:16.494 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <====      Total: 1
58:16.495 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====>  Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ? 
58:16.495 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 2(Integer)
58:16.505 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <====      Total: 1
58:16.505 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <==      Total: 1
58:16.506 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐), orderDetailModelList=[OrderDetailModel(id=3, orderId=2, goodsId=1, num=1, totalPrice=8.00)])
58:16.506 [main] INFO  c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
58:16.506 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
58:16.506 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 3(Integer)
58:16.508 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <==      Total: 1
58:16.509 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=3, userId=1, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=null)

It can be seen from the output that the order 1 has been queried twice, the order 2 has been queried 3 times, and the order 3 has been queried 1 time; the discriminator is considered a good function.

Inheritance (extends)

Inheritance is one of the three major features in Java, which can play the role of reusing code, and mybatis also has the function of inheritance, which is similar to the role of inheritance in java. It is mainly used in resultMap and can reuse the mapping relationships configured in other resultMap.

usage

<resultMap extends="被继承的resultMap的id"></resultMap>

Case study

Let's use inheritance to transform the above discriminator case and optimize the code

OrderMapper.xml
<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo6.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!-- 鉴别器 -->
    <discriminator javaType="int" column="id">
        <case value="1" resultMap="orderModelMap3" />
        <case value="2" resultMap="orderModelMap4" />
    </discriminator>
</resultMap>
<resultMap id="orderModelMap3" type="com.zhonghu.chat09.demo6.model.OrderModel" extends="orderModelMap2">
    <!--通过用户id查询用户信息-->
    <association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
</resultMap>
<resultMap id="orderModelMap4" type="com.zhonghu.chat09.demo6.model.OrderModel" extends="orderModelMap3">
    <!--通过订单id查询订单列表-->
    <collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
    <![CDATA[
    SELECT
        a.id ,
        a.user_id,
        a.create_time,
        a.up_time
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

The focus is on the two extends properties above. The above orderModelMap3 inherits the mapping relationship configured in orderModelMap2 (except for the discriminator), and adds an association to query user information; orderModelMap4 inherits orderModelMap3, and adds a query order list. Collection element. The above uses extends to achieve code reuse, which is actually the same as the following code:

<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo6.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!-- 鉴别器 -->
    <discriminator javaType="int" column="id">
        <case value="1" resultMap="orderModelMap3" />
        <case value="2" resultMap="orderModelMap4" />
    </discriminator>
</resultMap>
<resultMap id="orderModelMap3" type="com.zhonghu.chat09.demo6.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!--通过用户id查询用户信息-->
    <association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
</resultMap>
<resultMap id="orderModelMap4" type="com.zhonghu.chat09.demo6.model.OrderModel">
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="create_time" property="createTime"/>
    <result column="up_time" property="upTime"/>
    <!--通过用户id查询用户信息-->
    <association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
    <!--通过订单id查询订单列表-->
    <collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
    <![CDATA[
    SELECT
        a.id ,
        a.user_id,
        a.create_time,
        a.up_time
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>
Test case
com.zhonghu.chat09.demo6.Demo6Test#getById2
@Test
public void getById2() throws IOException {
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        //查询订单为1的
        OrderModel orderModel = mapper.getById2(1);
        log.info("{}", orderModel);
        log.info("------------------------------------------------------------");
        //查询订单为2的
        orderModel = mapper.getById2(2);
        log.info("{}", orderModel);
        log.info("------------------------------------------------------------");
        //查询订单为3的
        orderModel = mapper.getById2(3);
        log.info("{}", orderModel);
    }
}
Run output
39:55.936 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
39:55.969 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 1(Integer)
39:55.986 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====>  Preparing: SELECT id,name FROM user where id = ? 
39:55.987 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
39:55.992 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <====      Total: 1
39:55.993 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <==      Total: 1
39:55.993 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=1, userId=2, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=2, name=Java冢狐), orderDetailModelList=null)
39:55.994 [main] INFO  c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
39:55.994 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
39:55.995 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 2(Integer)
39:55.995 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====>  Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ? 
39:55.996 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 2(Integer)
39:56.000 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <====      Total: 1
39:56.001 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====>  Preparing: SELECT id,name FROM user where id = ? 
39:56.004 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 1(Integer)
39:56.005 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <====      Total: 1
39:56.005 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <==      Total: 1
39:56.005 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐), orderDetailModelList=[OrderDetailModel(id=3, orderId=2, goodsId=1, num=1, totalPrice=8.00)])
39:56.005 [main] INFO  c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
39:56.005 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==>  Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ? 
39:56.006 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 3(Integer)
39:56.007 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <==      Total: 1
39:56.007 [main] INFO  c.j.chat05.demo6.Demo6Test - OrderModel(id=3, userId=1, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=null)

to sum up

The beginning of this article focuses on the related content of MyBatis's lazy loading, and the global lazy loading and partial lazy loading are introduced. After the lazy loading is introduced, some related discriminators and inheritance are introduced. Related content.

At last

  • If you feel that you are rewarded after reading it, I hope to pay attention to it. By the way, give me a thumbs up. This will be the biggest motivation for my update. Thank you for your support.
  • Welcome everyone to pay attention to my public account [Java Fox], focusing on the basic knowledge of java and computer, I promise to let you get something after reading it, if you don’t believe me, hit me
  • Seek one-click triple connection: like, forward, and watching.
  • If you have different opinions or suggestions after reading, please comment and share with us. Thank you for your support and love.

——I am Chuhu, and I love programming as much as you.

Welcome to follow the public account "Java Fox" for the latest news

Guess you like

Origin blog.csdn.net/issunmingzhi/article/details/113999040