[Mybatis da entrada ao tutorial de combate real] Capítulo 5 Explicação detalhada da consulta da associação Mybatis

5. Consulta associada ao Mybatis

5.1 Análise do modelo de dados

5.1.1 Introdução à função de tabela

  • Tabela de Usuários: Registre as informações básicas dos usuários.

  • Tabela de pedidos: Registra os pedidos criados pelos usuários (pedidos de compra de mercadorias).

  • Tabela de detalhes do pedido: Registre os detalhes do pedido, ou seja, as informações dos produtos adquiridos.

  • Tabela de produtos: Registre as informações básicas do produto.

5.1.2 Relacionamento comercial entre tabelas

Tabela de usuários e tabela de pedidos:

  • Tabela de usuário ---> tabela de pedidos: um usuário pode criar vários pedidos, relacionamento um-para-muitos;

  • Tabela de Pedidos ---> Tabela de Usuários: Um pedido é criado por apenas um usuário, relacionamento um-para-um;

Formulário de pedido e formulário de detalhes do pedido:

  • Tabela de pedidos ---> tabela de detalhes do pedido: um pedido pode conter vários detalhes do pedido, porque um pedido pode comprar vários itens e as informações de compra de cada item são registradas na tabela de detalhes do pedido, um relacionamento um para muitos;

  • Tabela de detalhes do pedido---> Tabela de pedidos: Um detalhe do pedido só pode ser incluído em um pedido, relacionamento um-para-um;

Tabela de detalhes do pedido e tabela de produtos:

  • Tabela de detalhes do pedido ---> Tabela de produtos: Um detalhe do pedido corresponde a apenas uma informação do produto, uma relação um-para-um;

  • Tabela de produtos ---> tabela de detalhes do pedido: um produto pode ser incluído em vários detalhes do pedido, relacionamento um-para-muitos;

Tabela de pedidos e tabela de produtos:

  • Tabela de pedidos <---> Tabela de mercadorias: Um pedido contém várias mercadorias e uma mercadoria pode ser adicionada a vários pedidos. A relação entre as duas é estabelecida por meio da tabela de detalhes do pedido, uma relação muitos-para-muitos;

Perceber:

  • Se duas tabelas tiverem associações de chave primária e estrangeira, seu relacionamento comercial será um-para-um/um-para-muitos ou um-para-um bidirecional (como tabela de usuário e tabela de detalhes do usuário).

  • Se duas tabelas são relacionamentos bidirecionais um-para-muitos, eles são relacionamentos muitos-para-muitos e deve haver uma tabela de descrição de relacionamento como uma tabela intermediária.

5.1.3 Estrutura da tabela

tabela de usuários:

CREATE TABLE `users`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `username` varchar(20),
  `password` varchar(50),
  `realname` varchar(20)
);

INSERT INTO `users` VALUES (1, 'admin', '123456', '管理员');
INSERT INTO `users` VALUES (2, 'tom', '123', '汤姆');
INSERT INTO `users` VALUES (3, 'jerry', '456', '杰瑞');
INSERT INTO `users` VALUES (4, 'zhangsan', '111', '张三');
INSERT INTO `users` VALUES (5, 'lisi', '222', '李四');

Formulário de pedido:

CREATE TABLE `orders`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `order_number` varchar(30),
  `total_price` double,
  `status` varchar(5),
  `user_id` int(11)
);
​
INSERT INTO `orders` VALUES (1, '201812290838001', 2535, '已评价', 2);
INSERT INTO `orders` VALUES (2, '201812290838002', 4704.6, '已签收', 2);
INSERT INTO `orders` VALUES (3, '201812290838003', 3620, '已支付', 2);
INSERT INTO `orders` VALUES (4, '201812290840001', 600, '已发货', 3);
INSERT INTO `orders` VALUES (5, '201812290840002', 280, '未支付', 3);

Tabela de detalhes do pedido:

