Mybatis(五):多对一处理,一对多处理

9.多对一处理

多个对象对应一个对象

比如:多个学生对应一个老师

掌握两个单词:

  • association — 联系 ,关联 多个人可以关联一个人。
  • collection — 集合 一个人有一个集合,包含多个人。
  • 发现是多对一业务情况,我们需要使用association 标签进行关联

准备工作:在数据库中创建要测试的数据表

先建立一个mybatis的数据库,在数据库中建立两个关联的表

CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`,`name`) VALUES (1,'秦老师');

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

结果显示如下表:
通过tid进行关联连接
在这里插入图片描述

多对一的处理方式一:

使用数据库的思想处理:联表查询

1. 创建实体类

在idea中根据数据表和测试所需环境(多对一)创建对应的实体类

Student类

package com.westos.pojo;

public class Student {

    private int id;
    private String name;

    private Teacher teacher;

    public Student() {
    }

    public Student(int id, String name, Teacher teacher) {
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

Teacher类

package com.westos.pojo;

public class Teacher {

    private int id;
    private String name;

    public Teacher() {
    }

    public Teacher(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

2. 定义dao接口

package com.westos.dao;

import com.westos.pojo.Student;

import java.util.List;

public interface StudentDao {

    //获得全部学生的信息以及对应的老师
    List<Student> getStudents();
}

2. 对应接口配置文件StudentMapper.xml

编写查询语句

  1. 查询学生信息 id name tid , 由于我们要得到老师的信息,我们需要联表查询
  2. 查询老师的信息 id name 。

遇到的问题:学生类中关联老师,多个学生对应一个老师,学生类属性中有一个特殊属性teacher,他对应的是一个表,而不是一条记录。无法直接查询。

关键字:

  • association :关联,多对一
  • column:数据库对应的列名
  • property:对应属性名
  • javaType:多对一字段对应的java类型
  • select;关联一个语句
<?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对应Mapper接口的类-->
<mapper namespace="com.westos.dao.StudentDao">

 <!--遇到问题:学生类中关联老师:多个学生对应一个老师-->
 <!--<select id="getStudents" resultType="Student">-->
     <!--select  s.id,s.name,t.name* from mybatis.student as s,mybatis.teacher as t-->
     <!--where s.tid = t.id-->
 <!--</select>-->

 <!--解决问题方式一:按查询结果嵌套处理,模拟数据库思想;-->
 <select id="getStudents" resultMap="StudentTeacher">
     select * from mybatis.student;
 </select>
 <!--关联上面的-->
 <resultMap id="StudentTeacher" type="Student">
     <id column="id" property="id"/>
     <result column="name" property="name"/>

     <!--属性和字段对应,    类和表对应,  对象和记录对应
     关联一个字段
     需求:拿到老师这个类的属性

     association :关联,多对一
     column:数据库对应的列名
     property:对应属性名
     javaType:多对一字段对应的java类型
     select;关联一个语句
     -->
     <association  column="tid" property="teacher" javaType="Teacher" select="getTeacher"/>
 </resultMap>
 <!--关联上面的文件-->
 <select id="getTeacher" resultType="Teacher">
     select * from mybatis.teacher where id = #{id}
 </select>
</mapper>

3. 测试类

   package com.westos.dao;

import com.westos.pojo.Student;
import com.westos.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

import java.util.List;

public class test {

 @Test
 public void getStudents(){

     SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
     SqlSession sqlSession = sqlSessionFactory.openSession();

     StudentDao mapper = sqlSession.getMapper(StudentDao.class);
     List<Student> students = mapper.getStudents();

     for (Student student : students) {
         System.out.println("学生姓名:"+student.getName()+"\t老师姓名:"+student.getTeacher().getName());
     }
     sqlSession.close();//关闭连接
 }

}

4. 测试结果

在这里插入图片描述


多对一的处理方式二:

1. 编写接口

package com.westos.dao;

import com.westos.pojo.Student;

import java.util.List;

public interface StudentDao {

  //获得全部学生的信息以及对应的老师
  List<Student> getStudents();
  //获得全部学生的信息以及对应的老师
  List<Student> getStudentsTwo();
}

2. 编写处理的StudentMapper.xml

  1. 查询学生id,学生姓名,老师姓名,需要从学生表和老师表中查询

  2. 学生对应的类进行映射,发现老师一个对象 , 所以关联一个对象;

   <?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对应Mapper接口的类-->
<mapper namespace="com.westos.dao.StudentDao">

   <!--遇到问题:学生类中关联老师:多个学生对应一个老师-->
   <!--<select id="getStudents" resultType="Student">-->
       <!--select  s.id,s.name,t.name* from mybatis.student as s,mybatis.teacher as t-->
       <!--where s.tid = t.id-->
   <!--</select>-->

   <!--解决问题方式一:按查询结果嵌套处理,模拟数据库思想;-->
   <select id="getStudents" resultMap="StudentTeacher">
       select * from mybatis.student;
   </select>
   <!--关联上面的-->
   <resultMap id="StudentTeacher" type="Student">
       <id column="id" property="id"/>
       <result column="name" property="name"/>

       <!--属性和字段对应,    类和表对应,  对象和记录对应
       关联一个字段
       需求:拿到老师这个类的属性

       association :关联,多对一
       column:数据库对应的列名
       property:对应属性名
       javaType:多对一字段对应的java类型
       select;关联一个语句
       -->
       <association  column="tid" property="teacher" javaType="Teacher" select="getTeacher"/>
   </resultMap>
   <!--关联上面的文件-->
   <select id="getTeacher" resultType="Teacher">
       select * from mybatis.teacher where id = #{id}
   </select>




   <!--解决方式二:一个resultMap解决 :模拟面型对象思想-->
   <select id="getStudentsTwo" resultMap="StudentTeacherTwo">
      select s.id,s.name,t.name as tname from mybatis.student as s, mybatis.teacher as t
       where s.tid = t.id
   </select>
   <!--设置结果集映射ResultMap-->
   <resultMap id="StudentTeacherTwo" type="Student">
       <id property="id" column="id"/>
       <result property="name" column="name"/>
      <!--直接关联一个老师-->
       <association property="teacher" javaType="Teacher">
           <result property="name" column="tname"/>
       </association>
   </resultMap>
</mapper>

3. 测试类

package com.westos.dao;

import com.westos.pojo.Student;
import com.westos.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

import java.util.List;

public class test {

 @Test
 //解决方式一
 public void getStudents(){

     SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
     SqlSession sqlSession = sqlSessionFactory.openSession();

     StudentDao mapper = sqlSession.getMapper(StudentDao.class);
     List<Student> students = mapper.getStudents();

     for (Student student : students) {
         System.out.println("学生姓名:"+student.getName()+"\t老师姓名:"+student.getTeacher().getName());
     }
     sqlSession.close();//关闭连接
 }


 @Test
 //解决方式二
 public void  getStudentsTwo(){

     SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
     SqlSession sqlSession = sqlSessionFactory.openSession();

     StudentDao mapper = sqlSession.getMapper(StudentDao.class);
     List<Student> studentsTwo = mapper.getStudentsTwo();

     for (Student student : studentsTwo) {
         System.out.println("学生姓名:"+student.getName()+"\t老师姓名:"+student.getTeacher().getName());
     }
     sqlSession.close();//关闭连接
 }

}

4. 测试结果

在这里插入图片描述

总结

  1. mybatis中遇到多对一的情况,要使用关联映射处理:使用association
  2. 两种处理思路:
    1. 数据库思想 : 联表查询
    2. OOP思想 :关联对象

10 . 一对多处理

一个老师对应多个学生

一对多的业务:使用collection处理

环境搭建

在idea中跟据数据表和测试所需要的环境(一对多)

一个老师对应多个学生

实体类

Student类

package com.westos.pojo;

public class Student {

    private  int id;
    private String name;
    //多个学生对一个老师
    private Teacher teacher;

    public Student() {
    }

    public Student(int id, String name, Teacher teacher) {
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

}
package com.westos.pojo;

import java.util.List;

public class Teacher {

    private int id;
    private String name;
    //一个老师对应多个学生
    private List<Student> students;

    public Teacher() {
    }

    public Teacher(int id, String name, List<Student> students) {
        this.id = id;
        this.name = name;
        this.students = students;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

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

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", students=" + students +
                '}';
    }
}

编写dao接口
package com.westos.dao;

import com.westos.pojo.Teacher;

public interface TeacherDao {
    //获得一个老师下的所有学生信息;老师是包含学生的集合

    Teacher getTeacher(int id);

    Teacher getTeacherTwo(int id);
}

对应mapper文件
<?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对应Mapper接口的类,不能写别名-->
<mapper namespace="com.westos.dao.TeacherDao">
    <!--一对多的处理-->
    <!--面向对象方式解决-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select s.id as sid,s.name as sname,t.id as tid,t.name as tname
        from mybatis.student as s,mybatis.teacher as t
        where s.tid = t.id  and t.id = #{id}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="name" column="tname"/>

        <!--对多:collection-->
        <collection property="students" ofType="Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
        </collection>
    </resultMap>


    <!--数据库思想-->
    <!--数据库思想-->
    <select id="getTeacherTwo" resultMap="TeacherStudent2">
        select * from mybatis.teacher where id = #{id}
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="T2"/>
    </resultMap>
    <select id="T2" resultType="Student">
        select * from mybatis.student where tid = #{id}
    </select>
</mapper>
测试类
package com.westos.dao;

import com.westos.pojo.Teacher;
import com.westos.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

public class test {

    @Test
    public void getTeacher(){
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        TeacherDao mapper = sqlSession.getMapper(TeacherDao.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher.getName());
        System.out.println(teacher.getStudents());

    }


    @Test
    public void getTeacherTwo(){
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        TeacherDao mapper = sqlSession.getMapper(TeacherDao.class);
        Teacher teacher = mapper.getTeacherTwo(1);
        System.out.println(teacher.getName());
        System.out.println(teacher.getStudents());

    }
}

测试结果:

  1. getTeacher

在这里插入图片描述
2. getTeacherTwo
在这里插入图片描述

总结

多对一:association 关联

一对多:collection 集合

两种解决方式:

  • 面对对象的思想:关联对象
  • SQL语句思想:联表查询
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值