首页 > 其他分享 >MyBatis中一对多关系的两种处理方法

MyBatis中一对多关系的两种处理方法

时间:2024-09-19 18:49:28浏览次数:13  
标签:classId Classes 两种 int id classes MyBatis 一对 public

目录

1.多表联查(通过collection标签的ofType属性)

1)mapper

2)mapper.xml

3)测试代码

4)测试结果

2.分布查询(通过collection标签的select属性)

1)mapper

2)mapper.xml

3)测试代码

4)测试结果

附录

1.Classes实体类

2.student类

3.OneToManyMapper

4.OneToManyMapper.xml

5.OneToManyMapperTest.xml

 6.sql

studentSql

classesSql


1.多表联查(通过collection标签的ofType属性)

1)mapper

/**
 * collectionBy ofType
 */
Classes queryClassesAndStudentBycollection(@Param("id") int id);

2)mapper.xml

<!--collection-->
<resultMap id="collectionResultMap" type="org.xiji.enty.Classes">
    <id property="cid" column="cid"/>
    <result property="className" column="className"/>
    <!--collection-->

    <collection property="students" ofType="org.xiji.enty.Student">
        <id property="sid" column="sid"/>
        <result property="studentName" column="studentName"/>
        <result property="studentAge" column="studentAge"/>
        <result property="classId" column="cid"/>

    </collection>

</resultMap>
<select id="queryClassesAndStudentBycollection" resultMap="collectionResultMap" >

    select * from classes c right join student s on c.cid = s.classId where c.cid=#{id}
</select>

解释:

  1. 主对象映射
    1. MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
    2. 主键 cid 和属性 className 直接映射到对应的数据库列。
  2. 集合映射
    1. collection 标签用于映射 Classes 对象中的 students 集合。
    2. 每个 Student 对象的属性 sid, studentName, studentAge, classId 分别映射到对应的数据库列。

3)测试代码

/**
 * 通过collection关联查询
 */
@Test
public void queryClassesAndStudentByAssociation()
{
    Classes classes = oneToManyMapper.queryClassesAndStudentBycollection(1);
    System.out.println(classes);
    List<Student> students = classes.getStudents();
    for (Student student : students) {
        System.out.println(student.toString());
    }
}

4)测试结果

2.分布查询(通过collection标签的select属性)

1)mapper

/**
 * 分布查询
 */
Classes queryClassesAndStudentByStep(@Param("id") int id);


/**
 * 查询id
 */
List<Student> queryClassesAndStudentByStepTwo(int id);

2)mapper.xml

<!--通过分布查询-->
<resultMap id="stepResultMap" type="org.xiji.enty.Classes">
    <id property="cid" column="cid"/>
    <result property="className" column="className"/>
    <collection property="students"
                select="queryClassesAndStudentByStepTwo"
                column="cid"
                ofType="org.xiji.enty.Student"
    >

        <id property="sid" column="sid"></id>
        <result property="classId" column="classId"></result>
        <result property="studentName" column="studentName"></result>
        <result property="studentAge" column="studentAge"></result>
    </collection>

</resultMap>

<select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >
    select *
    from classes where cid=#{id};
</select>

<select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">
    select * from student where classId=#{id}
</select>j

解释:

  1. 主对象映射
    1. MyBatis 使用 resultMap 将查询结果映射到 Classes 对象上。
    2. 主键 cid 和属性 className 直接映射到对应的数据库列。
  2. 分布查询
    1. collection 标签用于映射 Classes 对象中的 students 集合。
    2. 通过 select 属性指定另一个映射语句的 ID,用于执行分布查询。
    3. column 属性指定传递给分布查询的参数列名称,这里是 cid 列。
  3. 子对象映射
    1. 每个 Student 对象的属性 sid, classId, studentName, studentAge 分别映射到对应的数据库列。


 

3)测试代码

/**
 * 通过collection分布查询
 */
@Test
public void queryClassesAndStudentByStep()
{
    Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);
    System.out.println(classes);
    List<Student> students = classes.getStudents();
    for (Student student : students) {
        System.out.println(student);
    }
}

4)测试结果

附录

1.Classes实体类

package org.xiji.enty;

import java.util.ArrayList;
import java.util.List;
import org.xiji. enty.Student;

/**
 * 班级表
 */
public class Classes {
    private int cid;
    private String className;


    List<Student> students;


    public List<Student> getStudents() {
        return students;
    }

    public Classes(int id, String className, List<Student> students) {
        this.cid = id;
        this.className = className;
        this.students = students;
    }

    public Classes() {
        students = new ArrayList<>();
    }

    public Classes(int id, String className) {
        this.cid = id;
        this.className = className;
    }

    public int getId() {
        return cid;
    }

    public void setId(int id) {
        this.cid = id;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }



    public void setStudents(List<Student> students) {
        this.students = students;
    }


    @Override
    public String toString() {
        return "Classes{" +
                "id=" + cid +
                ", className='" + className + '\'' +
                ", students=" + students +
                '}';
    }
}

2.student类