CREATE TABLE `orders_detail`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `amount` int(11),
  `goods_id` int(11),
  `orders_id` int(11)
);
​
INSERT INTO `orders_detail` VALUES (1, 1, 1, 1);
INSERT INTO `orders_detail` VALUES (2, 3, 8, 1);
INSERT INTO `orders_detail` VALUES (3, 1, 2, 2);
INSERT INTO `orders_detail` VALUES (4, 2, 7, 2);
INSERT INTO `orders_detail` VALUES (5, 1, 3, 3);
INSERT INTO `orders_detail` VALUES (6, 6, 6, 3);
INSERT INTO `orders_detail` VALUES (7, 2, 4, 4);
INSERT INTO `orders_detail` VALUES (8, 1, 5, 5);

Lista de mercadorias:

CREATE TABLE `goods`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `goods_name` varchar(50),
  `description` varchar(500),
  `price` double
);
​
INSERT INTO `goods` VALUES (1, '手机', '手机', 2499);
INSERT INTO `goods` VALUES (2, '笔记本电脑', '笔记本电脑', 4699);
INSERT INTO `goods` VALUES (3, 'IPAD', 'IPAD', 3599);
INSERT INTO `goods` VALUES (4, '运动鞋', '运动鞋', 300);
INSERT INTO `goods` VALUES (5, '外套', '外套', 280);
INSERT INTO `goods` VALUES (6, '可乐', '可乐', 3.5);
INSERT INTO `goods` VALUES (7, '辣条', '辣条', 2.8);
INSERT INTO `goods` VALUES (8, '水杯', '水杯', 12);

5.2 Consulta um-para-um

5.2.1 Requisitos

    Consultar informações do pedido. A associação é a seguinte:    
        1. Informações do usuário relacionadas à consulta de associação.

5.2.2 Realizado por resultType

Classe de entidade:

    A classe de entidade Orders não pode mapear todos os campos e uma classe de entidade recém-criada é necessária para criar uma classe de entidade que inclua mais campos de consulta. OrdersQuery contém os atributos que Orders e Users precisam consultar.

package com.newcapec.vo;

/**
 * OrdersQuery值对象,不是entity/po,因为它和数据库中表的字段不是对应关系
 */
public class OrdersQuery {

    //订单属性
    private Integer id;
    private String orderNumber;
    private Double totalPrice;
    private String status;
    private Integer userId;
    //用户属性
    private String username;
    private String password;
    private String realname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    @Override
    public String toString() {
        return "OrdersQuery{" +
            "id=" + id +
            ", orderNumber='" + orderNumber + '\'' +
            ", totalPrice=" + totalPrice +
            ", status='" + status + '\'' +
            ", userId=" + userId +
            ", username='" + username + '\'' +
            ", password='" + password + '\'' +
            ", realname='" + realname + '\'' +
            '}';
    }
}

interface do mapeador:

package com.newcapec.mapper;

import com.newcapec.vo.OrdersQuery;

import java.util.List;

public interface OrdersMapper {

    List<OrdersQuery> selectUseResultType();
}

arquivo mapeador:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.newcapec.mapper.OrdersMapper">

    <select id="selectUseResultType" resultType="com.newcapec.vo.OrdersQuery">
        select a.id,a.order_number,a.total_price,a.status,a.user_id,b.username,b.password,b.realname
        from orders a, users b where a.user_id=b.id
    </select>
</mapper>

teste:

public class QueryTest {

    @Test
    public void testOneToOneResultType() {
        SqlSession sqlSession = MybatisUtil.getSession();
        OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
        List<OrdersQuery> list = ordersMapper.selectUseResultType();
        for (OrdersQuery ordersQuery : list) {
            System.out.println(ordersQuery);
        }
        sqlSession.close();
    }
}

5.2.3 Realizado por resultMap

  • 5.2.3.1 Classe de entidade

Classe de usuário:

package com.newcapec.entity;

public class Users {

    private Integer id;
    private String username;
    private String password;
    private String realname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    @Override
    public String toString() {
        return "Users{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", password='" + password + '\'' +
            ", realname='" + realname + '\'' +
            '}';
    }
}

Classe do pedido:

    Adicione o atributo Users à classe Orders e o atributo Users é usado para armazenar informações do usuário para consultas associadas.

    Como o usuário de consulta de associação de pedido é um relacionamento um-para-um, um único objeto Usuários é usado aqui para armazenar as informações do usuário da consulta de associação.

