Mybatis關(guān)聯(lián)映射的實現(xiàn)
數(shù)據(jù)部分:
student表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `Sname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, `age` int(11) DEFAULT NULL, `t_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '張三', '男', 18, 1); INSERT INTO `student` VALUES (2, '李四', '女', 18, 1); INSERT INTO `student` VALUES (3, '王五', '男', 18, 1); INSERT INTO `student` VALUES (4, '小白', '女', 18, 1); INSERT INTO `student` VALUES (5, '小黑', '男', 18, 1); INSERT INTO `student` VALUES (6, '小紅', '女', 20, 2); INSERT INTO `student` VALUES (7, '小李', '男', 20, 2); INSERT INTO `student` VALUES (8, '小張', '女', 20, 2); INSERT INTO `student` VALUES (9, '小趙', '男', 20, 2); INSERT INTO `student` VALUES (10, '小王', '女', 20, 2); SET FOREIGN_KEY_CHECKS = 1;
teacher表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for teacher -- ---------------------------- DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `id` int(11) NOT NULL AUTO_INCREMENT, `Tname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of teacher -- ---------------------------- INSERT INTO `teacher` VALUES (1, '張老師'); INSERT INTO `teacher` VALUES (2, '李老師'); SET FOREIGN_KEY_CHECKS = 1;
查詢老師的學(xué)生sql信息語句與查詢結(jié)果如下:

查詢學(xué)生的老師信息sql語句與查詢結(jié)果如下:

直接查詢
查詢出來的數(shù)據(jù)用TeacherStudents實體類進(jìn)行封裝
TeacherStudents.java
package com.qcby.entity;
public class TeacherStudents {
private Integer id;
private String Tname;
private String Sname;
private String sex;
@Override
public String toString() {
return "TeacherStudents{" +"id=" + id +", Tname='" + Tname + '\'' +", Sname='" + Sname + '\'' +", sex='" + sex + '\'' +'}';
}
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getTname() {return Tname;}
public void setTname(String tname) {Tname = tname;}
public String getSname() {return Sname;}
public void setSname(String sname) {Sname = sname;}
public String getSex() {return sex;}
public void setSex(String sex) {this.sex = sex;}
}
TeacherStudentMapper.xml 內(nèi)寫查詢語句
<?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.qcby.dao.TeacherStudentsDao">
<select id="findTeacherStudents" resultType="com.qcby.entity.TeacherStudents">
select teacher.*,student.Sname,student.sex from teacher left join student on student.t_id = teacher.id
</select>
</mapper>
SqlMapConfig.xml
<mappers>
<mapper resource="mapper/TeacherStudentsMapper.xml"></mapper>
</mappers>
TeacherStudentsDao.java
package com.qcby.dao;
import com.qcby.entity.TeacherStudents;
import java.util.List;
public interface TeacherStudentsDao {
List<TeacherStudents> findTeacherStudents();
}
TeacherStudentsTest.java
import com.qcby.dao.TeacherStudentsDao;
import com.qcby.entity.TeacherStudents;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TeacherStudentsTest {
private InputStream in = null;
private SqlSession session = null;
private TeacherStudentsDao teacherStudentsDao = null;
@Before //前置通知, 在方法執(zhí)行之前執(zhí)行
public void init() throws IOException {
//加載主配置文件,目的是為了構(gòu)建SqlSessionFactory對象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//創(chuàng)建SqlSessionFactory對象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通過SqlSessionFactory工廠對象創(chuàng)建SqlSesssion對象
session = factory.openSession();
//通過Session創(chuàng)建UserDao接口代理對象
teacherStudentsDao = session.getMapper(TeacherStudentsDao.class);
}
@After //@After: 后置通知, 在方法執(zhí)行之后執(zhí)行 。
public void destory() throws IOException {
//釋放資源
session.close();
in.close();
}
@Test
public void findAll(){
List<TeacherStudents> list = teacherStudentsDao.findTeacherStudents();
System.out.println(list.toString());
}
}
直接查詢的查詢結(jié)果:

關(guān)聯(lián)映射
student 表和 teacher 表存在著一對多與多對一的關(guān)系,我們介紹 MyBatis 中處理關(guān)聯(lián)關(guān)系的兩種關(guān)聯(lián)映射查詢方式,分別是直接查詢與分布查詢。
直接查詢通過 SQL 的JOIN(如LEFT JOIN、INNER JOIN)關(guān)聯(lián)多個表,進(jìn)行聯(lián)合查詢獲取主表和關(guān)聯(lián)表的所有所需字段,然后在<resultMap>中通過<association>一對一或<collection>一對多標(biāo)簽,定義主表與關(guān)聯(lián)表字段到對應(yīng)實體屬性的映射規(guī)則,MyBatis 會自動將查詢結(jié)果分別封裝為主實體和關(guān)聯(lián)實體,并將關(guān)聯(lián)實體注入主實體的關(guān)聯(lián)屬性中。
分步查詢是分階段完成查詢,先執(zhí)行主查詢獲取主實體數(shù)據(jù)及關(guān)聯(lián)字段(select * from student),再由 MyBatis 自動根據(jù)關(guān)聯(lián)字段調(diào)用對應(yīng) Mapper 方法,執(zhí)行關(guān)聯(lián)查詢獲取關(guān)聯(lián)實體數(shù)據(jù)(select * from teacher where id = #{t_id}),最終將關(guān)聯(lián)實體自動封裝到主實體的關(guān)聯(lián)屬性中??山Y(jié)合延遲加載,僅在使用關(guān)聯(lián)數(shù)據(jù)時觸發(fā)關(guān)聯(lián)查詢。
下面我們來看詳細(xì)代碼:
SqlMapConfig.xml
<mappers>
<mapper resource="mapper/StudentMapper.xml"></mapper>
<mapper resource="mapper/TeacherMapper.xml"></mapper>
</mappers>
Student.java
package com.qcby.entity;
public class Student {
private Integer id;
private String Sname;
private String sex;
private Integer age;
private Integer t_id;
private Teacher teacher;
@Override
public String toString() {
return "Student{" +"id=" + id +", Sname='" + Sname + '\'' +", sex='" + sex + '\'' +", age=" + age +", t_id=" + t_id +", teacher=" + teacher +'}';
}
public Teacher getTeacher() {return teacher;}
public void setTeacher(Teacher teacher) {this.teacher = teacher;}
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getSname() {return Sname;}
public void setSname(String sname) {Sname = sname;}
public String getSex() {return sex;}
public void setSex(String sex) {this.sex = sex;}
public Integer getAge() {return age;}
public void setAge(Integer age) {this.age = age;}
public Integer getT_id() {return t_id;}
public void setT_id(Integer t_id) {this.t_id = t_id;}
}
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="com.qcby.dao.StudentDao">
<select id="findStudentTeacher" resultMap="studentTeacher">
select student.*,teacher.Tname from student left join teacher on student.t_id = teacher.id
</select>
<resultMap id="studentTeacher" type="com.qcby.entity.Student">
<id property="id" column="id"/>
<result property="Sname" column="Sname"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<result property="t_id" column="t_id"/>
<association property="teacher" javaType="com.qcby.entity.Teacher">
<result property="Tname" column="Tname"/>
</association>
</resultMap>
<select id="findStudentTeacher1" resultMap="studentTeacher1">
select * from student
</select>
<resultMap id="studentTeacher1" type="com.qcby.entity.Student">
<id property="id" column="id"/>
<result property="Sname" column="Sname"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<result property="t_id" column="t_id"/>
<association property="teacher" javaType="com.qcby.entity.Teacher"
select="com.qcby.dao.TeacherDao.findTeacherByT_id" column="t_id">
</association>
</resultMap>
<select id="findStudentByT_id" resultType="com.qcby.entity.Student">
select * from student where t_id = #{id}
</select>
</mapper>
<select> 標(biāo)簽用于主查詢,resultMap 屬性用于指定映射規(guī)則<resultMap> 標(biāo)簽用于結(jié)果映射規(guī)則,其中 id 屬性值要與 select 標(biāo)簽中的 resultMap 屬性值相同,是映射規(guī)則的唯一標(biāo)識,type 指定映射的目標(biāo)實體類,result 映射普通字段,property=實體類中的屬性名,column=數(shù)據(jù)庫當(dāng)中的字段,而 <association> 標(biāo)簽用于處理對象的關(guān)聯(lián)信息,其中 property=關(guān)聯(lián)對象的屬性名、javaType=關(guān)聯(lián)對象的類型、select=對應(yīng)的查詢方法、column=傳遞給關(guān)聯(lián)查詢的參數(shù)
StudenDao.java
package com.qcby.dao;
import com.qcby.entity.Student;
import java.util.List;
public interface StudentDao {
List<Student> findStudentTeacher();
List<Student> findStudentTeacher1();
Student findStudentByT_id(Integer t_id);
}
StudentTest.java
import com.qcby.dao.StudentDao;
import com.qcby.entity.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class StudentTest {
private InputStream in = null;
private SqlSession session = null;
private StudentDao studentDao = null;
@Before //前置通知, 在方法執(zhí)行之前執(zhí)行
public void init() throws IOException {
//加載主配置文件,目的是為了構(gòu)建SqlSessionFactory對象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//創(chuàng)建SqlSessionFactory對象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通過SqlSessionFactory工廠對象創(chuàng)建SqlSesssion對象
session = factory.openSession();
//通過Session創(chuàng)建UserDao接口代理對象
studentDao = session.getMapper(StudentDao.class);
}
@After //@After: 后置通知, 在方法執(zhí)行之后執(zhí)行 。
public void destory() throws IOException {
//釋放資源
session.close();
in.close();
}
@Test
public void findStudentTeacher(){
List<Student> students = studentDao.findStudentTeacher();
System.out.println(students.toString());
}
@Test
public void findStudentTeacher1(){
List<Student> students = studentDao.findStudentTeacher();
System.out.println(students.toString());
}
}
findStudentTeacher() 直接查詢結(jié)果如下:

findStudentTeacher1() 分步查詢結(jié)果如下:

Teacher.java
package com.qcby.entity;
import java.util.List;
public class Teacher {
private Integer id;
private String Tname;
private List<Student> students;
@Override
public String toString() {
return "Teacher{" +"id=" + id +", Tname='" + Tname + '\'' +", students=" + students +'}';
}
public List<Student> getStudents() {return students;}
public void setStudents(List<Student> students) {this.students = students;}
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getTname() {return Tname;}
public void setTname(String tname) {Tname = tname;}
}
TeacherMapper.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.qcby.dao.TeacherDao">
<select id="getStudents" resultMap="teacherStudents">
select teacher.*,student.Sname,student.sex from teacher left join student on student.t_id = teacher.id
</select>
<resultMap id="teacherStudents" type="com.qcby.entity.Teacher">
<id property="id" column="id"/>
<result property="Tname" column="Tname"/>
<collection property="students" ofType="com.qcby.entity.Student">
<result property="Sname" column="Sname"/>
<result property="sex" column="sex"/>
</collection>
</resultMap>
<select id="findTeacherByT_id" resultType="com.qcby.entity.Teacher">
select * from teacher where id = #{t_id}
</select>
<select id="getStudents1" resultMap="teacherStudents1">
select * from teacher
</select>
<resultMap id="teacherStudents1" type="com.qcby.entity.Teacher">
<id property="id" column="id"/>
<result property="Tname" column="Tname"/>
<collection property="students" ofType="com.qcby.entity.Student"
select="com.qcby.dao.StudentDao.findStudentByT_id" column="id" fetchType="lazy"/>
</resultMap>
</mapper>
在 Teacher.java 中 student 屬性的類型是 List 集合,collection 標(biāo)簽用于處理集合映射到 Student.java 中,oftype=集合泛型的類型
TeacherDao.java
package com.qcby.dao;
import com.qcby.entity.Teacher;
import java.util.List;
public interface TeacherDao {
List<Teacher> getStudents();
Teacher findTeacherByT_id(Integer t_id);
List<Teacher> getStudents1();
}
TeacherTest.java
import com.qcby.dao.TeacherDao;
import com.qcby.entity.Teacher;
import com.qcby.entity.TeacherStudents;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TeacherTest {
private InputStream in = null;
private SqlSession session = null;
private TeacherDao teacherDao = null;
@Before //前置通知, 在方法執(zhí)行之前執(zhí)行
public void init() throws IOException {
//加載主配置文件,目的是為了構(gòu)建SqlSessionFactory對象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//創(chuàng)建SqlSessionFactory對象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通過SqlSessionFactory工廠對象創(chuàng)建SqlSesssion對象
session = factory.openSession();
//通過Session創(chuàng)建UserDao接口代理對象
teacherDao = session.getMapper(TeacherDao.class);
}
@After //@After: 后置通知, 在方法執(zhí)行之后執(zhí)行 。
public void destory() throws IOException {
//釋放資源
session.close();
in.close();
}
@Test
public void getStudents(){
List<Teacher> teachers = teacherDao.getStudents();
for (Teacher teacher:teachers){
System.out.println(teacher);
}
}
@Test
public void getStudents1(){
List<Teacher> teachers = teacherDao.getStudents1();
for (Teacher teacher:teachers){
System.out.println(teacher);
System.out.println(teacher.getTname());
System.out.println(teacher.getStudents());
}
}
}
getStudents() 直接查詢結(jié)果如下:

getStudents1() 分步查詢結(jié)果如下:

延遲加載
MyBatis 的延遲加載(Lazy Loading)是一種優(yōu)化數(shù)據(jù)庫查詢性能的機制,它允許在需要時才加載關(guān)聯(lián)對象的數(shù)據(jù),而不是在加載主對象時就立即加載所有關(guān)聯(lián)數(shù)據(jù)。這種 “按需加載” 的方式可以減少不必要的數(shù)據(jù)庫查詢,提升系統(tǒng)性能。
延遲加載實現(xiàn)效果如圖:

只執(zhí)行了一個sql’語句,當(dāng)查詢該對象時,只加載該對象本身的屬性,對于其關(guān)聯(lián)的對象暫不加載,直到程序真正需要訪問這些關(guān)聯(lián)對象時,才會發(fā)起對應(yīng)的數(shù)據(jù)庫查詢
如何配置延遲加載
- 全局配置:SqlMapConfig.xml
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
lazyLoadingEnabled 是延遲加載的全局開關(guān),aggressiveLazyLoading 對 lazyLoadingEnabled 的補充配置,當(dāng)開啟延遲加載,aggressiveLazyLoading 再設(shè)置為 true 時,任何方式調(diào)用都會加載該對象的所有屬性,設(shè)置為 false 則該屬性將按需加載,若 lazyLoadingEnabled=false 關(guān)閉延遲加載時,此配置無效,所有關(guān)聯(lián)對象都會立即加載。
- 局部配置:在映射文件中通過
<association>或<collection>標(biāo)簽中由 fetchType 屬性指定
<collection property="students" ofType="com.qcby.entity.Student"
select="com.qcby.dao.StudentDao.findStudentByT_id" column="id" fetchType="lazy"/>
fetchType有兩個值,一個是"lazy"為懶加載,一個是"eager"為立即加載
到此這篇關(guān)于Mybatis關(guān)聯(lián)映射的實現(xiàn)的文章就介紹到這了,更多相關(guān)Mybatis關(guān)聯(lián)映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springmvc實現(xiàn)導(dǎo)出數(shù)據(jù)信息為excle表格示例代碼
本篇文章主要介紹了springmvc實現(xiàn)導(dǎo)出數(shù)據(jù)信息為excle表格,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧。2017-01-01
SpringBoot+MyBatis實現(xiàn)動態(tài)字段更新的三種方法
字段更新是指在數(shù)據(jù)庫表中修改特定列的值的操作,這種操作可以通過多種方式進(jìn)行,具體取決于業(yè)務(wù)需求和技術(shù)環(huán)境,本文給大家介紹了在Spring Boot和MyBatis中,實現(xiàn)動態(tài)更新不固定字段的三種方法,需要的朋友可以參考下2025-04-04
SpringBoot中通過AOP整合日志文件的實現(xiàn)
本文主要介紹了SpringBoot中通過AOP整合日志文件的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
SpringBoot+Redisson自定義注解一次解決重復(fù)提交問題
項目中經(jīng)常會出現(xiàn)重復(fù)提交的問題,本文主要介紹了SpringBoot+Redisson自定義注解一次解決重復(fù)提交問題,具有一定的參考價值,感興趣的可以了解一下2024-03-03
如何通過ServletInputStream讀取http請求傳入的數(shù)據(jù)
這篇文章主要介紹了如何通過ServletInputStream讀取http請求傳入的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Java中使用BigDecimal進(jìn)行浮點數(shù)運算
這篇文章主要介紹了Java中使用BigDecimal進(jìn)行浮點數(shù)運算,需要的朋友可以參考下2014-07-07
詳解SpringBoot構(gòu)建Docker鏡像的3種方式
這篇文章主要介紹了SpringBoot構(gòu)建Docker鏡像的3種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

