当前位置: 首页 > news >正文

Mybatis学习笔记(二)

八、多表联合查询

(一) 多表联合查询概述

在开发过程中单表查询不能满足项目需求分析功能,对于复杂业务来讲,关联的表有几张,甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务,就必须进行多表查询,在mybatis中提供了多表查询的结果时映射标签,可以实现表之间的一对一、一对多、多对一、多对多关系映射。

(二) MyBatis实现一对一查询

1. 构建数据库表

        person(个人表) IdCard(身份证表)

CREATE TABLE person(
p_id INT NOT NULL AUTO_INCREMENT,
p_name VARCHAR(30),
PRIMARY KEY(p_id) 
);#IdCard表
CREATE TABLE idcard(
c_id INT NOT NULL AUTO_INCREMENT,
c_cardno VARCHAR(18),
c_uselife DATE,
c_person_id INT NOT NULL,
PRIMARY KEY(c_id),
FOREIGN KEY(c_person_id) REFERENCES person(p_id),
UNIQUE KEY(c_cardno));INSERT INTO person(p_name) VALUES('张三'),('李四');INSERT INTO idcard(c_cardno,c_uselife,c_person_id)
VALUES('110112199012127821','2029-10-10',1);
INSERT INTO idcard(c_cardno,c_uselife,c_person_id)
VALUES('120114199911103491','2030-12-01',2);

2.准备项目环境

3.嵌套结果方式查询

 3.1实体类创建

Person

package com.jn.entity;public class Person {private Integer id;private String name;public Person() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +'}';}
}

IdCard 

package com.jn.entity;import java.util.Date;public class IdCard {private Integer id;private String cardno;private Date useLife;public IdCard() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getCardno() {return cardno;}public void setCardno(String cardno) {this.cardno = cardno;}public Date getUserLife() {return useLife;}public void setUserLife(Date userLife) {this.useLife = userLife;}@Overridepublic String toString() {return "IdCard{" +"id=" + id +", cardno='" + cardno + '\'' +", userLife=" + useLife +'}';}
}
3.2编写sql语句

实现查询个人信息时,也要查询个人所对应的身份证信息。

select p.*,c.* from
person p,
idcard c
where p.p_id=c.c_person_id and p.p_id=1;

3.3编写PersonIdCard类
package com.jn.entity;import java.util.Date;public class PersonIdCard extends Person{private String cardno;private Date useLife;public String getCardno() {return cardno;}public void setCardno(String cardno) {this.cardno = cardno;}public Date getUseLife() {return useLife;}public void setUseLife(Date useLife) {this.useLife = useLife;}
}
3.4定义持久层接口

PersonDao