package com.newcapec.entity;

public class Orders {

    private Integer id;
    private String orderNumber;
    private Double totalPrice;
    private String status;
    private Integer userId;
    /**
     * 一对一关系属性
     */
    private Users users;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Users getUsers() {
        return users;
    }

    public void setUsers(Users users) {
        this.users = users;
    }

    @Override
    public String toString() {
        return "Orders{" +
                "id=" + id +
                ", orderNumber='" + orderNumber + '\'' +
                ", totalPrice=" + totalPrice +
                ", status='" + status + '\'' +
                ", userId=" + userId +
                ", users=" + users +
                '}';
    }
}
  • 5.2.3.2 interface do mapeador
List<Orders> selectUseResultMap();
  • 5.2.3.3 arquivo mapeador

    tag de associação: Descrição do mapeamento de relacionamento um-para-um.
        propriedade: o nome da propriedade do relacionamento
        javaType: o tipo da propriedade do relacionamento

<resultMap id="selectResultMap" type="com.newcapec.entity.Orders">
    <id column="id" property="id"/>
    <result column="order_number" property="orderNumber"/>
    <result column="total_price" property="totalPrice"/>
    <result column="status" property="status"/>
    <result column="user_id" property="userId"/>
    <association property="users" javaType="com.newcapec.entity.Users">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="realname" property="realname"/>
    </association>
</resultMap>
<select id="selectUseResultMap" resultMap="selectResultMap">
    select a.id,a.order_number,a.total_price,a.status,a.user_id,b.username,b.password,b.realname
    from orders a, users b where a.user_id=b.id
</select>
  • 5.2.3.4 Teste
@Test
public void testOneToOneResultMap() {
    SqlSession sqlSession = MybatisUtil.getSession();
    OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
    List<Orders> list = ordersMapper.selectUseResultMap();
    for (Orders orders : list) {
        System.out.println(orders);
    }
    sqlSession.close();
}

5.2.4 resultType e resultMap realizam o resumo da consulta um-para-um

  • resultType: É relativamente simples usar resultType, se a classe de entidade não incluir o nome da coluna que está sendo consultada, você precisa adicionar o atributo correspondente ao nome da coluna para completar o mapeamento. Se o resultado da consulta não tiver requisitos especiais, é recomendável usar resultType.

  • resultMap: Você precisa definir resultMap separadamente, o que é um pouco problemático de implementar.Se você tiver requisitos especiais para resultados de consulta, poderá usar resultMap para mapear a consulta associada aos atributos da classe de entidade.

  • resultMap pode implementar carregamento lento, mas resultType não pode implementar carregamento lento.

5.3 Consulta um-para-muitos

5.3.1 Requisitos

    Consultar informações do pedido. A associação é a seguinte:
        1. Consulta associada de suas informações de usuário relacionadas
        2. Consulta associada de seus detalhes de pedidos relacionados.

5.3.2 Classe de entidade

Classe de detalhes do pedido:

public class OrdersDetail {
    
    private Integer id;
    private Integer amount;
    private Integer ordersId;
    private Integer goodsId;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Integer getOrdersId() {
        return ordersId;
    }

    public void setOrdersId(Integer ordersId) {
        this.ordersId = ordersId;
    }

    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    @Override
    public String toString() {
        return "OrdersDetail{" +
                "id=" + id +
                ", amount=" + amount +
                ", ordersId=" + ordersId +
                ", goodsId=" + goodsId +
                '}';
    }
}

Classe do pedido:

    Adicione o atributo List<OrdersDetail> detailList à classe Order e o atributo details será usado para armazenar os detalhes do pedido da consulta associada.

    Como os detalhes do pedido da consulta de associação de pedido são um relacionamento um-para-muitos, o objeto de coleção é usado aqui para armazenar as informações de detalhes do pedido da consulta de associação.

public class Orders {