package org.xiji.enty;
import org.xiji.enty.Classes;

/**
 * 学生表
 */
public class Student {
    private int sid;
    private String studentName;
    private int studentAge;
    private int classId;

   private Classes classes;



    public Student(int id, String studentName, int studentAge, int classId, Classes classes) {
        this.sid = id;
        this.studentName = studentName;
        this.studentAge = studentAge;
        this.classId = classId;
        this.classes = classes;
    }

    public Student(int id, String studentName, int studentAge, int classId) {
        this.sid = id;
        this.studentName = studentName;
        this.studentAge = studentAge;
        this.classId = classId;
    }

    public Student() {

    }

    public int getId() {
        return sid;
    }

    public void setId(int id) {
        this.sid = id;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public int getStudentAge() {
        return studentAge;
    }

    public void setStudentAge(int studentAge) {
        this.studentAge = studentAge;
    }

    public int getClassId() {
        return classId;
    }

    public void setClassId(int classId) {
        this.classId = classId;
    }

    public Classes getClasses() {
        return classes;
    }

    public void setClasses(Classes classes) {
        this.classes = classes;
    }

    public void setClasses(int id,String className)
    {
        this.classes = new Classes(id,className);
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + sid +
                ", studentName='" + studentName + '\'' +
                ", studentAge=" + studentAge +
                ", classId=" + classId +
                ", classes=" + classes +
                '}';
    }
}

3.OneToManyMapper

package org.xiji.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.xiji.enty.Classes;
import org.xiji.enty.Student;

import java.util.List;

@Mapper
public interface OneToManyMapper {

    /**
     * association
     */
    Classes queryClassesAndStudentByAssociation(@Param("id") int id);

    /**
     * 分布查询
     */
    Classes queryClassesAndStudentByStep(@Param("id") int id);


    /**
     * 查询id
     */
    List<Student> queryClassesAndStudentByStepTwo(int id);


}

4.OneToManyMapper.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="org.xiji.mapper.OneToManyMapper">

    <!--collection-->
    <resultMap id="collectionResultMap" type="org.xiji.enty.Classes">
        <id property="cid" column="cid"/>
        <result property="className" column="className"/>
        <!--collection-->

        <collection property="students" ofType="org.xiji.enty.Student">
            <id property="sid" column="sid"/>
            <result property="studentName" column="studentName"/>
            <result property="studentAge" column="studentAge"/>
            <result property="classId" column="cid"/>

        </collection>

    </resultMap>
    <select id="queryClassesAndStudentByAssociation" resultMap="collectionResultMap" >

        select * from classes c right join student s on c.cid = s.classId where c.cid=#{id}
    </select>


    <!--通过分布查询-->
    <resultMap id="stepResultMap" type="org.xiji.enty.Classes">
        <id property="cid" column="cid"/>
        <result property="className" column="className"/>
        <collection property="students"
                    select="queryClassesAndStudentByStepTwo"
                    column="cid"
                    ofType="org.xiji.enty.Student"
        >

            <id property="sid" column="sid"></id>
            <result property="classId" column="classId"></result>
            <result property="studentName" column="studentName"></result>
            <result property="studentAge" column="studentAge"></result>
        </collection>

    </resultMap>

    <select id="queryClassesAndStudentByStep" resultMap="stepResultMap" >
        select *
        from classes where cid=#{id};
    </select>

    <select id="queryClassesAndStudentByStepTwo" resultType="org.xiji.enty.Student">
        select * from student where classId=#{id}
    </select>




</mapper>

5.OneToManyMapperTest.xml

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.xiji.enty.Classes;
import org.xiji.enty.Student;
import org.xiji.mapper.ManyToOneMapper;
import org.xiji.mapper.OneToManyMapper;

import java.util.List;

@SpringJUnitConfig(locations = {"classpath:springConfig.xml"})
public class OneTwoManyMapperTest {

    @Autowired
    private OneToManyMapper oneToManyMapper;

    /**
     * 通过collection关联查询
     */
    @Test
    public void queryClassesAndStudentByAssociation()
    {
        Classes classes = oneToManyMapper.queryClassesAndStudentByAssociation(1);
        System.out.println(classes);
        List<Student> students = classes.getStudents();
        for (Student student : students) {
            System.out.println(student.toString());
        }
    }

