(9) MyBatis da entrada ao carregamento lento, discriminador e herança

Este é o nono artigo da série mybatis. Antes de ler as sugestões anteriores, vá para a conta pública [Java Tsukuba Fox] para visualizar o artigo anterior, que é conveniente para compreensão e compreensão. No artigo anterior, apresentamos como abrir e usar o mapeamento automático do MyBatis.Acho que todos têm uma compreensão desse conhecimento.

O que eu quero trazer para você hoje é principalmente o conhecimento e o conteúdo do MyBatis lazy loading e os aspectos relacionados ao discriminador.

Carregamento lento

Introdução ao Lazy Loading

O chamado carregamento lento é para adiar o tempo de carregamento de dados, e uma aplicação típica é para adiar o tempo de execução de consultas aninhadas.

Porque consultas relacionadas são freqüentemente usadas em mybatis, mas nem sempre é necessário retornar resultados de consultas relacionadas imediatamente. Por exemplo, para consultar as informações do pedido, não é necessário retornar as informações do usuário ou os detalhes do pedido correspondentes ao pedido no tempo, portanto, quando nos deparamos com essa situação, precisamos de um mecanismo. Quando precisarmos visualizar os dados associados, iremos execute o correspondente A consulta retorna o resultado desejado.

Esse tipo de demanda pode ser implementado no mybatis usando um mecanismo de carregamento lento.

Dois métodos de configuração para atrasar o carregamento

MyBatis fornece dois métodos de configuração para carregamento lento, a saber:

  • Configuração global
  • Como configurar em sqlmap

Julgando pelos nomes desses dois métodos, você pode encontrar a diferença entre esses dois tipos de carregamento lento. O primeiro método é eficaz para todas as consultas relacionadas, enquanto o segundo método só é eficaz para configurações relacionadas.

Vamos dar uma olhada nas duas maneiras de usar o carregamento lento.

Carregamento lento de configuração global

Para realizar o atraso de carregamento da configuração global, é necessário passar o arquivo de configuração do mybatis.

O arquivo de configuração mybatis usa os dois atributos a seguir para controlar o carregamento atrasado:

<settings>
    <!--打开延迟加载的开关  -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  • lazyLoadingEnabled: esta propriedade é mais fácil de entender, seja para habilitar o carregamento lento, o padrão é falso, se você precisar habilitar o carregamento lento, defina-o como verdadeiro
  • angryLazyLoading: quando verdadeiro, chama qualquer propriedade adiada, e todas as propriedades adiadas serão carregadas. Se for falso, apenas a propriedade especificada será carregada quando uma determinada propriedade for chamada.

Esta é a descrição do carregamento lento da configuração global. Vamos usar um exemplo específico para ilustrar como o carregamento lento da configuração global é usado.

exigem

Desta vez queremos usar o MyBatis para atender a demanda é consultar várias informações do pedido através do id do pedido, tais como: informações do usuário do pedido, lista de detalhes do pedido. Entre eles, as informações do usuário do pedido e as informações detalhadas do pedido são obtidas por carregamento lento.

configuração mybatis

De acordo com a introdução anterior, o primeiro passo é configurá-lo através do arquivo de configuração do mybatis. Do seguinte modo:

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

OrderMapper.xml

Depois de definir a configuração global, continuamos com nossa abordagem de desenvolvimento normal.A primeira é escrever um arquivo xml e escrever nossa instrução sql no arquivo xml.

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

Existem duas consultas relacionadas no elemento orderModelMap1 acima, também vamos escrever sobre elas.

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>

Modelo 3 correspondente

Escrevemos três xml acima, então escreveremos o modelo correspondente ao 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;
}

Caso de teste

Depois de escrever o modelo, nosso código está basicamente pronto. A seguir, vamos dar uma olhada no efeito do carregamento lento.

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

Executar saída

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冢狐)

Pode-se ver no log que há 3 consultas no total e as próximas 2 consultas aparecem após a linha divisória, indicando que orderModel.getUserModel () é chamado para acionar as próximas 2 ações de consulta.

O que chamamos no código é obter informações do usuário, e as informações da lista de pedidos também são carregadas. Isso ocorre principalmente porque angryLazyLoading está definido como verdadeiro. Quando um atributo de carregamento atrasado é usado, outros atributos de carregamento atrasado também são usados ​​juntos. Carregado , então 2 consultas relacionadas foram acionadas.

Vamos dar uma olhada no efeito de definir angryLazyLoading como falso

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

Execute a saída do caso de teste novamente

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冢狐)

Por meio dessas duas comparações, podemos ver facilmente a diferença no efeito de o carregamento lento estar habilitado ou não.

Carregamento lento em sqlmap

No espaço acima, apresentamos como funciona o carregamento lento global e como usá-lo. A abordagem global terá efeito em todas as consultas relacionadas, e o escopo de influência é relativamente grande. Mybatis também fornece uma maneira de definir consultas relacionadas, que só terá efeito nas consultas relacionadas definidas atualmente.

