(8) MyBatis da entrada ao solo - o uso de mapeamento automático

Este é o oitavo artigo da série mybatis. Se você não leu as sugestões anteriores, primeiro vá para a conta pública [Java Tsukuba Fox] para ver o texto anterior, que é conveniente para compreensão e compreensão. No artigo anterior, apresentamos algumas das maneiras como mybatis usa consultas, especialmente consultas um-para-um e consultas um-para-muitos. Para quem ainda não viu, é recomendável ir à conta oficial para verificar.

Hoje apresentamos o mapeamento automático que temos usado, mas não tivemos tempo de introduzir muito.

O que é mapeamento automático?

Antes de introduzir o mapeamento automático, vamos dar uma olhada no mapeamento manual, da seguinte maneira:

<resultMap id="orderModelMap1" type="com.zhonghu.chat08.demo7.model.OrderModel">
    <id column="id" property="id"/>
    <result column="userId" property="userId" />
    <result column="createTime" property="createTime" />
    <result column="upTime" property="upTime" />
</resultMap>
<select id="getById1" resultMap="orderModelMap1">
    <![CDATA[
    SELECT
        a.id,
        a.user_id userId,
        a.create_time createTime,
        a.up_time upTime
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

Observe que existem 4 linhas de configuração no elemento resultMap acima, da seguinte maneira:

<id column="id" property="id"/>
<result column="userId" property="userId" />
<result column="createTime" property="createTime" />
<result column="upTime" property="upTime" />

Essas 4 linhas de código são usadas para configurar o relacionamento de mapeamento entre as colunas do resultado sql e os campos no objeto OrderModel.

Você notou que os valores dos elementos de coluna e propriedade nas regras de mapeamento são os mesmos. Mybatis suporta configuração de mapeamento automático. Quando o mapeamento automático está ativado, quando o nome da coluna de sql é o mesmo que o nome do campo em o modelo (não faz distinção entre maiúsculas e minúsculas), mybatis irá mapear automaticamente internamente, e não precisamos escrever manualmente as regras de mapeamento de 4 linhas acima.

Vamos mudar o exemplo acima para o método de mapeamento automático, da seguinte maneira:

<resultMap id="orderModelMap2" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true">
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
    <![CDATA[
    SELECT
        a.id,
        a.user_id userId,
        a.create_time createTime,
        a.up_time upTime
    FROM
        orders a
    WHERE
        a.id = #{value}
    ]]>
</select>

Preste atenção ao atributo autoMapping no resultMap acima, se para habilitar o mapeamento automático, nós o configuramos como true, então mybatis irá mapear e atribuir valores automaticamente de acordo com o nome da coluna e o campo com o mesmo nome no Model.

Os resultados finais da consulta das duas configurações acima são os mesmos e os valores dos quatro campos correspondentes aos resultados da consulta são atribuídos automaticamente aos atributos de mesmo nome no OrderModel.

Interruptor de mapeamento automático

Existem dois tipos principais de mapeamento automático no mybatis. Um é a configuração global, que é efetiva para todos os resultMaps do aplicativo. Isso é definido no arquivo de configuração mybatis; o outro é configurado através da propriedade autoMapping do resultMap.

Quando mybatis julga se um resultMap está habilitado para configuração de mapeamento automático, ele primeiro procura seu próprio atributo autoMapping. Se este atributo for definido, ele usará diretamente o valor desse atributo. Se o atributo autoMapping do elemento resultMap não estiver configurado , ele será configurado globalmente. Regras de mapeamento automático.

Deixe-nos explicar em detalhes o conteúdo disso.

mybatis mapeia automaticamente a configuração global

Adicione a seguinte configuração no arquivo de configuração global mybatis:

<settings>
    <setting name="autoMappingBehavior" value="自动映射规则"/>
</settings>

Existem principalmente os seguintes:

  • NENHUMA: Desligue a chave de mapeamento global
  • PARCIAL: Atributos do mapa diferentes do mapeamento de resultado aninhado (ou seja, atributos conectados) definidos internamente, este também é o valor padrão.
  • FULL: mapeia automaticamente todos os atributos.

NENHUM

Quando o valor de autoMappingBehavior é definido como NONE na configuração global de mybatis, significa que o mapeamento automático global está desligado, o que fará com que o SQL realmente retorne um resultado, mas o resultado não será mapeado automaticamente quando o resultado for mapeado , então o retorno está vazio

PARCIAL

O mapeamento automático será executado, mas alguns mapeamentos de consulta complexos aninharão alguns mapeamentos (como associação, coleção) no resultMap. Quando PARTIAL for usado, se houver um mapeamento aninhado, o mapeamento aninhado não será mapeado automaticamente.

COMPLETO

Todos os atributos são mapeados automaticamente.

uso de mapeamento automático

Como mencionamos acima, quando o atributo autoMapping é especificado no resultMap, o mapeamento automático do resultMap é controlado pelo atributo autoMapping e não tem nada a ver com o comportamento da configuração de mapeamento global (autoMappingBehavior) em mybatis.

Caso 1

Esta configuração principal é principalmente em sqlmap, da seguinte maneira:
<resultMap id="orderModelMap7" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true">
    <association property="userModel" autoMapping="true">
        <id column="user_id" property="id"/>
    </association>
</resultMap>
<select id="getById7" resultMap="orderModelMap7">
    <![CDATA[
    SELECT
        a.id,
        a.user_id userId,
        a.create_time createTime,
        a.up_time upTime,
        b.id as user_id,
        b.name
    FROM
        orders a,user b
    WHERE
        a.user_id = b.id
        AND a.id = #{value}
    ]]>
</select>
Caso de teste correspondente
com.zhonghu.chat08.demo7.Demo7Test#getById7
@Test
public void getById7() throws IOException {
    this.before("demo7/mybatis-config1.xml");
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        OrderModel orderModel = mapper.getById7(2);
        log.info("{}", orderModel);
    }
}
Executar saída
24:37.544 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - ==>  Preparing: SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime, b.id as user_id, b.name FROM orders a,user b WHERE a.user_id = b.id AND a.id = ? 
24:37.589 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - ==> Parameters: 2(Integer)
24:37.610 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById7 - <==      Total: 1
24:37.610 [main] INFO  c.j.chat05.demo7.Demo7Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐))

