当前位置: 首页 > article >正文

mybatis的多对一、一对多的用法

目录

1、使用VO聚合对象(可以解决这两种情况)

多对一:

一对多:

2、非聚合的多对一做法:

3、非聚合的一对多做法:


1、使用VO聚合对象(可以解决这两种情况)

当我需要多对一、一对多时,可以创建VO聚合对象。

例如:学生类和老师类,会出现多对一、一对多的情况。此时创建一个聚合类,里面包含所需要的学生类和老师类的属性。并先查询出前面的内容,再根据前面的内容查询出后面的内容。

多对一:

数据库设计,学生表中有一个tid来匹配老师id:

 

在学生类和老师类后,再创建出一个聚合类:

@Data
public class Student {
    private Integer id;
    private String username;
    private Integer tid;
}
@Data
public class Teacher {
    private Integer id;
    private String username;
}
@Data
public class StudentAndTeacher {
    private Integer id;
    private String username;
    private Teacher teacher;
}

写出查询所有学生和根据学生类里的tid查询老师: 

@Mapper
public interface AllMapper {
    List<Student> AllStudent();
    Teacher AllTeacherByTid(Integer tid);
}
    <select id="AllStudent" resultType="com.example.demo.entity.Student">
        select * from student;
    </select>

    <select id="AllTeacherByTid" resultType="com.example.demo.entity.Teacher">
        select * from teacher where id=#{tid};
    </select>

通过聚合类,把这两个查询到的内容聚合到一起:

    @Test
    public void AllStudent() {
        List<Student> students = allMapper.AllStudent();
        for (Student student : students) {
            StudentAndTeacher studentAndTeacher = new StudentAndTeacher();
            studentAndTeacher.setId(student.getId());
            studentAndTeacher.setUsername(student.getUsername());
            studentAndTeacher.setTeacher(allMapper.AllTeacherByTid(student.getTid()));
            System.out.println(studentAndTeacher);
        }
    }

结果如下:

一对多:

学生类和老师类一样,但是聚合类不一样,因为现在的主体是老师,而不是学生。

@Data
public class Student {
    private Integer id;
    private String username;
    private Integer tid;
}
@Data
public class Teacher {
    private Integer id;
    private String username;
}
@Data
public class TeacherAndStudent {
    private Integer id;
    private String username;
    private List<Student> studentList;
}

写出查询所有老师和根据老师的id去学生表里查对应tid的学生: 

@Mapper
public interface AllMapper {
    List<Teacher> AllTeacher();
    List<Student> AllStudentById(Integer id);
}
    <select id="AllTeacher" resultType="com.example.demo.entity.Teacher">
        select * from teacher;
    </select>

    <select id="AllStudentById" resultType="com.example.demo.entity.Student">
        select * from student where tid=#{id};
    </select>

通过聚合类,把这两个查询到的内容聚合到一起:

    @Test
    public void AllTeacher() {
        List<Teacher> Teachers = allMapper.AllTeacher();
        for (Teacher teacher : Teachers) {
            List<Student> students = allMapper.AllStudentById(teacher.getId());
            TeacherAndStudent studentAndTeacher = new TeacherAndStudent();
            studentAndTeacher.setId(teacher.getId());
            studentAndTeacher.setUsername(teacher.getUsername());
            studentAndTeacher.setStudentList(students);
            System.out.println(studentAndTeacher);
        }
    }

结果如下:

2、非聚合的多对一做法:

知识点:association标签是用在多对一时,当一个类中有其他类作为该类的属性时,要用到这个标签。

此时的Student类中有一个属性是Teacher类:

@Data
public class Student {
    private Integer id;
    private String username;
    private Teacher teacher;
}
@Data
public class Teacher {
    private Integer id;
    private String username;
}
@Mapper
public interface AllMapper {
    List<Student> AllStudent();
}

这里用resultMap来匹配。 

要注意两点:

1、result 标签里的property对应的是java类的属性名,column对应的是select 标签里查询出来的字段名。并且要注意,若多个表的字段名相同,必须要用别名区分,并在column中写上别名而非字段名。