    private Integer id;
    private String orderNumber;
    private Double totalPrice;
    private String status;
    private Integer userId;
    /**
     * 一对一关系属性
     */
    private Users users;
    /**
     * 一对多关系属性
     */
    private List<OrdersDetail> detailList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Users getUsers() {
        return users;
    }

    public void setUsers(Users users) {
        this.users = users;
    }

    public List<OrdersDetail> getDetailList() {
        return detailList;
    }

    public void setDetailList(List<OrdersDetail> detailList) {
        this.detailList = detailList;
    }

    @Override
    public String toString() {
        return "Orders{" +
                "id=" + id +
                ", orderNumber='" + orderNumber + '\'' +
                ", totalPrice=" + totalPrice +
                ", status='" + status + '\'' +
                ", userId=" + userId +
                ", users=" + users +
                ", detailList=" + detailList +
                '}';
    }
}

5.3.3 interface do mapeador

List<Orders> selectOrdersAndDetail();

5.3.4 arquivo mapeador

    tag de coleção: Descrição do mapeamento de relacionamento um-para-muitos.
        propriedade: o nome da propriedade de relacionamento
        ofType: a propriedade de relacionamento é uma coleção de listas, o tipo de elementos armazenados na coleção

<resultMap id="detailResultMap" type="com.newcapec.entity.Orders">
    <id column="id" property="id"/>
    <result column="order_number" property="orderNumber"/>
    <result column="total_price" property="totalPrice"/>
    <result column="status" property="status"/>
    <result column="user_id" property="userId"/>
    <association property="users" javaType="com.newcapec.entity.Users">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="realname" property="realname"/>
    </association>
    <collection property="detailList" ofType="com.newcapec.entity.OrdersDetail">
        <id column="detail_id" property="id"/>
        <result column="amount" property="amount"/>
        <result column="goods_id" property="goodsId"/>
        <result column="id" property="ordersId"/>
    </collection>
</resultMap>
<select id="selectOrdersAndDetail" resultMap="detailResultMap">
    select a.id,a.order_number,a.total_price,a.status,a.user_id,b.username,b.password,b.realname,
    c.id detail_id,c.amount,c.goods_id
    from orders a
    join users b on a.user_id=b.id
    join orders_detail c on a.id=c.orders_id
</select>

5.3.5 Teste

@Test
public void testOneToMany() {
    SqlSession sqlSession = MybatisUtil.getSession();
    OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
    List<Orders> list = ordersMapper.selectOrdersAndDetail();
    for (Orders orders : list) {
        System.out.println(orders);
    }
    sqlSession.close();
}

5.4 Consultas muitos-para-muitos

5.4.1 Pedidos e Mercadorias

  • 5.4.1.1 Requisitos

    Consultar informações do pedido. A associação é a seguinte:
        1. Consulta associada das informações do usuário relacionadas
        2. Consulta associada dos detalhes do pedido relacionado
        3. Consulta associada das informações do produto nos detalhes do pedido

  • 5.4.1.2 Classe de entidade

    Altere o atributo goods_id do tipo Integer na classe OrderDetail para o atributo Goods type, e o atributo goods é usado para armazenar as informações de mercadoria da consulta associada.

    A relação entre pedidos e detalhes do pedido é um-para-muitos, e a relação entre detalhes do pedido e produtos é um-para-um. Por outro lado, a relação entre produtos e detalhes do pedido é um-para-muitos, e a relação entre pedidos detalhes e pedidos são um-para-um, então pedidos e produtos são muitos-para-muitos antes da relação.

Categoria de mercadoria:

public class Goods {

    private Integer id;
    private String goodsName;
    private String description;
    private Double price;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", goodsName='" + goodsName + '\'' +
                ", description='" + description + '\'' +
                ", price=" + price +
                '}';
    }
}

Classe de detalhes do pedido:

public class OrdersDetail {

    private Integer id;
    private Integer amount;
    private Integer ordersId;
    private Integer goodsId;
    /**
     * 一对一关系
     */
    private Goods goods;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public Integer getOrdersId() {
        return ordersId;
    }

    public void setOrdersId(Integer ordersId) {
        this.ordersId = ordersId;
    }

    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public Goods getGoods() {
        return goods;
    }