Consulta associada, geralmente usamos associação e coleção, esses dois elementos possuem um atributo fetchType, através deste atributo podemos especificar o método de carregamento da consulta associada.

fetchType tem dois valores

  • ansioso: carregue imediatamente
  • preguiçoso: carregamento lento

Vamos implementar um requisito: ainda usamos o ID do pedido para consultar as informações do pedido e obter as informações do usuário associadas e a lista detalhada do pedido. As informações do usuário devem ser carregadas imediatamente e os detalhes do pedido devem ser carregados posteriormente.

mapper xml é o seguinte

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

Preste atenção aos atributos fetchType dos dois elementos de associação e coleção na configuração acima. Ansioso significa carregamento imediato e preguiçoso significa carregamento atrasado.

Caso de teste

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

Executar saída

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)]

Preste atenção à linha divisória na saída. Pode ser analisado que as informações do usuário são imediatamente encontradas junto com as informações do pedido, e os detalhes do pedido são carregados lentamente quando chamamos orderModel.getOrderDetailModelList () para obter a lista de pedidos.

Discriminador

Às vezes, uma consulta de banco de dados pode retornar vários conjuntos de resultados diferentes (mas ainda há uma certa conexão em geral), o elemento discriminador é projetado para lidar com esta situação, o conceito de discriminador é bem compreendido —— É muito semelhante ao switch declaração na linguagem Java.

Os dois atributos comumente usados ​​de tags discriminadoras são os seguintes:

  • coluna: Este atributo é usado para definir a coluna cujo valor deve ser comparado.
  • javaType: este atributo é usado para especificar o tipo da coluna para garantir que o mesmo tipo java seja usado para comparar valores.

A tag discriminadora pode ter uma ou mais tags de caso. A tag de caso tem um atributo mais importante:

  • valor: este valor é o valor que o discriminador especifica a coluna a ser usada para correspondência. Quando corresponder, o resultado seguirá o mapeamento associado a este caso.

Usamos o discriminador para implementar uma função: consultar as informações do pedido por meio do id do pedido, quando o id do pedido recebido for 1, obter as informações do pedido e as informações da pessoa que fez o pedido; quando o id do pedido recebido for 2, obter as informações do pedido, informações do pedido, informações detalhadas do pedido; em outros casos, apenas as informações do pedido são consultadas por padrão.

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>

Preste atenção ao discriminador acima. Esta parte é a chave. O caso dentro do discriminador será combinado com o campo id em cada linha do resultado da consulta. Se a correspondência for bem-sucedida, a consulta associada dentro do caso será executada. Se não é correspondido, apenas o discriminador será padronizado As regras de mapeamento configuradas.

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>

As 3 classes de modelo correspondentes

@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;
}

Caso de teste

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

Executar saída

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)

Pode ser visto na saída que a ordem 1 foi consultada duas vezes, a ordem 2 foi consultada 3 vezes e a ordem 3 foi consultada 1 vez; o discriminador é considerado uma boa função.

Herança (estende)

Herança em Java é um dos três principais recursos, que pode desempenhar o papel de reutilizar código, e mybatis também tem a função de herança, que é semelhante ao papel de herança em java. É usado principalmente em resultMap e pode reutilizar o relacionamento de mapeamento configurado em outro resultMap.

uso

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

Estudo de caso

Vamos usar a herança para transformar o caso do discriminador acima e otimizar o código

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>

O foco está nas duas propriedades estendidas acima. O orderModelMap3 acima herda o relacionamento de mapeamento configurado em orderModelMap2 (exceto para o discriminador) e adiciona uma associação para consultar informações do usuário; orderModelMap4 herda orderModelMap3 e adiciona uma lista de pedidos de consulta. Elemento de coleção. O uso acima se estende para alcançar a reutilização de código, que na verdade é igual ao código a seguir:

<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>
Caso de teste
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);
    }
}
Executar saída
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)

Resumindo

O início deste artigo concentra-se no conteúdo relacionado do carregamento lento do MyBatis e no carregamento lento global e no carregamento lento parcial. Após a introdução do carregamento lento, alguns discriminadores relacionados e herança são introduzidos. Conteúdo relacionado.

Finalmente

  • Se você sentir que é recompensado após a leitura, espero prestar atenção a isso. A propósito, dê um sinal de positivo. Essa será a maior motivação para minha atualização. Obrigado pelo seu apoio.
  • Sejam todos bem-vindos, prestem atenção à minha conta pública [Java Fox], com foco no conhecimento básico de java e informática, prometo deixar vocês obterem algo depois de lê-lo, se não acreditam em mim, me bata
  • Procure uma conexão tripla de um clique: curtir, avançar e assistir.
  • Se você tiver opiniões ou sugestões diferentes após a leitura, por favor, comente e compartilhe conosco. Obrigado pelo seu apoio e amor.

——Eu sou Chuhu e adoro programar tanto quanto você.

Bem-vindo a seguir a conta pública "Java Fox" para as últimas notícias

Acho que você gosta

Origin blog.csdn.net/issunmingzhi/article/details/113999040
Recomendado
Clasificación