笔记 笔记
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

EasT-Duan

Java 开发
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

购买兑换码请添加

添加时候请写好备注,否则无法通过。

  • Maven

  • Bootstrap

  • Spring

  • Spring MVC

  • MyBatis

    • MyBatis 简介
    • Spring 整合 MyBatis
    • Spring 整合 Druid
    • 动态 SQL
    • 关联关系
      • 一对一
      • 一对多
      • 多对多
  • JUnit

  • GitFlow 工作流指南

  • SpringBoot

  • Reactor

  • 微服务

  • Java Web
  • MyBatis
EasT-Duan
2023-09-14
目录

关联关系

欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。

# 一对一

  1. 创建两个实体类

    @Data
    public class User {
        //用户ID
        private int id;
        //用户姓名
        private String username;
        //用户性别
        private String sex;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Data
    public class Orders {
        //订单ID
        private int id;
        //用户ID
        private int userId;
        //订单数量
        private String number;
        //和用户表构成一对一的关系,即一个订单只能由一个用户创建
        private User user;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  2. 创建 OrderMapper 接口和 OrderMapper.xml 文件

    public interface OrdersMapper {
        /**
         * 方式一:嵌套结果
         * select * from orders o,user u where o.user_id=u.id and o.id=#{id}
         * @param orderId
         * @return
         */
        //根据订单ID查询订单和用户信息
        public Orders selectOrderAndUserByOrderID(int orderId);
    
        /**
         * 方式二:嵌套查询
         * select * from order WHERE id=1;//得到user_id
         * select * from user WHERE id=1   //1 是上一个查询得到的user_id的值
         * @param orderId
         * @return
         */
        //根据订单ID得到订单信息(包含user_id)
        public Orders getOrderByOrderId(int orderId);
    
        //根据用户ID查询用户信息
        public User getUserByUserId(int userID);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?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="one.to.one.mapper.OrdersMapper">
          <resultMap type="com.ys.po.Orders" id="getOrderAndUser">
            <!--
                 id:指定查询列表唯一标识,如果有多个唯一标识,则配置多个id
                 column:数据库对应的列
                 property:实体类对应的属性名
             -->
            <id column="id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <!-- association:用于映射关联查询单个对象的信息
                 property:实体类对应的属性名
                 javaType:实体类对应的全类名
             -->
            <association property="user" javaType="com.ys.po.User">
                <!--
                     id:指定查询列表唯一标识,如果有多个唯一标识,则配置多个id
                     column:数据库对应的列
                     property:实体类对应的属性名
                  -->
                <id column="id" property="id"/>
                <result column="username" property="username"/>
                <result column="sex" property="sex"/>
            </association>
        </resultMap>
        <!-- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 封装联表查询的数据(去除重复的数据)
     		select * from orders o,user u where o.user_id=u.id and o.id=#{id}
     	-->
        <select id="selectOrderAndUserByOrderID" resultMap="getOrderAndUser">
     		select * from orders o,user u where o.user_id=u.id and o.id=#{id}
     	</select>
        
        
        <!--
             方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
             select user_id from order WHERE id=1;//得到user_id
             select * from user WHERE id=1  //1 是上一个查询得到的user_id的值
             property:别名(属性名)    
             column:列名 
          -->
        <select id="getOrderByOrderId" resultMap="getOrderMap">
     		select * from order where id=#{id}
     	</select>
        
        <resultMap type="com.ys.po.Orders" id="getOrderMap">
            <id column="id" property="id"/>
            <result column="number" property="number"/>
            <association property="userId"  column="id" select="getUserByUserId"></association>
        </resultMap>
        
        <select id="getUserByUserId" resultType="com.ys.po.User">
     		select * from user where id=#{id}
     	</select>
    </mapper> 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58

# 一对多

  1. 修改 User

    @Data
    public class User {
        //用户ID
        private int id;
        //用户姓名
        private String username;
        //用户性别
        private String sex;
        //一个用户能创建多个订单,用户和订单构成一对多的关系
        public List<Orders> orders;
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  2. 创建 UserMapper 接口和 UserMapper.xml 文件

    public interface UserMapper {
        //根据用户id查询用户信息,以及用户下面的所有订单信息
        public User selectUserAndOrdersByUserId(int UserId);
    } 
    
    1
    2
    3
    4
    <?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="one.to.many.mapper.UserMapper">
      <!--
      方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
      封装联表查询的数据(去除重复的数据)
      select * from user u,orders o where u.id=o.user_id and u.id=#{id}
      -->
      <select id="selectUserAndOrdersByUserId" resultMap="getUserAndOrders">
        select u.*, o.id oid, o.number number
        from user u,
             orders o
        where u.id = o.user_id
          and u.id = #{id}
      </select>
      <resultMap type="com.ys.po.User" id="getUserAndOrders">
        <!--id:指定查询列表唯一标识,如果有多个唯一标识,则配置多个id
        column:数据库对应的列
        property:实体类对应的属性名 -->
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <!--
        property:实体类中定义的属性名
        ofType:指定映射到集合中的全类名
        -->
        <collection property="orders" ofType="com.ys.po.Orders">
          <id column="oid" property="id"/>
          <result column="number" property="number"/>
        </collection>
      </resultMap>
    </mapper> 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

# 多对多

这里我们以用户 user 表和 角色 role 表为例,假定一个用户能被分配成多重角色,而一种角色也能分给多个用户,故用户和角色构成多对多的关系。

  • 需求:实现查询所有对象并且加载它所分配的用户信息。

  • 分析:查询角色我们需要用到 Role 表,但角色分配的用户的信息我们并不能直接找到用户信息,而是要通过中间表 (USER_ROLE 表)
    才能关联到用户信息。

  • SQL:

    SELECT 
      r.*,
      u.id uid,
      u.username username,
      u.birthday birthday,
      u.sex sex,
      u.address address 
    FROM
      user u,
      role r,
      user_role ur 
    WHERE u.`id` = ur.`UID` 
      AND ur.`RID` = r.`ID`
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

  1. 修改 User

    @Data
    public class User {
        //用户ID
        private int id;
        //用户姓名
        private String username;
        //用户性别
        private String sex;
        //生日
        private Date birthday;
        //用户性别
        private String address;
        //角色信息
        public List<Role> roles;
    } 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Data
    public class Role {
        private int id;
        private String name;
        private String roleDesc;
        private List<User> users;
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. 创建 RoleMapper 接口和 UserMapper.xml 文件

    public interface RoleMapper {
    	/**
    	 * 查询所有的角色
    	 * @title: findAll
    	 * @return
    	 */
    	List<Role> findAll();
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 定义resultmap -->
    <resultMap type="Role" id="roleMap">
        <id property="roleId" column="ID" />
        <result property="roleName" column="ROLE_NAME" />
        <result property="roleDesc" column="ROLE_DESC" />
        <collection property="users" ofType="user">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
        </collection>
    </resultMap>
    <!--配置查询所有 -->
    <select id="findAll" resultMap="roleMap">
        SELECT
        r.*,
        u.id uid,
        u.username username,
        u.birthday birthday,
        u.sex sex,
        u.address address
        FROM
        USER u,
        role r,
        user_role ur
        WHERE u.`id` = ur.`UID`
        AND ur.`RID` = r.`ID`
    </select>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
#MyBatis
上次更新: 2025/04/12, 05:37:39
动态 SQL
JUnit 简介

← 动态 SQL JUnit 简介→

最近更新
01
Reactor 核心
02-24
02
前置条件
10-30
03
计算机网络
09-13
更多文章>
Theme by Vdoing | Copyright © 2019-2025 powered by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式