首页 > 其他分享 ><collection> 和 <association>的详细用法(附详细代码解析)

<collection> 和 <association>的详细用法(附详细代码解析)

时间:2024-10-27 20:16:52浏览次数:3  
标签:映射 标签 collection private 详细 属性 id association User

MyBatis 中的 <association><collection> 标签

在 MyBatis 中,<association><collection> 标签用于配置复杂查询的结果集关联映射,主要用于处理实体类之间的嵌套关系。二者的区别在于:

  • <association> 标签用于一对一的关系映射,比如实体类 A 中包含一个实体类 B 的对象。
  • <collection> 标签用于一对多的关系映射,比如实体类 A 中包含一个 B 类对象的集合。

示例:<association><collection> 标签的区别

我们以下面的场景为例:

  • 一个 User 实体类,它有一个 Address 实体类的属性(表示一对一关系)。
  • 一个 User 实体类,它有多个 Order 实体类的对象(表示一对多关系)。

数据库表结构

假设有三个表:useraddressorders,表结构如下:

user 表结构:
CREATE TABLE user (
    id BIGINT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    address_id BIGINT
);
address 表结构:
CREATE TABLE address (
    id BIGINT PRIMARY KEY,
    city VARCHAR(50),
    street VARCHAR(100)
);
orders 表结构:
CREATE TABLE orders (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    product_name VARCHAR(100),
    price DECIMAL(10, 2)
);

实体类定义

以下是 Java 实体类定义:

User 实体类:
public class User {
    private Long id;
    private String name;
    private int age;
    private Address address; // 一对一关系
    private List<Order> orders; // 一对多关系

    // getters and setters
}
Address 实体类:
public class Address {
    private Long id;
    private String city;
    private String street;

    // getters and setters
}
Order 实体类:
public class Order {
    private Long id;
    private Long userId;
    private String productName;
    private BigDecimal price;

    // getters and setters
}

MyBatis 映射配置

UserMapper.xml 配置

UserMapper.xml 中使用 <association><collection> 标签来映射复杂关系:

<mapper namespace="com.example.mapper.UserMapper">
    <!-- 查询用户及其地址和订单信息 -->
    <select id="getUserById" resultMap="userResultMap">
        SELECT
            u.id AS user_id, u.name, u.age,
            a.id AS address_id, a.city, a.street,
            o.id AS order_id, o.product_name, o.price
        FROM user u
        LEFT JOIN address a ON u.address_id = a.id
        LEFT JOIN orders o ON u.id = o.user_id
        WHERE u.id = #{id}
    </select>

    <!-- 用户结果映射 -->
    <resultMap id="userResultMap" type="com.example.entity.User">
        <id property="id" column="user_id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        
        <!-- 一对一映射 Address -->
        <association property="address" javaType="com.example.entity.Address" columnPrefix="address_" fetchType="lazy" select="com.example.mapper.AddressMapper.getAddressById">
            <id property="id" column="address_id"/>
            <result property="city" column="city"/>
            <result property="street" column="street"/>
        </association>

        <!-- 一对多映射 Orders -->
        <collection property="orders" ofType="com.example.entity.Order" columnPrefix="order_" fetchType="lazy">
            <id property="id" column="order_id"/>
            <result property="productName" column="product_name"/>
            <result property="price" column="price"/>
        </collection>
    </resultMap>
</mapper>
  • <association> 标签:用于映射 User 和 Address 之间的一对一关系,将 Address 的属性映射到 User 对象中的 address 属性上。

    • columnPrefix 属性:用于为关联对象的列指定前缀,以避免与其他表的列名冲突。
    • fetchType 属性:用于指定加载方式,lazy 表示懒加载,eager 表示立即加载。
    • select 属性:用于指定关联关系中需要调用的查询方法,这里可以指定一个 Mapper 方法(例如 com.example.mapper.AddressMapper.getAddressById),以实现更灵活的关联查询。
  • <collection> 标签:用于映射 User 和 Order 之间的一对多关系,将 Order 的列表映射到 User 对象中的 orders 属性上。

    • columnPrefix 属性:与 <association> 中的 columnPrefix 类似,用于避免列名冲突。
    • fetchType 属性:指定加载方式,支持懒加载和立即加载。

