mybatis关系映射之一对多和多对一

MyBatis 是一款优秀的 ORM 框架,提供给我们了一些关系映射的解决方案。其中比较常见的一对多和多对一的关系映射,我们可以通过 MyBatis 提供的标签和注解来实现。

一对多关系映射

一对多关系通常是指一个实体类关联多个实体类的情况,例如一个学院对应多个专业,一个专业对应多个学生。在 MyBatis 中,我们可以通过使用 Collection 和 Association 标签来实现一对多的关系映射。

使用 Collection 标签

我们假设有一个学院表和一个专业表,一个学院对应多个专业,那么我们的实体类设计可以如下:

public class College {
    private Integer id;
    private String name;
    private List<Major> majors;
    // getter、setter
}

public class Major {
    private Integer id;
    private String name;
    private Integer collegeId;
    // getter、setter
}

我们需要在 CollegeMapper.xml 中编写返回类型为 College 的 select 语句,用于查询学院和其下的所有专业。我们可以在 College 对象中添加一个 List 类型的属性 majors 来封装查询结果,使用 Collection 标签来实现:

<select id="findCollegeWithMajors" resultType="College">
    SELECT c.id, c.name,
        m.id AS `majors.id`,
        m.name AS `majors.name`,
        m.college_id AS `majors.collegeId`
    FROM college c
        LEFT JOIN major m ON c.id = m.college_id
    WHERE c.id = #{id}
    ORDER BY m.id
</select>

上述 SQL 语句中使用了别名语法来将 select 查询结果中的 majors.id、majors.name 和 majors.college_id 映射到 Major 对象的属性中。在查询结果集中,按照 Major 的 id 升序排序。

接下来,我们在 CollegeMapper 接口中添加一个方法来调用上述查询语句:

public interface CollegeMapper {
    College findCollegeWithMajors(Integer id);
}

最后,在使用 CollegeMapper 接口的地方就可以调用此方法查询学院和其下的专业:

College college = collegeMapper.findCollegeWithMajors(1);

使用 Association 标签

在有些情况下,我们需要将一对多的关联对象作为一个单一的属性进行封装,如将所有专业封装到一个字符串中。此时,我们可以使用 Association 标签来实现。

使用 Association 标签时,我们需要定义一个实体类来封装关联对象的多个属性。假设我们需要将一个学院下的所有专业名封装到一个字符串中,我们需要先新建一个封装类:

public class CollegeWithMajorNames {
    private Integer id;
    private String name;
    private String majorNames;  // 专业名,以逗号分隔
    // getter、setter
}

然后在 CollegeMapper.xml 中编写返回类型为 CollegeWithMajorNames 的 select 语句:

<select id="findCollegeWithMajorNames" resultType="CollegeWithMajorNames">
    SELECT c.id, c.name,
        GROUP_CONCAT(m.name SEPARATOR ',') AS `majorNames`
    FROM college c
        LEFT JOIN major m ON c.id = m.college_id
    WHERE c.id = #{id}
    GROUP BY c.id
</select>

上述 SQL 语句使用了 MySQL 的 GROUP_CONCAT 函数将多条查询结果合并为一个字符串,使用逗号作为分隔符。在查询结果集中,仅有一个 CollegeWithMajorNames 对象。

最后,我们在 CollegeMapper 接口中添加一个方法来调用上述查询语句:

public interface CollegeMapper {
    CollegeWithMajorNames findCollegeWithMajorNames(Integer id);
}

最终,在使用 CollegeMapper 接口的地方就可以调用此方法查询学院和其下的专业名:

CollegeWithMajorNames collegeWithMajorNames = collegeMapper.findCollegeWithMajorNames(1);

多对一关系映射

多对一关系通常是指多个实体类关联一个实体类的情况,例如多个学生对应一个专业,多个专业对应一个学院。在 MyBatis 中,我们可以通过使用 ResultMap 标签和对应实体类的关联属性来实现多对一的关系映射。

假设一个学生表和一个专业表,一个学生对应一个专业,一个专业对应一个学院,那么我们的实体类设计可以如下:

public class Student {
    private Integer id;
    private String name;
    private Integer majorId;
    // getter、setter
}

public class Major {
    private Integer id;
    private String name;
    private Integer collegeId;
    // getter、setter
}

public class College {
    private Integer id;
    private String name;
    // getter、setter
}

我们需要在 StudentMapper.xml 中编写返回类型为 Student 的 select 语句,用于查询学生和其所属的专业和学院。我们可以在 Student 对象中添加一个 Major 类型的属性 major 和一个关联属性 college,分别表示学生所属的专业和所属的学院。使用 ResultMap 标签和对应实体类的关联属性来实现多对一的关系映射:

<resultMap id="studentResultMap" type="Student">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <association property="major" column="major_id" javaType="Major" select="findMajorById"/>
    <association property="college" javaType="College">
        <id column="college_id" property="id"/>
        <result column="college_name" property="name"/>
    </association>