    public void setGoods(Goods goods) {
        this.goods = goods;
    }

    @Override
    public String toString() {
        return "OrdersDetail{" +
                "id=" + id +
                ", amount=" + amount +
                ", ordersId=" + ordersId +
                ", goodsId=" + goodsId +
                ", goods=" + goods +
                '}';
    }
}
  • 5.4.1.3 interface do mapeador
List<Orders> selectOrdersAndGoods();
  • 5.4.1.4 arquivo mapeador
<resultMap id="goodsResultMap" type="com.newcapec.entity.Orders">
    <id column="id" property="id"/>
    <result column="order_number" property="orderNumber"/>
    <result column="total_price" property="totalPrice"/>
    <result column="status" property="status"/>
    <result column="user_id" property="userId"/>
    <association property="users" javaType="com.newcapec.entity.Users">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="realname" property="realname"/>
    </association>
    <collection property="detailList" ofType="com.newcapec.entity.OrdersDetail">
        <id column="detail_id" property="id"/>
        <result column="amount" property="amount"/>
        <result column="goods_id" property="goodsId"/>
        <result column="id" property="ordersId"/>
        <association property="goods" javaType="com.newcapec.entity.Goods">
            <id column="goods_id" property="id"/>
            <result column="goods_name" property="goodsName"/>
            <result column="description" property="description"/>
            <result column="price" property="price"/>
        </association>
    </collection>
</resultMap>
<select id="selectOrdersAndGoods" resultMap="goodsResultMap">
    select a.id,a.order_number,a.total_price,a.status,a.user_id,b.username,b.password,b.realname,
    c.id detail_id,c.amount,c.goods_id,d.goods_name,d.description,d.price
    from orders a
    join users b on a.user_id=b.id
    join orders_detail c on a.id=c.orders_id
    join goods d on c.goods_id=d.id
</select>
  • 5.4.1.5 Teste
@Test
public void testManyToMany1() {
    SqlSession sqlSession = MybatisUtil.getSession();
    OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
    List<Orders> list = ordersMapper.selectOrdersAndGoods();
    for (Orders orders : list) {
        System.out.println(orders);
    }
    sqlSession.close();
}

5.4.2 Relação muitos-para-muitos entre alunos e cursos

  • 5.4.2.1 Requisitos

    Consulte as informações do aluno e faça a correlação para consultar as informações do curso correspondente do aluno.

  • 5.4.2.2 Estrutura da tabela
CREATE TABLE `course`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `cname` varchar(20)
);

INSERT INTO `course` VALUES (1, '大学语文');
INSERT INTO `course` VALUES (2, '大学英语');
INSERT INTO `course` VALUES (3, '高等数学');
INSERT INTO `course` VALUES (4, 'JAVA语言');
INSERT INTO `course` VALUES (5, '网络维护');
INSERT INTO `course` VALUES (6, '通信原理');

CREATE TABLE `student`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(20),
  `gender` varchar(20),
  `major` varchar(20)
);

INSERT INTO `student` VALUES (1, '小明', '男', '软件工程');
INSERT INTO `student` VALUES (2, '小红', '女', '网络工程');
INSERT INTO `student` VALUES (3, '小丽', '女', '物联网');

CREATE TABLE `student_course`  (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT,
  `student_id` int(11),
  `course_id` int(11)
);

INSERT INTO `student_course` VALUES (1, 1, 1);
INSERT INTO `student_course` VALUES (2, 1, 3);
INSERT INTO `student_course` VALUES (3, 1, 4);
INSERT INTO `student_course` VALUES (4, 2, 1);
INSERT INTO `student_course` VALUES (5, 2, 2);
INSERT INTO `student_course` VALUES (6, 2, 5);
INSERT INTO `student_course` VALUES (7, 3, 2);
INSERT INTO `student_course` VALUES (8, 3, 3);
INSERT INTO `student_course` VALUES (9, 3, 6);
  • 5.4.2.3 Classe de entidade

Categoria do curso:

public class Course {

    private Integer id;
    private String cname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", cname='" + cname + '\'' +
                '}';
    }
}

