1.多对一
- 对于学生这边而言, 关联 … 多个学生,关联一个老师 【多对一】
- 对于老师而言, 集合 , 一个老师,有很多学生 【一对多】
- 在sql中创建老师和学生表
Teacher表
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');
- 导入依赖
<!-- 导入依赖 -->
<dependencies>
<!-- 单元测试的包 Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- 操作数据库 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- lombok -->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
- 新建实体类 Teacher,Student
老师类
package com.yang.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
学生类
package com.jiang.pojo;
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
//学生表中对应的这个老师是对象不是字段
private Teacher teacher;
}
- 建立对应的老师和学生Mapper接口
public interface StudentMapper {
List<Student> getStudents();
}
public interface TeacherMapper {
}
- 建立对应的Mapper.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="com.yang.mapper.StudentMapper">
<!--
获取所有的学生及学生对应的老师信息
1.获取所有的学生信息
2.获取所有学生的tid,然后再去老师表中查询这个id对应的老师
-->
<resultMap id="StudentTeacher" type="Student">
<!--colum 查询出来对应数据库字段-->
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!-- tid是一个字段,teacher是一个对象-->
<!--关联 ,这个对象是什么类型-->
<association property="teacher" javaType="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
<!--这个其实就是mysql的联表查询,
查询的sql结果可能来自多个对象,将这多个对象关联,
对象关联只考虑一个问题:
这个查询出来的字段,到底是哪个对象中的哪个属性-->
<select id="getStudents" resultMap="StudentTeacher">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid=t.id <!--这一句是把这两个表关联起来-->
</select>
</mapper>
按照查询嵌套
<!--
思路:
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 集合: collection -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id}
</select>
- 在核心配置文件中绑定注册我们的Mapper接口或者文件!
<mappers>
<mapper resource="com/yang/mapper/StudentMapper.xml"/>
</mappers>
- 测试查询是否能够成功!
@Test
public void testGetStudent(){
SqlSession session = MyBatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
System.out.println(mapper.getStudents());
}
2.一对多
一个老师对应多个学生,现在学生是个体,是一个集合和之前一样,首先搭建环境
1.建表导入依赖
2.老师类和学生类
学生类
@Data
public class Student {
private int id;
private String name;
private int tid;
}
老师类
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生 现在学生是个体
//一对多的时候,多的一方是个体,以一为中心
//多对一的时候,一的一方是个体,以多为中心
private List<Student> students;
}
3.实体类对应的接口
public interface TeacherMapper {
//获取这个老师下的所有学生
public Teacher getTeacher(int id);
}
4.接口对应的xml文件
按照结果集映射查询
<!--按结果集映射查询-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname,t.id tid
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 集合: collection
javaType="" 指定属性的类型!
集合中的泛型信息,我们使用ofType获取
-->
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<!--学生的tid就是老师的id-->
<result property="tid" column="tid"/>
</collection>
</resultMap>
按照查询嵌套处理
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.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 mybatis.student where tid = #{tid}
</select>
5.在核心配置文件中绑定注册我们的Mapper接口或者文件!
<mappers>
<mapper resource="com/yang/mapper/TeacherMapper.xml"/>
</mappers>
6.测试查询
@Test
public void testGetTeacher(){
SqlSession session = MyBatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
}
总结:
- 关联 - association 【多对一】
- 集合 - collection 【一对多】
- javaType & ofType
- JavaType 用来指定实体类中属性的类型
- ofType 用来指定映射到List或者集合中的 pojo类型,泛型中的约束类型!
注意的点:
- 保证SQL的可读性,尽量保证通俗易懂
- 注意一对多和多对一中,属性名和字段的问题!
- 如果问题不好排查错误,可以使用日志 , 建议使用 Log4j