多对一处理
多对一:
- 多个学生对应一个老师
- 站在学生这边,对于学生而言,**关联:**多个学生关联一个老师[多对一]
- 站在老师这边,对于老师而言, **集合:**一个老师有很多个学生[一对多]
表关系:
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');
测试环境搭建:
- 导入lombok
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
- 新建实体类Teacher,Student
package com.hang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
//学生需要关联一个老师 这里不定义tid了
private Teacher teacher;
}
package com.hang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
private int id;
private String name;
}
- 建立Mapper接口
public interface StudentMapper {
/**
* 查询所有的学生信息,以及对应的老师的信息!
* @return
*/
public List<Student> getStudent();
/**
*
* @return
*/
public List<Student> getStudent2();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hang.dao.StudentMapper">
<!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的id的tid,寻找对应的老师
捋思路:先查了学生 再查了老师 由于学生里面的结果存在老师这样一个特殊对象 不是普通的字段 所以单独处理 由于是对象所以使用association去做
javaType="Teacher" 由于是一个对象所以要设置类型 select="getTeacher" 对象查出来的通过这个tid要干嘛
-->
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<!--两个关联起来,本质还是Student类型 重点是把teacher=null的属性解决 本质还是解决属性名字段名不一致的问题-->
<resultMap id="StudentTeacher" type="Student">
<result column="id" property="id"/>
<result column="name" property="name"/>
<!--还有一个属性是teacher 无法写 只能针对单个属性 -->
<!--复杂的属性我们需要单独处理
如果是一个对象使用association
如果是一个集合使用collection
teacher是一个对象 我们需要去获取一个对象 首先我们给property这个属性赋值一个类型了 因为它是一个复杂类型 所以需要给column一个类型 javaType
这是个对象 数据库是个列 想办法让这个tid查出来等于teacher 于是再加一个嵌套查询
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{tid}
</select>
<!--================按照结果嵌套处理======================-->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student as s ,teacher as 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>
</mapper>
public interface TeacherMapper {
/**
* 根据id查询老师
* @param id
* @return
*/
@Select("select * from teacher where id = #{tid}")
Teacher getTeacher(@Param("tid") int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hang.dao.TeacherMapper">
</mapper>
- 在核心配置文件中绑定注册Mapper接口或者文件~ 方式很多种,随意选
<!--绑定接口-->
<mappers>
<mapper class="com.hang.dao.TeacherMapper"/>
<mapper class="com.hang.dao.StudentMapper"/>
</mappers>
- 测试查询是否能否成功~
import com.hang.dao.StudentMapper;
import com.hang.dao.TeacherMapper;
import com.hang.pojo.Student;
import com.hang.pojo.Teacher;
import com.hang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
public static void main(String[] args) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
sqlSession.close();
}
@Test
public void getStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent();
for (Student student : studentList) {
System.out.println(student);//查出来老师为null
}
sqlSession.close();
}
@Test
public void getStudent2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> student2 = mapper.getStudent2();
for (Student student : student2) {
System.out.println(student);
}
}
}
按照查询嵌套处理
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hang.dao.StudentMapper">
<!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的id的tid,寻找对应的老师
捋思路:先查了学生 再查了老师 由于学生里面的结果存在老师这样一个特殊对象 不是普通的字段 所以单独处理 由于是对象所以使用association去做
javaType="Teacher" 由于是一个对象所以要设置类型 select="getTeacher" 对象查出来的通过这个tid要干嘛
-->
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<!--两个关联起来,本质还是Student类型 重点是把teacher=null的属性解决 本质还是解决属性名字段名不一致的问题-->
<resultMap id="StudentTeacher" type="Student">
<result column="id" property="id"/>
<result column="name" property="name"/>
<!--还有一个属性是teacher 无法写 只能针对单个属性 -->
<!--复杂的属性我们需要单独处理
如果是一个对象使用association
如果是一个集合使用collection
teacher是一个对象 我们需要去获取一个对象 首先我们给property这个属性赋值一个类型了 因为它是一个复杂类型 所以需要给column一个类型 javaType
这是个对象 数据库是个列 想办法让这个tid查出来等于teacher 于是再加一个嵌套查询
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{tid}
</select>
</mapper>
按照结果嵌套处理
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hang.dao.StudentMapper">
<!--================按照结果嵌套处理======================-->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student as s ,teacher as 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>
</mapper>
回顾Mysql多对一查询方式:
- 子查询
#子查询
select id,name,tid from student where tid=(select teacher.id from teacher );
- 联表查询
select s.id as sid,s.name as sname,t.name as tname,t.id as tid
from student as s,teacher as t
where s.tid = t.id;