在 MyBatis 中实现一对多映射时,可以通过 resultMap
配置来实现。假设我们有两个表:Category
和 Product
,一个 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();
}
resultMap
3. 配置一对多的 在 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 的一对多映射:
- 在数据库中建立一对多的外键关系。
- 在 MyBatis 中通过
resultMap
定义一对多的映射。 - 在 Service 层与 Controller 层调用一对多查询并返回结果。
这样我们就完成了一个简单的 MyBatis 一对多映射示例。如果有更多复杂的需求,也可以通过自定义查询和复杂的 resultMap
实现多层嵌套映射。