在 MyBatis 中实现一对多映射时,可以通过 resultMap 配置来实现。假设我们有两个表:CategoryProduct,一个 Category 可以有多个 Product,即这是一个一对多的关系。下面是一个具体的示例,展示如何使用 MyBatis 实现一对多映射。

示例场景

假设有以下两个表:

category 表:

CREATE TABLE category (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255)
);

product 表:

CREATE TABLE product (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255),
    price DECIMAL(10, 2),
    category_id INT,
    FOREIGN KEY (category_id) REFERENCES category(id)
);

1. 创建实体类

Category 实体类

package com.example.entity;

import lombok.Data;
import java.util.List;

@Data
public class Category {
    private Integer id;
    private String name;
    private List<Product> products; // 一对多关系,产品列表
}

Product 实体类

package com.example.entity;

import lombok.Data;

@Data
public class Product {
    private Integer id;
    private String name;
    private Double price;
    private Integer categoryId;
}

2. 创建 Mapper 接口

CategoryMapper.java

package com.example.mapper;

import com.example.entity.Category;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface CategoryMapper {

    // 通过 category id 查询所有产品的类别信息(包括产品信息)
    @Select("SELECT * FROM category")
    List<Category> findAllCategoriesWithProducts();
}

3. 配置一对多的 resultMap

CategoryMapper.xml 中定义 resultMap 来实现一对多映射。

CategoryMapper.xml

<?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.example.mapper.CategoryMapper">

    <!-- 定义一对多的 resultMap -->
    <resultMap id="CategoryProductMap" type="com.example.entity.Category">
        <!-- 类别的字段映射 -->
        <id column="id" property="id" />
        <result column="name" property="name" />
        
        <!-- 嵌套映射:映射产品列表 -->
        <collection property="products" ofType="com.example.entity.Product">
            <id column="id" property="id" />
            <result column="name" property="name" />
            <result column="price" property="price" />
            <result column="category_id" property="categoryId" />
        </collection>
    </resultMap>

    <!-- 查询类别和产品 -->
    <select id="findAllCategoriesWithProducts" resultMap="CategoryProductMap">
        SELECT 
            c.id AS category_id, 
            c.name AS category_name, 
            p.id AS product_id, 
            p.name AS product_name, 
            p.price AS product_price, 
            p.category_id AS product_category_id
        FROM 
            category c
        LEFT JOIN 
            product p 
        ON 
            c.id = p.category_id;
    </select>
</mapper>

4. Service 层与 Controller 实现

CategoryService.java

package com.example.service;

import com.example.entity.Category;
import com.example.mapper.CategoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    public List<Category> findAllCategoriesWithProducts() {
        return categoryMapper.findAllCategoriesWithProducts();
    }
}

CategoryController.java

package com.example.controller;

import com.example.entity.Category;
import com.example.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    @GetMapping("/categories")
    public List<Category> getCategoriesWithProducts() {
        return categoryService.findAllCategoriesWithProducts();
    }
}

5. 测试

启动应用后,访问 http://localhost:8080/categories,可以查看到 Category 及其 Product 列表。

总结

在这个实现中,我们通过以下几个步骤实现了 MyBatis 的一对多映射:

  1. 在数据库中建立一对多的外键关系。
  2. 在 MyBatis 中通过 resultMap 定义一对多的映射。
  3. 在 Service 层与 Controller 层调用一对多查询并返回结果。

这样我们就完成了一个简单的 MyBatis 一对多映射示例。如果有更多复杂的需求,也可以通过自定义查询和复杂的 resultMap 实现多层嵌套映射。