package com.jn.dao;import com.jn.entity.PersonIdCard;public interface PersonDao {public PersonIdCard getPersonById(int id);
}
3.5定义 PersonDao.xml 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.PersonDao"><select id="getPersonById" resultMap="PersonResultMap">SELECT p.*,c.* from person p ,idcard c where p.p_id = c.c_person_id and p.p_id = 1;</select><resultMap id="PersonResultMap" type="PersonIdCard"><id column="p_id" property="id"></id><result column="p_id" property="id"></result><result column="p_name" property="name"></result><result column="c_cardno" property="cardno"></result><result column="c_uselife" property="useLife"></result></resultMap>
</mapper>
3.6创建 PersonTest 测试类
package com.jn.test;import com.jn.dao.PersonDao;
import com.jn.entity.PersonIdCard;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class PersonTest {@Testpublic void testGetPersonById() throws Exception{//获取sqlSession对象SqlSession sqlSession = MyBatisUtils.getSession();//通过sqlSession获取PersonDao的代理对象PersonDao personDao = sqlSession.getMapper(PersonDao.class);PersonIdCard personIdCard = personDao.getPersonById(1);System.out.println(personIdCard);//commitsqlSession.close();MyBatisUtils.close(sqlSession);}
}
3.7测试结果

4.嵌套查询方式

前言

查的到底是什么?

        查的是一个对象Person,这个对象不仅包含了Person里面的属性,同时还包含了一个IdCard对象。然后把两个表里面的信息整合以便于后续处理。

4.1添加idCard属性

在person类里面添加idCard属性 

package com.jn.entity;public class Person {private Integer id;private String name;private IdCard idCard;public Person() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public IdCard getIdCard() {return idCard;}public void setIdCard(IdCard idCard) {this.idCard = idCard;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", idCard=" + idCard +'}';}
}
4.2持久层里面添加方法
package com.jn.dao;import com.jn.entity.Person;
import com.jn.entity.PersonIdCard;public interface PersonDao {public PersonIdCard getPersonById(Integer id);//嵌套查询的查询方法public Person getPersonById2(Integer id);
}
4.3持久层接口IdCardDao
package com.jn.dao;import com.jn.entity.Person;public interface IdCardDao {public Person getIdCardByPersonId(Integer id);
}
4.4定义 IdCardDao.xml 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.IdCardDao"><!--查询符合结果的IdCard对象并返回给命名空间IdCardDao下的getIdCardByPersonId函数,然后配合PersonDao.xml进行数据的联合查询
--><select id="getIdCardByPersonId"  parameterType="int" resultMap="IdCardResult">select * from idcard  where c_person_id  = #{id}</select><resultMap id="IdCardResult" type="IdCard"><id column="c_id" property="id"></id><result column="c_id" property="id"></result><result column="c_cardno" property="cardno"></result><result column="c_uselife" property="useLife"></result></resultMap>
</mapper>
4.5PersonDao.xml 配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.PersonDao"><!--嵌套结果的查询--><select id="getPersonById" resultMap="PersonResultMap">SELECT p.*,c.* from person p ,idcard c where p.p_id = c.c_person_id and p.p_id = 1;</select><resultMap id="PersonResultMap" type="PersonIdCard"><id column="p_id" property="id"></id><result column="p_id" property="id"></result><result column="p_name" property="name"></result><result column="c_cardno" property="cardno"></result><result column="c_uselife" property="useLife"></result></resultMap><!--嵌套查询的结果。根据id先查询到Person对象里面的字段信息,然后配合IdCard.xml查询返回的IdCard对象进行结合,然后返回一个getPersonById2函数的Person对象--><select id="getPersonById2" parameterType="int" resultMap="PersonResultMap2">select * from person where p_id = #{id}</select><resultMap id="PersonResultMap2" type="Person"><id column="p_id" property="id"></id><result column="p_name" property="name"></result><!--映射Person的复杂字段idCard对象属性--><association property="idCard" javaType="IdCard" column="p_id" select="com.jn.dao.IdCardDao.getIdCardByPersonId"></association></resultMap>
</mapper>

column:表示取上次查询出来的指定列的值,做为select属性所指定的查询的输入值。
select:表示指定的查询.

4.6加入测试方法
    //测试嵌套查询@Testpublic void testNestedQueryById() throws Exception{//获取sqlSession对象SqlSession sqlSession = MyBatisUtils.getSession();//通过sqlSession获取PersonDao的代理对象PersonDao personDao = sqlSession.getMapper(PersonDao.class);Person person = personDao.getPersonById2(1);System.out.println(person);MyBatisUtils.close(sqlSession);}
4.7测试结果

 到目前为止项目的结构目录

(三)MyBatis实现一对多查询

1.创建数据库表

department(部门表),employee(员工表)同时设定部门和员工表的关系

CREATE TABLE department(
d_id INT NOT NULL AUTO_INCREMENT,
d_name VARCHAR(100),
PRIMARY KEY(d_id)
);CREATE TABLE employee(
e_id INT NOT NULL AUTO_INCREMENT,
e_name VARCHAR(30),
e_gender VARCHAR(6),
e_age INT,
e_depart_id INT,
PRIMARY KEY(e_id),
FOREIGN KEY(e_depart_id) REFERENCES department(d_id)
);
-- 向 department 表中插入数据
INSERT INTO department (d_name) VALUES ('研发部');
INSERT INTO department (d_name) VALUES ('销售部');
INSERT INTO department (d_name) VALUES ('财务部');
INSERT INTO department (d_name) VALUES ('市场部');
INSERT INTO department (d_name) VALUES ('人力资源部');-- 向 employee 表中插入数据
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('张三', '男', 25, 1);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('李四', '女', 30, 1);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('王五', '男', 28, 2);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('赵六', '女', 32, 2);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('孙七', '男', 27, 3);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('周八', '男', 26, 1);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('吴九', '女', 29, 1);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('郑十', '男', 31, 2);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('钱十一', '女', 24, 3);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('刘十二', '男', 33, 4);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('陈十三', '女', 28, 4);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('杨十四', '男', 30, 5);
INSERT INTO employee (e_name, e_gender, e_age, e_depart_id) VALUES ('胡十五', '女', 27, 5);​

2.嵌套结果的方式

2.1实体类创建

Department类

package com.jn.entity;public class Department {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

Employee类

package com.jn.entity;public class Employee {private int id;private String name;private String gender;private Integer age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +'}';}
}
2.2编写sql查询语句
select d.*,e.* from department d,employee  e where d.d_id=e.e_depart_id and d.d_id=1;

2.3Department加入List

把Employee属性变为List集合作为Department的属性

package com.jn.entity;import java.util.List;public class Department {private int id;private String name;private List<Employee> emps;public Department() {}public int getId(){return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Employee> getEmps() {return emps;}public void setEmps(List<Employee> emps) {this.emps = emps;}@Overridepublic String toString() {return "Department{" +"id=" + id +", name='" + name + '\'' +", emps=" + emps +'}';}
}
2.4持久层DepartmentDao 
package com.jn.dao;import com.jn.entity.Department;public interface DepartmentDao {public Department getDepartById(Integer id);
}
2.5映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.DepartmentDao"><select id="getDepartById" parameterType="int" resultMap="getDepartmentMap">select d.*,e.* from department d,employee  e where d.d_id=e.e_depart_id and d.d_id=#{id}</select><resultMap id="getDepartmentMap" type="Department"><id column="d_id" property="id"></id><result column="d_name" property="name"></result><collection property="emps" ofType="Employee"><id column="e_id" property="id"></id><result column="e_name" property="name"></result><result column="e_gender" property="gender"></result><result column="e_age" property="age"></result></collection></resultMap>
</mapper>
2.6测试方法
package com.jn.test;import com.jn.dao.DepartmentDao;
import com.jn.entity.Department;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class DepartmentTest {@Testpublic void testGetDepartmentById() throws Exception{//获取sqlSession对象SqlSession sqlSession = MyBatisUtils.getSession();//通过sqlSession对象得到DepartmentDao的接口代理对象DepartmentDao departmentDao = sqlSession.getMapper(DepartmentDao.class);Department department = departmentDao.getDepartById(1);System.out.println(department.getName());department.getEmps().forEach(System.out::println);//closesqlSession.close();}
}
2.7测试结果

 

3.嵌套查询的方式

3.1定义EmployeeDao
package com.jn.dao;import com.jn.entity.Employee;import java.util.List;public interface EmployeeDao {public List<Employee> getEmployeeById(Integer id);
}
3.2定义 EmployeeDao.xml 
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.EmployeeDao"><!--配置employee的查询语句,返回一个Employee对象的集合--><select id="getEmployeeById" parameterType="int" resultMap="getEmployeeResultMap">select * from employee where e_depart_id = #{id}</select><resultMap id="getEmployeeResultMap" type="Employee"><id column="e_id" property="id"></id><result column="e_name" property="name"></result><result column="e_gender" property="gender"></result><result column="e_age" property="age"></result></resultMap>
</mapper>
3.3 DepartmentDao添加
package com.jn.dao;import com.jn.entity.Department;public interface DepartmentDao {public Department getDepartById(Integer id);public Department getDepartById2(Integer id);
}
3.4DepartmentDao.xml添加
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.DepartmentDao"><select id="getDepartById" parameterType="int" resultMap="getDepartmentMap">select d.*,e.* from department d,employee  e where d.d_id=e.e_depart_id and d.d_id=#{id}</select><resultMap id="getDepartmentMap" type="Department"><id column="d_id" property="id"></id><result column="d_name" property="name"></result><collection property="emps" ofType="Employee"><id column="e_id" property="id"></id><result column="e_name" property="name"></result><result column="e_gender" property="gender"></result><result column="e_age" property="age"></result></collection></resultMap><select id="getDepartById2" parameterType="int" resultMap="getDepartmentMap2">select * from department where d_id=#{id}</select><resultMap id="getDepartmentMap2" type="Department"><id column="d_id" property="id"></id><result column="d_name" property="name"></result><collection property="emps" ofType="Employee" column="d_id" select="com.jn.dao.EmployeeDao.getEmployeeById"></collection></resultMap>
</mapper>
3.5测试方法
    //嵌套查询@Testpublic void testGetDepartmentById2() throws Exception{//获取sqlSession对象SqlSession sqlSession = MyBatisUtils.getSession();//通过sqlSession对象得到DepartmentDao的接口代理对象DepartmentDao departmentDao = sqlSession.getMapper(DepartmentDao.class);Department department = departmentDao.getDepartById2(1);System.out.println(department.getName());department.getEmps().forEach(System.out::println);//closesqlSession.close();}
3.6测试结果

(三)MyBatis实现多对多查询

1.创建数据库表

CREATE TABLE student(sid INT NOT NULL AUTO_INCREMENT,sname VARCHAR(30),PRIMARY KEY (sid)
);CREATE TABLE teacher(tid INT NOT NULL AUTO_INCREMENT,tname VARCHAR(30),PRIMARY KEY (tid)
);CREATE TABLE student_teacher(s_id INT NOT NULL,t_id INT NOT NULL,PRIMARY KEY (s_id,t_id),FOREIGN KEY (s_id) REFERENCES student(sid),FOREIGN KEY (t_id) REFERENCES teacher(tid)
);
INSERT INTO student(sname) VALUES('张三'),('李四');
INSERT INTO teacher (tname) VALUES('刘老师'),('李老师');
INSERT INTO student(sname) VALUES('王五'),('赵六');
INSERT INTO teacher(tname) VALUES('张老师'),('王老师');
INSERT INTO student(sname) VALUES('孙七'),('周八');
INSERT INTO teacher(tname) VALUES('陈老师'),('杨老师');
INSERT INTO student(sname) VALUES('吴九'),('郑十');
INSERT INTO teacher(tname) VALUES('马老师'),('胡老师');
INSERT INTO student_teacher(s_id,t_id) VALUES(1,1),(1,2),(2,1),(3,3),(3,4),(4,3),(4,4),(5,5),(5,6),(6,5),(6,6),(7,7),(7,8),(8,7),(8,8);

2.嵌套结果方式

2.1创建数据模型

Student,Teacher,StudentTeacher

package com.jn.entity;public class Student {private int id;private int name;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getName() {return name;}public void setName(int name) {this.name = name;}
}
package com.jn.entity;public class Teacher {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Teacher{" +"id=" + id +", name='" + name + '\'' +'}';}
}

package com.jn.entity;public class StudentTeacher {private int sid;private int tid;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public int getTid() {return tid;}public void setTid(int tid) {this.tid = tid;}
}
2.2编写多对多的sql语句
select s.*,t.*,st.* from student s,teacher t,student_teacher st where s.sid = st.s_id and st.t_id=t.tid AND s.sid=1;

2.3S中加入List属性
package com.jn.entity;import java.util.List;public class Student {private int id;private String name;private List<StudentTeacher> studentTeacherList;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<StudentTeacher> getStudentTeacherList() {return studentTeacherList;}public void setStudentTeacherList(List<StudentTeacher> studentTeacherList) {this.studentTeacherList = studentTeacherList;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name=" + name +", studentTeacherList=" + studentTeacherList +'}';}
}
2.4ST加入Teacher属性
package com.jn.entity;public class StudentTeacher {private int sid;private int tid;private Teacher teacher;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public int getTid() {return tid;}public void setTid(int tid) {this.tid = tid;}public Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}@Overridepublic String toString() {return "StudentTeacher{" +"sid=" + sid +", tid=" + tid +", teacher=" + teacher +'}';}
}
2.5tudentDao编写
package com.jn.dao;import com.jn.entity.Student;public interface StudentDao  {public Student getStudentById(Integer id);}
2.6SudentDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.StudentDao"><select id="getStudentById" parameterType="int" resultMap="getStudentMap">select s.*,t.*,st.* from student s,teacher t,student_teacher st where s.sid = st.s_id and st.t_id=t.tid AND s.sid=#{id}</select><resultMap id="getStudentMap" type="Student"><id column="sid" property="id"></id><result column="sname" property="name"></result><collection property="studentTeacherList" ofType="StudentTeacher"><result column="s_id" property="sid"></result><result column="t_id" property="tid"></result><association property="teacher" javaType="Teacher"><id column="tid" property="id"></id><result column="tname" property="name"></result></association></collection></resultMap>
</mapper>
2.7测试方法
package com.jn.test;import com.jn.dao.StudentDao;
import com.jn.entity.Student;
import com.jn.entity.StudentTeacher;
import com.jn.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;public class StudentTest {@Testpublic void testGetStudentById()throws Exception{SqlSession sqlSession = MyBatisUtils.getSession();StudentDao studentDao = sqlSession.getMapper(StudentDao.class);Student student = studentDao.getStudentById(1);System.out.println(student.getName());List<StudentTeacher> studentTeacherList = student.getStudentTeacherList();studentTeacherList.forEach(System.out::println);}
}
2.8测试结果

3.嵌套查询方式

3.1TeacherDao
package com.jn.dao;import com.jn.entity.Teacher;public interface TeacherDao {public Teacher getTeacherById(Integer id);
}
 3.2TeacherDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.TeacherDao"><select id="getTeacherById" parameterType="int" resultType="Teacher">select tid id,tname name from teacher where tid =#{id}</select>
</mapper>
3.3StudentTeacherDao
package com.jn.dao;import com.jn.entity.StudentTeacher;import java.util.List;public interface StudentTeacherDao {public List<StudentTeacher> getStudentTeacherBySid(Integer id);
}
3.4StudentTeacherDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.StudentTeacherDao"><select id="getStudentTeacherBySid" parameterType="int" resultMap="getStudentTeacherMap">select * from student_teacher where s_id =#{id}</select><resultMap id="getStudentTeacherMap" type="StudentTeacher"><result column="s_id" property="sid"></result><result column="t_id" property="tid"></result><association property="teacher" column="t_id"  javaType="Teacher"select="com.jn.dao.TeacherDao.getTeacherById"></association></resultMap>
</mapper>
3.5StudentDao添加方法
package com.jn.dao;import com.jn.entity.Student;public interface StudentDao  {public Student getStudentById(Integer id);public Student getStudentById2(Integer id);}
3.6StudentDao.xml配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jn.dao.StudentDao"><select id="getStudentById" parameterType="int" resultMap="getStudentMap">select s.*,t.*,st.* from student s,teacher t,student_teacher st where s.sid = st.s_id and st.t_id=t.tid AND s.sid=#{id}</select><resultMap id="getStudentMap" type="Student"><id column="sid" property="id"></id><result column="sname" property="name"></result><collection property="studentTeacherList" ofType="StudentTeacher"><result column="s_id" property="sid"></result><result column="t_id" property="tid"></result><association property="teacher" javaType="Teacher"><id column="tid" property="id"></id><result column="tname" property="name"></result></association></collection></resultMap><!--嵌套查询--><select id="getStudentById2" parameterType="int" resultMap="getStudentMap2">select * from student where sid=#{id}</select><resultMap id="getStudentMap2" type="Student"><id column="sid" property="id"></id><result column="sname" property="name"></result><collection property="studentTeacherList" ofType="StudentTeacher" column="sid"select="com.jn.dao.StudentTeacherDao.getStudentTeacherBySid"></collection></resultMap></mapper>
3.7测试方法
    //多对多的嵌套测试@Testpublic void testGetStudentById2()throws Exception{SqlSession sqlSession = MyBatisUtils.getSession();StudentDao studentDao = sqlSession.getMapper(StudentDao.class);Student student = studentDao.getStudentById2(1);System.out.println(student.getName());List<StudentTeacher> studentTeacherList = student.getStudentTeacherList();studentTeacherList.forEach(System.out::println);sqlSession.close();}
3.8测试结果

九、延迟加载策略

(一)简介

1.什么是延迟加载?

        延迟加载(lazy load)是(也称为懒加载)关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
        延迟加载,可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。

2.为什么要使用延迟加载?

        减少访问数据库的频率,我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限为了减少并发量,减少系统资源的消耗。

(二)局部延时加载

        注意:只有在嵌套查询的时候才能用到延时加载

        在mybatis中使用resultMap来实现一对一,一对多,多对多关系的操作。主要是通过 association、collection 实现一对一及一对多映射。association、collection 具备延迟加载功能。

 1.现象演示

在进行查询上述Employee与Department关联信息的时候,正常查询结果:

显示了两条sql语句的查询

然后把department.getEmps().forEach(System.out::println);给注释了查看结果

还是查询了两条sql语句

 2.局部解决

</resultMap>
相关联的查询标签上加 fetchType=”lazy”
fetchType默认值为eager 立即加载,Lazy为延时加载。

然后查看结果:

        发现只执行了一条sql语句

然后不进行注释查看结果 :

正常执行

(三)全局延时加载

        如果希望所有关联都需要延时加载,可以在mybatis的核心配置文件中进行配置,不用在collection或association中指定。默认全局开启。

1.配置setting

<settings>
<!--开启延时加载开关-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--关闭立即加载,实施按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

2.测试 

测试正常 

相关文章:

Mybatis学习笔记(二)

八、多表联合查询 (一) 多表联合查询概述 在开发过程中单表查询不能满足项目需求分析功能&#xff0c;对于复杂业务来讲&#xff0c;关联的表有几张&#xff0c;甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务&#xff0c;就必须进行多表查询&#xff0c…...

Google“Big Sleep“人工智能项目发现真实软件漏洞

据Google研究人员称&#xff0c;该公司的一个人工智能项目足够聪明&#xff0c;能够自行发现现实世界中的软件漏洞&#xff1b;Google的人工智能项目最近在开源数据库引擎 SQLite 中发现了一个之前未知的可利用漏洞。 该公司随后在正式软件发布之前报告了这一漏洞&#xff0c;这…...

npm入门教程5:package.json

一、package.json 文件的作用 依赖管理&#xff1a;列出项目所依赖的包&#xff08;库&#xff09;及其版本&#xff0c;便于其他开发者或自动化工具快速安装和更新这些依赖。元数据描述&#xff1a;提供项目的描述、作者、许可证等元信息&#xff0c;有助于项目的管理和维护。…...

docker-高级(待补图)

文章目录 数据卷(Volume)介绍查看方法删除方法绑定方法匿名绑定具名绑定Bind Mount 数据卷管理 网络bridge(桥接模式 默认)HOST(主机模式)Nonecontainer(指定一个容器进行关联网络共享)自定义(推荐)docker network 命令创建网络docker network create 实例展示-自定义实例展示-…...

Qt 文件目录操作

Qt 文件目录操作 QDir 类提供访问系统目录结构 QDir 类提供对目录结构及其内容的访问。QDir 用于操作路径名、访问有关路径和文件的信息以及操作底层文件系统。它还可以用于访问 Qt 的资源系统。 Qt 使用“/”作为通用目录分隔符&#xff0c;与“/”在 URL 中用作路径分隔符…...

Pandas 数据清洗

1.数据清洗定义 数据清洗是对一些没有用的数据进行处理的过程。很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况&#xff0c;如果要使数据分析更加准确&#xff0c;就需要对这些没有用的数据进行处理。 2.清洗空值 DataFrame.dropna(axis0, howany, threshN…...

IO学习笔记

当前需求&#xff0c;希望进行游戏可以保存游戏进度&#xff0c;可以将游戏的进度保存到一个文本文件&#xff0c;每一次打完游戏更新文本内容&#xff0c;下一次打游戏读取游戏进度&#xff0c;这里就涉及到两个知识IO流和File的知识。 File类 概述 java.io.File 类是文件…...

汇编练习-1

1、要求 练习要求引自《汇编语言-第4版》实验10.3(P209页) -编程&#xff0c;将data段中的数据&#xff0c;以10进制的形式显示出来 data segment dw 123,12666,1,8,3,38 data ends 2、实现代码(可惜没找到csdn对8086汇编显示方式) assume cs:codedata segmentdw 16 dup(0) ;除…...

初识二叉树( 二)

初识二叉树 二 实现链式结构二叉树前中后序遍历遍历规则代码实现 结点个数以及高度等层序遍历判断是否为完全二叉树 实现链式结构二叉树 ⽤链表来表示⼀棵二叉树&#xff0c;即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成&#xff0c;数据域和左右指针…...

AcWing1077-cnblog

问题背景 给定一个树形结构的图&#xff0c;每个节点代表一个地点&#xff0c;每个节点有一个守卫的代价。我们希望以最低的代价在树的节点上放置守卫&#xff0c;使得整棵树的所有节点都被监控。可以通过三种方式覆盖一个节点&#xff1a; 由父节点监控。由子节点监控。自己…...

五、SpringBoot3实战(1)

一、SpringBoot3介绍 1.1 SpringBoot3简介 SpringBoot版本&#xff1a;3.0.5 https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.introducing-spring-boot 到目前为止&#xff0c;你已经学习了多种配置Spring程序的方式…...

练习LabVIEW第三十三题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十三题&#xff1a; 用labview编写一个判断素数的程序 开始编写&#xff1a; LabVIEW判断素数&#xff0c;首先要搞…...

如何在服务器端对PDF和图像进行OCR处理

介绍 今天我想和大家分享一个我在研究技术资料时发现的很好玩的东西——Tesseract。这不仅仅是一个普通的库&#xff0c;而是一个用C语言编写的OCR神器&#xff0c;能够识别一大堆不同国家的语言。我一直在寻找能够处理各种文档的工具&#xff0c;而Tesseract就像是给了我一把…...

Windows 下实验视频降噪算法 MeshFlow 详细教程

MeshFlow视频降噪算法 Meshflow 视频降噪算法来自于 2017 年电子科技大学一篇高质量论文。 该论文提出了一个新的运动模型MeshFlow&#xff0c;它是一个空间平滑的稀疏运动场 (spatially smooth sparse motion field)&#xff0c;其运动矢量 (motion vectors) 仅在网格顶点 (m…...

Python入门:如何正确的控制Python异步并发量(制并发量的关键技巧与易错点解析)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 异步并发量控制 📒📝 Python异步并发简介📝 为什么要限制并发量🎈 资源管理🎈 服务稳定性📝 新手容易犯的错误🎈 忽略并发量限制🎈 错误设置并发量📝 设置并发量要注意的事情🎈 了解任务类型🎈 考虑系统资…...

qt QCheckBox详解

QCheckBox 是 Qt 框架中的一个控件&#xff0c;用于创建复选框&#xff0c;允许用户进行选择和取消选择。它通常用于表单、设置界面和任何需要用户选择的场景。 QCheckBox继承自QAbstractButton类&#xff0c;因此继承了按钮的特性。它表示一个复选框&#xff0c;用户可以通过…...

PAT甲级-1041 Be Unique

题目 题目大意 从一组数字中选出第一个唯一出现的数&#xff0c;输出该数。如果没有&#xff0c;则输出None。 思路 哈希的思想&#xff0c;将数值作为索引&#xff0c;对应该数值出现的次数&#xff0c;然后遍历数组即可。 注意第一个数字是指数字的个数&#xff0c;不是数…...

【jvm】如何设置堆内存大小

目录 1. 使用命令行参数设置2. idea中设置3. 注意事项 1. 使用命令行参数设置 1.在Java命令后添加-Xms和-Xmx参数。2.-Xms参数用于设置JVM的初始堆内存大小&#xff0c;等价于-XX:InitialHeapSize。3.-Xmx参数用于设置JVM的最大堆内存大小&#xff0c;等价于-XX:MaxHeapSize。…...

kernel源码分析 do_msgsnd read_msg

笔者分析的源码是v 5.11.22 链接&#xff1a;msg.c - ipc/msg.c - Linux source code v5.11.22 - Bootlin do_msgsnd static long do_msgsnd(int msqid, long mtype, void __user *mtext,size_t msgsz, int msgflg) {struct msg_queue *msq;struct msg_msg *msg;int err;str…...

掌握 CTE 技巧,实现连续日期和月份的 SQL 报表统计

在 SQL 查询中&#xff0c;报表统计往往涉及到特定时间段内的数据汇总&#xff0c;如每日、每月的销售数据等。然而&#xff0c;面对缺少数据的日期或月份&#xff0c;传统 SQL 查询可能会直接跳过这些日期&#xff0c;使得输出的报表在视觉上并不连续。本文将展示如何利用 CTE…...

【表格解决问题】EXCEL行数过多,WPS如何按逐行分别打印多个纸张中

1 问题描述 如图&#xff1a;我的表格行数太多了。打印在一张纸上有点不太好看 2 解决方式 Step01&#xff1a;先选中你需要打印的部分&#xff0c;找到【页面】->【打印区域】->【设置打印区域】 Step02&#xff1a;先选中一行&#xff0c;找到【插入分页符】 Step0…...

Maven讲解从基础到高级配置与实践

一、基础认知 1.1 Maven 的主要作用 Maven 主要是用来管理 Java 项目构建流程的工具&#xff0c;包括以下几个方面&#xff1a; 依赖管理&#xff1a;通过 POM.xml 文件管理项目的外部依赖库&#xff0c;不同版本的依赖包可以通过 Maven 中央仓库自动下载&#xff0c;减少了…...

Vue3组件式父子传值

下面是使用 <script setup> 语法的 Vue 3 组件之间传值的示例。 示例 1:使用 Props 和 Emits 父组件 <template><div><h1>父组件</h1><ChildComponent :message="parentMessage" @reply="handleReply" /><p>…...

网页自动化测试和爬虫:Selenium库入门与进阶

网页自动化测试和爬虫&#xff1a;Selenium库入门与进阶 在现代Web开发和数据分析中&#xff0c;自动化测试和数据采集成为了开发流程中的重要部分。Python 的 Selenium 库是一种强大的工具&#xff0c;不仅用于网页自动化测试&#xff0c;也在网页爬虫中得到了广泛的应用。本…...

Cells 单元

Goto Data Grid 数据网格 Cells 单元 Content Alignment 内容对齐 显示数值的数据网格单元格会将其内容向右对齐。显示其他类型数据的单元格将其内容向左排列。若要更改单元格内容对齐方式&#xff0c;请处理 ColumnView.RowCellDefaultAlignment 事件。 Selection Modes 选…...

2024/11/2 安卓创建首页界面

‌Gradle 8.7 bin‌是指Gradle 8.7版本的二进制包&#xff0c;通常以.zip或.tar.gz格式提供。这个二进制包包含了运行Gradle所需的所有文件&#xff0c;用户可以直接下载并解压使用&#xff0c;无需从源代码编译。 首先了解最常用的布局 线性布局&#xff08;从上到下&#x…...

SpringSession源码分析

默认对常规Session的理解和使用&#xff0c;如何使用Set-Cookie。 Maven库 常见的spring-session-data-redis依赖spring-session-core <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-core</artifactId&…...

IIC

IIC 目录 IIC BH1750型号的光照传感器 IIC通信协议 iic物理层 IIC软件层协议 -- 那么一主多从&#xff0c;怎么选中与指定的从机通信呢&#xff1f; 从机设备地址 -- 从手册中查看 IIC 写操作 IIC 读操作 硬件IIC和模拟 IIC 使用 模拟 IIC 使用 &#xff01;&…...

LLM Observability: Azure OpenAI (一)

作者&#xff1a;来自 Elastic Vinay Chandrasekhar•Andres Rodriguez 我们很高兴地宣布 Azure OpenAI 集成现已全面上市&#xff0c;它提供了对 Azure OpenAI 服务性能和使用的全面可观察性&#xff01;另请参阅本博客的第 2 部分 虽然我们已经提供了对 LLM 环境的可视性一段…...

qt QBrush详解

1、概述 QBrush是Qt框架中的一个基本图形对象类&#xff0c;它主要用于定义图形的填充模式。QBrush可以用于填充如矩形、椭圆形、多边形等形状&#xff0c;也可以用于绘制背景等。通过QBrush&#xff0c;可以设置填充的颜色、样式&#xff08;如实心、渐变、纹理等&#xff09…...