    /**
     * 通过collection分布查询
     */
    @Test
    public void queryClassesAndStudentByStep()
    {
        Classes classes = oneToManyMapper.queryClassesAndStudentByStep(1);
        System.out.println(classes);
        List<Student> students = classes.getStudents();
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

 6.sql

studentSql

/*
 Navicat Premium Data Transfer

 Source Server         : mybatis
 Source Server Type    : MySQL
 Source Server Version : 80025
 Source Host           : localhost:3306
 Source Schema         : mybatis

 Target Server Type    : MySQL
 Target Server Version : 80025
 File Encoding         : 65001

 Date: 15/09/2024 23:50:47
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `sid` int NOT NULL AUTO_INCREMENT COMMENT '学生id',
  `studentName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生姓名',
  `studentAge` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生年龄',
  `classId` int NULL DEFAULT NULL COMMENT '班级id',
  PRIMARY KEY (`sid`) USING BTREE,
  INDEX `classId`(`classId` ASC) USING BTREE,
  CONSTRAINT `classId` FOREIGN KEY (`classId`) REFERENCES `classes` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张三', '18', 1);
INSERT INTO `student` VALUES (2, '李四', '20', 1);
INSERT INTO `student` VALUES (3, '小久', '21', 1);
INSERT INTO `student` VALUES (4, 'xiji', '22', 1);

SET FOREIGN_KEY_CHECKS = 1;

classesSql

/*
 Navicat Premium Data Transfer

 Source Server         : mybatis
 Source Server Type    : MySQL
 Source Server Version : 80025
 Source Host           : localhost:3306
 Source Schema         : mybatis

 Target Server Type    : MySQL
 Target Server Version : 80025
 File Encoding         : 65001

 Date: 15/09/2024 23:51:16
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for classes
-- ----------------------------
DROP TABLE IF EXISTS `classes`;
CREATE TABLE `classes`  (
  `cid` int NOT NULL AUTO_INCREMENT COMMENT '班级id',
  `className` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级名称',
  PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of classes
-- ----------------------------
INSERT INTO `classes` VALUES (1, '一班');
INSERT INTO `classes` VALUES (2, '二班');
INSERT INTO `classes` VALUES (3, '三班');
INSERT INTO `classes` VALUES (5, '五班');

SET FOREIGN_KEY_CHECKS = 1;

标签:classId,Classes,两种,int,id,classes,MyBatis,一对,public
From: https://blog.csdn.net/2301_76862031/article/details/142290996

相关文章

  • Spring Boot 整合 MyBatis 的详细步骤(两种方式)
    1.SpringBoot配置MyBatis的详细步骤1、首先,我们创建相关测试的数据库,数据表。如下:CREATEDATABASE`springboot_mybatis`USE`springboot_mybatis`CREATETABLE`monster`(`id`intnotnullauto_increment,`age`intnotnull,`birthday`DATEDEFAULTN......
  • mybatis的代理技术
    在MyBatis中,代理对象是通过动态代理技术生成的对象,用于拦截对接口方法的调用并将这些调用转发给相应的SQL映射文件中的SQL语句执行。具体来说,代理对象是一个实现了某个接口的类实例,但这个实例的实际行为是在运行时动态生成的,而不是在编译时固定的。###动态代理在Java中......
  • 2024Mysql And Redis基础与进阶操作系列(6)作者——LJS[含MySQL 多表之一对一/多;多对多;
    MySQL多表操作1多表关系简介1.1一对一关系比如1.2一对多/多对一关系比如:实现规则:1.3多对多关系举例:规则:2.多表联合查询简介多表查询有以下分类知识补充——笛卡尔积(了解即可)交叉连接查询[产生笛卡尔积]内连接查询(使用的关键字innerjoin--inner可以省......
  • mybatis-plus 条件参数说明
     //条件构造器1@TestpublicvoidtestFindWrapper1(){//查询年龄小于25或年龄大于30的人QueryWrapper<Student>queryWrapper=newQueryWrapper<>();queryWrapper.lt("age",25).or().gt("age",30);List<Student>students=studentMapp......
  • mybatis 通过工厂模式将mapper接口的代理对象注入spring容器中
    MapperFactoryBean是MyBatis框架中用于创建Mapper对象的一个工厂类。getObject方法是该工厂类中的一个关键方法,用于返回实际的Mapper对象。具体来说,MapperFactoryBean通过getObject方法来创建和初始化Mapper接口的实现,从而可以在Spring容器中注入和使用这些Mappe......
  • QT 屏幕旋转的两种方式
    https://blog.csdn.net/a3121772305/article/details/90116793?ops_request_misc=%257B%2522request%255Fid%2522%253A%252296666120-3F57-485C-8C6A-F05218C0EC93%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=96666120-3F57-4......
  • MyBatis基础
    MyBatis基础1.什么是mybatisMyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和POJO(PlainOrdinaryJava......
  • 十七,Spring Boot 整合 MyBatis 的详细步骤(两种方式)
    十七,SpringBoot整合MyBatis的详细步骤(两种方式)@目录十七,SpringBoot整合MyBatis的详细步骤(两种方式)1.SpringBoot配置MyBatis的详细步骤2.最后:MyBatis的官方文档:https://mybatis.p2hp.com/关于MyBatis的学习的详细内容,大家可以移步至:✏️✏️✏️MyBatis_Chin......
  • MyBatis动态SQL中的`if`标签使用【后端 19】
    MyBatis动态SQL中的if标签使用引言MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。在MyBatis中,动态SQL是一个非常强大的特性,它允许你根据不同的条件来动态构建SQL语句。if标签是动态SQL中最常用的一个标签,它类似于Java中的if语句,......
  • MyBatis 增删改查【后端 17】
    MyBatis增删改查引言MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(PlainOldJavaObject......