</resultMap>

<select id="findStudentWithMajorAndCollege" resultMap="studentResultMap">
    SELECT s.id, s.name,
        s.major_id,
        m.college_id,
        m.name AS `major.name`,
        c.id AS `college.id`,
        c.name AS `college_name`
    FROM student s
        JOIN major m ON s.major_id = m.id
        JOIN college c ON m.college_id = c.id
    WHERE s.id = #{id}
</select>

<select id="findMajorById" resultType="Major">
    SELECT id, name, college_id FROM major WHERE id = #{id}
</select>

上述 SQL 语句中,我们需要先定义一个 ResultMap 标签,并使用 association 标签来表示关联属性。在 association 标签中使用 id 标签表示关联对象的主键,使用 result 标签来将查询结果中的列映射到关联对象的属性中。在第二个 association 标签中,我们将 Java 类型指定为 College,表示既然已经查询过 Major 的信息,也就同时查询了 College 的信息,可以将其封装到一个新的对象中。

接下来,我们在 StudentMapper 接口中添加一个方法来调用上述查询语句:

public interface StudentMapper {
    Student findStudentWithMajorAndCollege(Integer id);
}

最后,在使用 StudentMapper 接口的地方就可以调用此方法查询学生和其所属的专业和学院:

Student student = studentMapper.findStudentWithMajorAndCollege(1);

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis关系映射之一对多和多对一 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • MySQL 同主机不同数据库之间的复制

    MySQL同主机不同数据库的复制命令:注意运行在Terminal中,不运行在MySQL命令行中。 mysqldump Portal_DEV -u root -ppassword1 –add-drop-table | mysql Portal_Optimize -u root -ppassword1 在复制过程中,出现如下报错: ERROR 1153 (08…

    MySQL 2023年4月16日
    00
  • wamp 安装redis扩展

    phpredis扩展下载地址  http://windows.php.net/downloads/pecl/snaps/redis/ 1.选择redis DLL文件扩展 phpinfo 查看VC版本 还有系统位数 再进行下载  所以选择上面这个 选择ts就行     2. 将下载好的php_redis.dll放入E:\wamp64\bin\php\php5.…

    Redis 2023年4月11日
    00
  • Mysql的Table doesn’t exist问题及解决

    Mysql数据库是一个非常流行的关系型数据库管理系统,但在使用过程中会遇到各种问题,其中一个常见问题就是“Table doesn’t exist”(表不存在)的错误。下面是如何解决这个问题的完整攻略。 问题原因 该问题的原因通常是由于数据库中没有该表造成的。有以下几个可能性: 数据库名称错误:如果数据库名称输入错误,那么就找不到该表。例如,如果你输入了类似S…

    database 2023年5月18日
    00
  • MySQL时间类型和模式详情

    MySQL是一种流行的关系型数据库系统,它提供了多种时间类型和模式,用于存储和处理时间数据。本文将详细介绍MySQL时间类型和模式的详细攻略。 时间类型 MySQL支持六种时间类型,分别是: DATE:日期类型,格式为YYYY-MM-DD,用于存储日期数据。 TIME:时间类型,格式为HH:MM:SS,用于存储时间数据。 DATETIME:日期时间类型,格式…

    database 2023年5月18日
    00
  • spring声明式事务 @Transactional 不回滚的多种情况以及解决方案

    下面我将详细讲解“spring声明式事务 @Transactional 不回滚的多种情况以及解决方案”。 一、@Transactional不回滚的多种情况 1.1 默认回滚规则 默认情况下,Spring会对所有运行时异常进行回滚。也就是说,只有在方法中抛出RuntimeException及其子类异常时,才会导致事务回滚。 对于受检异常(即继承自Excepti…

    database 2023年5月21日
    00
  • Django中celery的使用项目实例

    对于Django中celery的使用项目实例攻略,我将按照以下步骤来进行详细讲解: 安装celery 在Django项目中使用celery,需要先通过pip安装celery。在命令行中输入以下命令可以安装celery: pip install celery 配置celery 在Django项目的settings.py中配置celery。首先,需要添加以下内容…

    database 2023年5月22日
    00
  • PostgreSQL中json数据类型详解

    PostgreSQL中json数据类型详解 什么是json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 JSON格式中的数据可以被任何编程语言读取和解析,因为它使用了键值对的形式。此外,JSON是一种自文档化的数据结构。 PostgreSQL 中的json PostgreSQL支持JSON格式的存储、查询和…

    database 2023年5月19日
    00
  • VMware15安装CentOS7详细过程以及常见问题(图文)

    VMware15安装CentOS7详细过程以及常见问题(图文) 1. 下载安装VMware Workstation 15 首先,我们需要下载安装VMware Workstation 15,它是VMware公司推出的一款虚拟机软件,它可以在你的Windows、Mac、Linux电脑上创建和运行虚拟机。下载安装过程略。 2. 下载CentOS7 ISO镜像文件 …

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部