Mybatis基础,利用mybatis实现复杂查询,多对一,一对多

多个学生对应一个老师

对于学生这边而言,关联..多个学生,关联一个老师【多对一】

对于老师而言,集合,一个老师有很多个学生【一对多】

注意:一对多相当与“对象”用(assocation)去处理

   多对一相当于”集合“用(collection)去处理

一,环境搭建

SQL    

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
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
<!--到resources包和java包有重名包时默认合成一个包,特别是引全路径是注意-->

pojo

student

package com.king.pojo;

import lombok.Data;

@Data
public class Student {
    private int id;
    private String name;

    //学生需要关联一个老师
    private Teacher teacher;
}

 teacher

package com.king.pojo;

import lombok.Data;

@Data
public class Teacher {
    private int id;
    private String name;

}

mappper测试

package com.king.dao;


import com.king.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface TeacherMapper {

    @Select("select * from teacher where id = #{tid}")
    public Teacher getTeacher(@Param("tid") int id);
}
    <mappers>
        <mapper resource="com/king/dao/TeacherMapper.xml"/>
    </mappers>
public class MyTest {

    @Test
    public void teacherTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();

    }
}

二,多对一查询方式:

    子查询

    联表查询

练习,题目《查询所有学生信息以及对应老师的信息》

方式一,按照查询嵌套处理(子查询)

<mapper namespace="com.king.dao.StudentMapper">

    <!--
      思路:1.查询所有的学生信息
           2.根据查询出来的学生tid,寻找对应的老师
    -->
    <select id="getStudent" resultMap="StudentTeacher">
        select * from student
    </select>

    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂语句-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id = #{id}
    </select>

</mapper>

 拓展:为什么联表查询的过程是没有顺序的(不是先执行完表一再表二)?

答:数据库是并发执行的

方式二,按照结果进行嵌套处理(联表查询)

    <!--按照结果嵌套处理-->
    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid, s.`name` sname,t.`name` tname
        from student s ,teacher t
        where s.tid=t.id
    </select>

    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
             
        </association>
    </resultMap>

三,一对多查询

3.1环境搭建

  实体类

package com.king.pojo;


import lombok.Data;

import java.util.List;

@Data
//一对多
public class Teacher {
    private int id;
    private String name;

    //一个老师有很多学生
    private List<Student> students;
}
package com.king.pojo;


import lombok.Data;

@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

3.2 mappper.xml实现

方式一:根据结果查询(调试代码,改sql就可,推荐这种)

    <!--按结果嵌套查询-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid,s.name sname,t.id tid,t.name tname
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid}
    </select>
    
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--复杂的属性,我们需要单独处理,
            多对一(对象,association),javaType 指定属性的类型
            一对多(集合,collection),ofType 获取泛型信息
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

 

 测试

    @Test
    public void teachersTest() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }

 

方式二:select子嵌套

    <select id="getTeacher2" resultMap="TeacherStudent2">
        select * from teacher where id = #{tid}
    </select>
    
    <resultMap id="TeacherStudent2" type="teacher">
        <collection property="students" javaType="ArrayList" ofType="student" select="getStudentByTeacherId" column="id"/>
        
    </resultMap>
    
    <select id="getStudentByTeacherId" resultType="student">
        select * from student where tid=#{tid}
    </select>

总结:

  1.关联----association【多对一】

  2.集合----collection 【一对多】

  3.javaType & ofType

    3.1 javaType 用来指定实体类中属性的类型

    3.2 ofType  用来指定映射到List或者集合中的pojo类型,(泛型中约束的类型)

原文地址:https://www.cnblogs.com/CL-King/p/13875190.html