MyBatis学习总结(5)--- 多对一、一对多的问题

MyBatis学习总结(5)— 多对一、一对多的问题

1. 多对一

多个对象对应一个对象

比如:你们都是我的学生 ,多个学生对应一个老师

掌握两个单词:

  • association — 联系 ,关联 多个人可以关联一个人。

  • collection — 集合 一个人有一个集合,包含多个人。

  • 发现是多对一业务情况,我们需要使用association 标签进行关联

要求:

根据给出的数据库,数据库有两个表student和teacher,student中多个学生对应teacher中的同一个老师。要求查询出表中的所有学生,并查出每个学生对应的同一个老师。

数据库信息如下:
Student表格:在这里插入图片描述
Teacher表格:
在这里插入图片描述

1.1. 多对一的处理方式一

思想:数据库连表查询

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

  • 1.定义dao接口

    List<Student> getStudents();
    
  • 2.Student实体类

    //student实体类的变量
    private int id;
    private String name;
    Teacher teacher;   //对应数据库的tid,对应teacher表的id
    
  • 3.编写查询语句

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

    2. 查询老师的信息 id name 。

    StudentMapper.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对应Mapper接口的类-->
    <mapper namespace="org.xiao.dao.StudentMapper">
    
        <!--&lt;!&ndash;解决问题方式一:按查询结果嵌套处理,模拟数据库思想;&ndash;&gt;-->
        <select id="getStudents"  resultMap="ST">
            select * from mybatis.student
        </select>
    
        <!--column="数据库的列名" property="类变量名"-->
        <resultMap id="ST" type="Student">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <!--属性和字段对应  , 类和表对应  , 对象和记录
        关联一个字段
        需求:拿到老师这个类的属性
    
        association : 关联,多对一
            column : 数据库对应的列名
            property : 对应属性名
            javaType : 多对一字段对应的Java类型
            select : 关联一个语句
        -->
            <!--连接Teacher表-->
            <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 org.xiao.dao;
    
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import org.xiao.pojo.Student;
    import org.xiao.utils.MyBatisUtils;
    
    import java.util.List;
    
    public class StudentDaoTest {
        @Test
        public void getStudents(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.getStudents();
            for (Student student : students) {
                System.out.println(student.getName()+"----"+student.getTeacher().getName());
            }
        }
    }
    
  • 项目结构

    说明:代码的其他部分参考前几篇博客,pom.xml、log4j、database,utils等的配置。
    在这里插入图片描述

  • 结果
    在这里插入图片描述

1.2 多对一的处理方式二

思想:面向对象

一个resultMap解决 , 模拟面向对象的思想

  • 1.编写接口

    List<Student> getStudentsTwo();
    
  • 2.编写处理的mapper映射文件,StudentMapper.xml

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

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

     <select id="getStudentsTwo" resultMap="ST2">
            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="ST2" type="Student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
    
            <!--直接关联一个老师-->
            <association property="teacher" javaType="Teacher">
                <result property="name" column="tname"/>
            </association>
        </resultMap>
    
  • 3.测试类

    package org.xiao.dao;
    
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import org.xiao.pojo.Student;
    import org.xiao.utils.MyBatisUtils;
    
    import java.util.List;
    
    public class StudentDaoTestTwo {
        @Test
        public void getStudentsTwo(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            Object mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = ((StudentMapper) mapper).getStudentsTwo();
    
            for (Student student : students) {
                System.out.println(student.getName()+"----"+student.getTeacher().getName());
            }
    
        }
    }
    
  • 结果:
    在这里插入图片描述

1.3 总结

  1. mybatis中遇到多对一的情况,要使用关联映射处理:使用association

       association : 关联,多对一
            column : 数据库对应的列名
            property : 对应属性名
            javaType : 多对一字段对应的Java类型
            select : 关联一个语句
    
  2. 两种处理思路:

    1. 数据库思想 : 联表查询
    2. OOP思想 :关联对象

2. 一对多

一个老师对应多个学生,根据老师的id查询老师,以及这位老师对应的所有学生。

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

  • 环境搭建

    Teacher实体类

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

2.1 一对多处理方式一

思想:数据库连表查询
  • 1.定义dao接口

    Teacher getTeacher(int id);
    
  • 2.查询语句

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

    2. 查询学生的信息 tid id name 。

    <?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="org.xiao.dao.TeacherMapper">
    
        <!-- 数据库思想 -->
        
        <!--  根据id 先查询老师 -->
        <select id="getTeacher" resultMap="TS">
            select * from mybatis.teacher where id = ${id}
        </select>
        
    	<!--连接student表-->
        <resultMap id="TS" type="Teacher">
            <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
        </resultMap>
    
        <!--查询学生信息-->
        <select id="getStudent" resultType="Student">
            select * from mybatis.student where tid = #{id}
        </select>
    </mapper>
    
  • 3.测试类

    public class TeacherDaoTest {
        @Test
        public void getTeacher(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = mapper.getTeacher(1);
    
            System.out.println(teacher.getName());
            System.out.println(teacher.getStudents());
        }
    }
    
  • 结果: 在这里插入图片描述

2.2 一对多处理方式二

思想:面向对象
  • 1.编写接口

    Teacher getTeacherTwo(int id);
    
  • 2.编写处理的mapper映射文件,TeacherMapper.xml

    1. 查询老师姓名,老师id,学生姓名,学生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="org.xiao.dao.TeacherMapper">
    
        <!-- 面向对象思想-->
        <!--查询老师信息、学生信息-->
        <select id="getTeacherTwo" resultMap="TS2">
            select s.id sid,s.name sname,t.name tname,t.id tid
             from mybatis.teacher t ,mybatis.student s
             where s.tid = t.id = #{id}
        </select>
    
        <!--老师类关联学生类-->
        <resultMap id="TS2" type="Teacher">
            <result property="name" column="tname"/>
            <collection property="students" ofType="Student">
                <id property="id" column="sid"/>
                <result property="name" column="sname"/>
                <result property="tid" column="tid"/>
            </collection>
        </resultMap>
    </mapper>
    
  • 3.测试类

    @Test
        public void getTeacherTwo(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher2 = mapper.getTeacherTwo(1);
            System.out.println(teacher2.getName());
            System.out.println(teacher2.getStudents());
        }
    
    
  • 结果:
    在这里插入图片描述

3. 总结

  • 关联映射处理

    多对一:association 关联

    一对多:collection 集合

  • 两种解决方式:

    面对对象的思想:关联对象

    SQL语句思想:联表查询

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值