Todos os atributos em OrderModel são mapeados automaticamente com sucesso.

A montagem automática não é tão divertida e deixar de jogar pode trazer alguns perigos ocultos. Vejamos um caso, veja o exemplo 2 abaixo.

Exemplo 2

De acordo com o número do pedido, consulte as informações do pedido e, a propósito, consulte a lista de detalhes do pedido. Para isso, usamos a consulta um-para-muitos em mybatis.

OrderDetaiMapper.xml adicionado
<select id="getListByOrderId1" resultType="com.zhonghu.chat08.demo7.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 = #{value}
    ]]>
</select>

Isso pode ser baseado no id do pedido para consultar a lista detalhada associada ao pedido.

Associação OrderMapper.xml
<resultMap id="orderModelMap8" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true">
    <collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById8" resultMap="orderModelMap8">
    <![CDATA[
    SELECT
        a.id,
        a.user_id userId,
        a.create_time createTime,
        a.up_time upTime
    FROM
        orders a
    WHERE a.id = #{value}
    ]]>
</select>
Caso de teste
com.zhonghu.chat08.demo7.Demo7Test#getById8
@Test
public void getById8() throws IOException {
    this.before("demo7/mybatis-config.xml");
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        OrderModel orderModel = mapper.getById8(1);
        log.info("{}", orderModel);
    }
}
Executar saída
11:06.193 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - ==>  Preparing: SELECT a.id, a.user_id userId, a.create_time createTime, a.up_time upTime FROM orders a WHERE a.id = ? 
11:06.229 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - ==> Parameters: 1(Integer)
11:06.250 [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 t_order_detail a WHERE a.order_id = ? 
11:06.251 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 1(Integer)
11:06.255 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <====      Total: 2
11:06.256 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById8 - <==      Total: 1
11:06.256 [main] INFO  c.j.chat05.demo7.Demo7Test - OrderModel(id=null, userId=2, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=[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 ao atributo id de OrderModel na saída, como ele é um valor nulo? Principalmente causado pela seguinte linha de configuração

<collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>

Há um atributo de coluna na configuração acima, que especifica id. Neste momento, mybatis pensa que você especificou manualmente o relacionamento de mapeamento para o campo id, então ele ignora o mapeamento automático do campo id para o atributo OrderModel.id, que leva ao id do objeto OrderModel. O atributo não foi atribuído. Neste momento, precisamos especificar manualmente a regra de mapeamento de id em orderModelMap8, da seguinte maneira:

<resultMap id="orderModelMap8" type="com.zhonghu.chat08.demo7.model.OrderModel" autoMapping="true">
    <id column="id" property="id" />
    <collection property="orderDetailModelList" select="com.zhonghu.chat08.demo7.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>

Execute o caso de teste novamente e será normal.

para concluir

Para o nosso desenvolvimento, o mapeamento automático pode realmente nos ajudar a salvar algum código, mas também existem alguns perigos ocultos. Esperamos que o sistema desenvolvido por nós seja robusto. É recomendável que, ao escrever mapeador xml, você reserve algum tempo para informar o configuração de mapeamento. Escreva, isso pode eliminar alguns perigos ocultos e tornar nosso sistema mais estável.

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/113872133
Recomendado
Clasificación