8、多對一的處理
多對一的理解:
-
多個學生對應一個老師
-
如果對于學生這邊,就是一個多對一的現象,即從學生這邊關聯一個老師!
資料庫設計
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');
搭建測驗環境
1、IDEA安裝Lombok插件
2、引入Maven依賴
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
3、在代碼中增加注解
@Data //GET,SET,ToString,有參,無參構造
public class Teacher {
private int id;
private String name;
}
@Data
public class Student {
private int id;
private String name;
//多個學生可以是同一個老師,即多對一
private Teacher teacher;
}
4、撰寫物體類對應的Mapper介面 【兩個】
-
無論有沒有需求,都應該寫上,以備后來之需!
public interface StudentMapper {
}
public interface TeacherMapper {
}
5、撰寫Mapper介面對應的 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.kuang.mapper.StudentMapper">
?
</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="com.kuang.mapper.TeacherMapper">
?
</mapper>
按查詢嵌套處理
1、給StudentMapper介面增加方法
//獲取所有學生及對應老師的資訊
public List<Student> getStudents();
2、撰寫對應的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="com.kuang.mapper.StudentMapper">
?
<!--
需求:獲取所有學生及對應老師的資訊
思路:
1. 獲取所有學生的資訊
2. 根據獲取的學生資訊的老師ID->獲取該老師的資訊
3. 思考問題,這樣學生的結果集中應該包含老師,該如何處理呢,資料庫中我們一般使用關聯查詢?
1. 做一個結果集映射:StudentTeacher
2. StudentTeacher結果集的型別為 Student
3. 學生中老師的屬性為teacher,對應資料庫中為tid,
多個 [1,...)學生關聯一個老師=> 一對一,一對多
4. 查看官網找到:association – 一個復雜型別的關聯;使用它來處理關聯查詢
-->
<select id="getStudents" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<!--association關聯屬性 property屬性名 javaType屬性型別 column在多的一方的表中的列名-->
<association property="teacher" column="tid" javaType="Teacher"select="getTeacher"/>
</resultMap>
<!--
這里傳遞過來的id,只有一個屬性的時候,下面可以寫任何值
association中column多引數配置:
column="{key=value,key=value}"
其實就是鍵值對的形式,key是傳給下個sql的取值名稱,value是片段一中sql查詢的欄位名,
-->
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id}
</select>
?
</mapper>
3、撰寫完畢去Mybatis組態檔中,注冊Mapper!
4、注意點說明:
<resultMap id="StudentTeacher" type="Student">
<!--association關聯屬性 property屬性名 javaType屬性型別 column在多的一方的表中的列名-->
<association property="teacher" column="{id=tid,name=tid}"javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
這里傳遞過來的id,只有一個屬性的時候,下面可以寫任何值
association中column多引數配置:
column="{key=value,key=value}"
其實就是鍵值對的形式,key是傳給下個sql的取值名稱,value是片段一中sql查詢的欄位名,
-->
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id} and name = #{name}
</select>
5、測驗
@Test
public void testGetStudents(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
?
List<Student> students = mapper.getStudents();
?
for (Student student : students){
System.out.println(
"學生名:"+ student.getName()
+"\t老師:"+student.getTeacher().getName());
}
}
按結果嵌套處理
除了上面這種方式,還可以按照結果進行嵌套處理;
1、介面方法撰寫
public List<Student> getStudents2();
2、撰寫對應的mapper檔案
<!--
按查詢結果嵌套處理
思路:
1. 直接查詢出結果,進行結果集的映射
-->
<select id="getStudents2" 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">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--關聯物件property 關聯物件在Student物體類中的屬性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
3、去mybatis-config檔案中注入【此處應該處理過了】
4、測驗
@Test
public void testGetStudents2(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
?
List<Student> students = mapper.getStudents2();
?
for (Student student : students){
System.out.println(
"學生名:"+ student.getName()
+"\t老師:"+student.getTeacher().getName());
}
}
小結
按照查詢進行嵌套處理就像SQL中的子查詢
按照結果進行嵌套處理就像SQL中的聯表查詢
9、一對多的處理
一對多的理解:
-
一個老師擁有多個學生
-
如果對于老師這邊,就是一個一對多的現象,即從一個老師下面擁有一群學生(集合)!
物體類撰寫
@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;
}
搭建測驗的環境(跟上面一樣)
按結果嵌套處理
1、TeacherMapper介面撰寫方法
//獲取指定老師,及老師下的所有學生
public Teacher getTeacher(int id);
2、撰寫介面對應的Mapper組態檔
<mapper namespace="com.kuang.mapper.TeacherMapper">
?
<!--
思路:
1. 從學生表和老師表中查出學生id,學生姓名,老師姓名
2. 對查詢出來的操作做結果集映射
1. 集合的話,使用collection!
JavaType和ofType都是用來指定物件型別的
JavaType是用來指定pojo中屬性的型別
ofType指定的是映射到list集合屬性中pojo的型別,
-->
<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=#{id}
</select>
?
<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
</mapper>
3、將Mapper檔案注冊到MyBatis-config檔案中
<mappers>
<mapper resource="mapper/TeacherMapper.xml"/>
</mappers>
4、測驗
@Test
public void testGetTeacher(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
按查詢嵌套處理
1、TeacherMapper介面撰寫方法
public Teacher getTeacher2(int id);
2、撰寫介面對應的Mapper組態檔
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--column是一對多的外鍵 , 寫的是一的主鍵的列名-->
<collection property="students" javaType="ArrayList" ofType="Student"column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{id}
</select>
3、將Mapper檔案注冊到MyBatis-config檔案中
4、測驗
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}
小結
1、關聯-association
2、集合-collection
3、所以association是用于一對一和多對一,而collection是用于一對多的關系
4、JavaType和ofType都是用來指定物件型別的
-
JavaType是用來指定pojo中屬性的型別
-
ofType指定的是映射到list集合屬性中pojo的型別,
注意說明:
1、保證SQL的可讀性,盡量通俗易懂
2、根據實際要求,盡量撰寫性能更高的SQL陳述句
3、注意屬性名和欄位不一致的問題
4、注意一對多和多對一 中:欄位和屬性對應的問題
5、盡量使用Log4j,通過日志來查看自己的錯誤
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/228372.html
標籤:Java
上一篇:Java基礎之:訪問修飾符