常用的高级属性与用法

除了上面提到的 <association><collection> 标签中使用的常见属性外,还有一些高级的标签和属性可以提高 MyBatis 的映射功能和灵活性:

  1. resultMap 标签中的 autoMapping 属性

    • autoMapping:自动映射列到属性,true 表示自动进行映射,false 表示不自动映射,可以用于减少手动配置的工作量。
    <resultMap id="userResultMap" type="com.example.entity.User" autoMapping="true">
        ...
    </resultMap>
    
  2. <constructor> 标签

    • <constructor> 标签用于在对象创建时通过构造函数传递参数。
    • 可以使用 <idArg><arg> 标签来指定构造函数参数的映射关系。
    <resultMap id="userResultMap" type="com.example.entity.User">
        <constructor>
            <idArg column="user_id" javaType="Long"/>
            <arg column="name" javaType="String"/>
            <arg column="age" javaType="int"/>
        </constructor>
        ...
    </resultMap>
    
  3. <discriminator> 标签

    • 用于处理多态对象的映射关系。可以根据某个字段的值来动态选择不同的子类映射。
    • 例如根据用户类型字段 user_type 来区分普通用户和管理员。
    <resultMap id="userResultMap" type="com.example.entity.User">
        <id property="id" column="user_id"/>
        <result property="name" column="name"/>
        <discriminator javaType="String" column="user_type">
            <case value="ADMIN" resultType="com.example.entity.AdminUser"/>
            <case value="USER" resultType="com.example.entity.RegularUser"/>
        </discriminator>
    </resultMap>
    
  4. <collection><association>cascade 属性

    • cascade:指定在父对象操作时是否对关联对象进行级联操作,例如插入、更新和删除。MyBatis 不直接提供 cascade 的配置,但可以通过编程方式实现类似的级联操作。
  5. select 属性的动态关联

    • select 属性 可以使用动态参数,灵活地调用其他查询,特别是在需要根据不同条件关联查询的时候,能极大增强查询能力。

Mapper 接口

定义 UserMapper 接口用于数据库访问:

public interface UserMapper {
    User getUserById(Long id);
}

定义 AddressMapper 接口,用于单独查询 Address 数据:

public interface AddressMapper {
    Address getAddressById(Long id);
}

Service 层

在 Service 层通过注入 UserMapper 来调用查询方法:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }
}

Controller 层

在 Controller 层处理前端的请求,返回用户数据:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
}

前端返回的 JSON 数据

假设用户的 ID 为 1,数据库中的数据如下:

  • User 表中:{id: 1, name: "John", age: 30, address_id: 1}
  • Address 表中:{id: 1, city: "New York", street: "5th Avenue"}
  • Orders 表中有两条记录:
    • {id: 1, user_id: 1, product_name: "Laptop", price: 1200.00}
    • {id: 2, user_id: 1, product_name: "Smartphone", price: 800.00}

返回的 JSON 数据将会是:

{
  "id": 1,
  "name": "John",
  "age": 30,
  "address": {
    "id": 1,
    "city": "New York",
    "street": "5th Avenue"
  },
  "orders": [
    {
      "id": 1,
      "productName": "Laptop",
      "price": 1200.00
    },
    {
      "id": 2,
      "productName": "Smartphone",
      "price": 800.00
    }
  ]
}

总结

  • <association> 标签 用于一对一映射,将 Address 映射到 User 对象的 address 属性中,支持属性如 columnPrefixfetchTypeselect 来控制列前缀、加载方式和关联查询。
  • <collection> 标签 用于一对多映射,将 Order 列表映射到 User 对象的 orders 属性中,类似地支持 columnPrefixfetchType 等属性。
  • <constructor> 标签 可以用于通过构造函数创建对象。
  • <discriminator> 标签 适用于多态映射,根据某些字段动态选择子类映射。