Classe do aluno:

public class Student {
    private Integer id;
    private String name;
    private String gender;
    private String major;

    /**
     * 一对多
     */
    private List<Course> courseList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }

    public List<Course> getCourseList() {
        return courseList;
    }

    public void setCourseList(List<Course> courseList) {
        this.courseList = courseList;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", major='" + major + '\'' +
                ", courseList=" + courseList +
                '}';
    }
}
  • 5.4.2.4 interface do mapeador
public interface StudentMapper {
    
    List<Student> select();
}
  • 5.4.2.5 arquivo mapeador
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.newcapec.mapper.StudentMapper">

    <resultMap id="selectResultMap" type="com.newcapec.entity.Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="major" property="major"/>
        <collection property="courseList" ofType="com.newcapec.entity.Course">
            <id column="course_id" property="id"/>
            <result column="cname" property="cname"/>
        </collection>
    </resultMap>
    <select id="select" resultMap="selectResultMap">
        select a.id,a.name,a.gender,a.major,b.course_id,c.cname
        from student a
                 join student_course b on a.id=b.student_id
                 join course c ON b.course_id=c.id
    </select>
</mapper>
  • 5.4.2.6 Teste
@Test
public void testManyToMany2() {
    SqlSession sqlSession = MybatisUtil.getSession();
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> list = studentMapper.select();
    for (Student student : list) {
        System.out.println(student);
    }
    sqlSession.close();
}

5.5 Resumo das consultas associadas

5.5.1 tipo de resultado

    Função: mapear os resultados da consulta para objetos de classe de entidade de acordo com a consistência dos nomes de coluna SQL e nomes de atributo de classe de entidade.
    
    Ocasião: é comum exibir alguns registros detalhados. Por exemplo, quando um usuário compra detalhes do produto e exibe todas as informações de consulta relacionadas na página, você pode usar diretamente resultType para mapear cada registro para uma classe de entidade e percorrer a lista no página front-end (a lista é classe de entidade) pode ser.

5.5.2 mapa de resultados

    Use associação e coleção para concluir o mapeamento avançado um-para-um e um-para-muitos (existem requisitos de mapeamento especiais para o resultado).

Associação

    Função: Mapeie as informações de consulta associadas a um objeto de classe de entidade.

    Ocasião: Para facilitar a consulta de informações relacionadas, a associação pode ser usada para mapear as informações relacionadas a um atributo do objeto atual, como ordem de consulta e informações relacionadas ao usuário.

coleção

    Função: mapear as informações de consulta associadas a uma coleção de listas.

    Ocasião: Para facilitar a consulta e passagem de informações relacionadas, você pode usar coleção para mapear informações relacionadas à coleção de lista. Por exemplo: para consultar o módulo de escopo de autoridade do usuário e o menu sob o módulo, você pode usar coleção para mapear o módulo para a lista de módulos e mapear a lista de menus para o módulo No atributo de lista de menus do objeto, o objetivo desta operação também é facilitar a consulta transversal do conjunto de resultados da consulta. Se resultType for usado, o resultado da consulta não poderá ser mapeado para a coleção de listas.

Herança de resultMap

     A tag resultMap pode herdar um resultMap existente ou público por meio do atributo extends, evitando configuração repetida e reduzindo a quantidade de configuração.

Os exemplos são os seguintes:

<!-- 父resultMap标签-->
<resultMap id="baseResultMap" type="com.newcapec.entity.Orders">
    <id column="id" property="id"/>
    <result column="order_number" property="orderNumber"/>
    <result column="total_price" property="totalPrice"/>
    <result column="status" property="status"/>
    <result column="user_id" property="userId"/>
</resultMap>
<!-- 继承父resultMap标签中的配置,避免重复配置 -->
<resultMap id="subResultMap" type="com.newcapec.entity.Orders" extends="baseResultMap">
    <association property="users" javaType="com.newcapec.entity.Users">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="realname" property="realname"/>
    </association>
</resultMap>

Acho que você gosta

Origin blog.csdn.net/ligonglanyuan/article/details/124396983
Recomendado
Clasificación