2、association 标签中,property对应的是Student类中的teacher属性,类型为Student类,这里的类型用javaType而不是Type。

    <select id="AllStudent" resultMap="StudentAndTeacher">
        select s.id sid, s.username susername, t.id tid, t.username tusername
        from student s, teacher t
        where s.tid = t.id;
    </select>
    <resultMap id="StudentAndTeacher" type="com.example.demo.entity.Student">
        <result property="id" column="sid"></result>
        <result property="username" column="susername"></result>
        <association property="teacher" javaType="com.example.demo.entity.Teacher">
            <result property="id" column="tid"></result>
            <result property="username" column="tusername"></result>
        </association>
    </resultMap>
 @Test
    public void StudentAndTeacher() {
        List<Student> students = allMapper.AllStudent();
        for (Student student : students) {
            System.out.println(student);
        }
    }

结果如下:

3、非聚合的一对多做法:

知识点:collection标签是用在一对多时,当一个类中有其他类集合作为该类的属性时,要用到这个标签。

此时的Teacher类中有一个属性是List<Student>:

@Data
public class Student {
    private Integer id;
    private String username;
    private Integer tid;
}
@Data
public class Teacher {
    private Integer id;
    private String username;
    private List<Student> students;
}
@Mapper
public interface AllMapper {
    List<Teacher> AllTeacher();
}

这里用resultMap来匹配。 

要注意两点:

1、result 标签里的property对应的是java类的属性名,column对应的是select 标签里查询出来的字段名。并且要注意,若多个表的字段名相同,必须要用别名区分,并在column中写上别名而非字段名。

2、collection标签中,property对应的是Teacher类中的students属性,类型为List,这里的类型用javaType而不是Type,ofType指的是List的泛型。

    <select id="AllTeacher" resultMap="TeacherAndStudent">
        select s.id sid, s.username susername, s.tid stid, t.id tid, t.username tusername
        from student s, teacher t
        where s.tid = t.id;
    </select>
    <resultMap id="TeacherAndStudent" type="com.example.demo.entity.Teacher">
        <result property="id" column="tid"></result>
        <result property="username" column="tusername"></result>
        <collection property="students" javaType="List"        
         ofType="com.example.demo.entity.Student">
            <result property="id" column="sid"></result>
            <result property="username" column="susername"></result>
            <result property="tid" column="stid"></result>
        </collection>
    </resultMap>
    @Test
    public void StudentAndTeacher() {
        List<Teacher> teachers = allMapper.AllTeacher();
        for (Teacher teacher : teachers) {
            System.out.println(teacher);
        }
    }

此时结果:


http://www.kler.cn/a/507012.html

相关文章:

  • Java设计模式——单例模式(特性、各种实现、懒汉式、饿汉式、内部类实现、枚举方式、双重校验+锁)
  • 生成订单号工具类
  • 读取长文本,使用读取底表
  • excel仅复制可见单元格,仅复制筛选后内容
  • h5使用video播放时关掉vant弹窗视频声音还在后台播放
  • 【15】Word:互联网发展状况❗
  • Git在码云上的使用指南:从安装到推送远程仓库
  • 每日进步一点点(网安)
  • Spring Boot 统一返回数据格式
  • 【2025最新版】PCL点云处理算法汇总(C++长期更新版)
  • 从零深度学习:(2)最小二乘法
  • 网安——CSS
  • [Linux]——进程(2)
  • “AI智能服务平台系统,让生活更便捷、更智能
  • list的模拟实现详解
  • 核心前端技术详解
  • Jupyter notebook中运行dos指令运行方法
  • Java进阶-在Ubuntu上部署SpringBoot应用
  • 微软开源AI Agent AutoGen 详解
  • Docker部署Spring Boot + Vue项目
  • ParcelFileDescriptor+PdfRenderer在Android渲染显示PDF文件
  • Spring Boot中使用AOP实现权限管理
  • Python 的时间处理模块 datetime 详解
  • 图论1-问题 B: 算法7-4,7-5:图的遍历——深度优先搜索
  • 博图 linucx vmware
  • css 实现自定义虚线