这些高级标签和属性在 MyBatis 的复杂查询和结果集映射中非常有用,能有效地将关系型数据库的数据转换为 Java 对象,从而简化开发工作。

标签:映射,标签,collection,private,详细,属性,id,association,User
From: https://blog.csdn.net/2302_78571314/article/details/143273686

相关文章

  • MySQL入门到实战详细教程
    MySQL介绍MySQL是一个开源的关系型数据库管理系统(RDBMS),由瑞典MySQLAB公司开发,属于Oracle旗下产品,它广泛应用于各种Web应用程序和网站,MySQL使用结构化查询语言(SQL)进行数据的管理和操作。MySQL主要特点开源免费:MySQL是一个开源项目,可以自由下载和使用。跨平台支持:MySQL可以在多......
  • wpf 数据绑定 列表 ObservableCollection
    #wpf数据绑定列表ObservableCollectionPrismDryIocDemo\PrismDryIocDemo\App.xaml<Applicationx:Class="PrismDryIocDemo.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http......
  • 网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇你就是网络安全高手了。
       关于我我算是“入行”不久的一个新人安全工作者,为什么是引号呢,因为我是个“半个野路子”出身。早在13年的时候,我在初中时期就已经在90sec、wooyun等社区一直学习、报告漏洞。后来由于升学的压力,我逐渐淡出了安全圈子,也没有继续学习技术。也因为这个原因,高考选择专业时......
  • 基于SpringBoot+Vue+uniapp的学生知识成果展示与交流的详细设计和实现(源码+lw+部署文
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 点跟踪论文—CoTracker: It is Better to Track Together使用Transform的时间与空间注
    CoTracker:ItisBettertoTrackTogether使用Transform的时间与空间注意力机制的密集点联合追踪算法详细解析文章概括总结:在之前学习的TrackingEverythingEverywhereAllatOnce(2023ICCV最佳学生论文)与RAFT:RecurrentAll-PairsFieldTransformsforOpticalF......
  • 小北在GitHub上克隆项目(超详细的图文并解)之用 Python 对图片和视频进行高清修复
    前言    估计友友们应该在网上看过很多用AI修复的高清视频,最近我也有相关需求,需要修复几张图片。于是便去GitHub上寻找相关开源项目,结果还真找到一个,效果还很不错,小北这里特意分享出来给友友们~Real-ESRGAN对于算法小白的上手还是比较容易的,即便不懂算法知识,也......
  • 详细解释这段代码及其工作原理
    详细解释这段代码及其工作原理。代码分析@GetMapping("/")publicStringindex(Modelmodel){List<Map<String,Object>>users=jdbcTemplate.queryForList("SELECT*FROMusers");model.addAttribute("users",users);retu......
  • Sqoop迁移工具大全. [概述,特点,安装与使用.最后详细阐述和DataX,Kettle等迁移工具的
    目录一,Sqoop的概述二,Sqoop的特点三,Sqoop的安装四,Sqoop快速入门五,从MySQL中导入数据到HDFS中六,从MySQL导入数据到Hive中七,从MySQL导入到Hive中并且存储格式是ORC八,Sqoop和DataX以及Kettle的区别一、Sqoop二、DataX三、Kettle四、总结一,Sqoop的概......
  • (已解决!!!非常详细)无法连接redis服务器
    问题:写springboot项目连接redis失败,报错如下:也可能有其他报错,反正就是连接不上发现能连接上虚拟机,但是连接不上redis上网寻求解决方法,发现一些文章比较乱不是很容易理解,所以总结了一下网上的方法成功解决前提:已经在vmware安装好centos,并且已经安装了redis且能运行,使用p......
  • 一篇最全Python 爬虫超详细讲解(零基础入门,适合小白)
    爬虫是指通过编程自动从网页上获取信息的技术.想象你平时打开网页,右键点击“查看源代码”,那些你看到的HTML代码就是网页的结构,而爬虫就像一位帮你阅读这些网页内容的“机器人”.创作不易,还请各位同学三连点赞!!收藏!!转发!!!刚入门学习Python的小伙伴可以试试我的这份学习方法......