6. Mybatis lazy loading
6.1 Was ist Lazy Loading?
Wenn Sie zusammengehörige Informationen abfragen müssen, kann die Nutzung der Lazy-Loading-Funktion von MyBatis den Druck auf die Datenbank effektiv reduzieren: Bei der ersten Abfrage werden nur die Hauptinformationen abgefragt, und die zugehörigen Informationen werden geladen, wenn der Benutzer sie erhält.
Lazy Loading wird für die Kaskadierung verwendet.Der Zweck des Lazy Loading besteht darin, die Verschwendung von Speicher zu reduzierenund die Belastung des Systems zu verringern. Man kann es als On-Demand-Loading verstehen: Wenn ich die dazugehörigen Daten abrufe, interagiere ich nur mit der Datenbank, sonst interagiere ich nicht.
resultMap kann erweitertes Mapping implementieren (unter Verwendung von Assoziation und Sammlung, um Eins-zu-eins- und Eins-zu-viele-Mapping zu realisieren), und Assoziation und Sammlung haben Lazy-Loading-Funktionen.
6.2 Schalten Sie den Verzögerungsladeschalter ein
Konfigurieren Sie in der Kernkonfigurationsdatei von MyBatis: lazyLoadingEnabled, aggressiveLazyLoading.
Einstellungselemente | beschreiben | Zuschuss | Standardwerte |
---|---|---|---|
LazyLoadingEnabled | Lazy Loading global einstellen. Wenn auf „false“ gesetzt, alle zugeordnet | wahr falsch | FALSCH |
aggressiveLazyLoading | Wenn auf „true“ gesetzt, können Lazy Loaded-Objekte vollständig mit beliebigen Lazy-Eigenschaften geladen werden. Andernfalls wird jedes Attribut bei Bedarf geladen | wahr falsch | WAHR |
<!-- 全局参数设置 -->
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
6.3 Entitätsklassen
6.3.1 Abteilungsklasse
public class Dept {
private Integer deptno;
private String dname;
private String loc;
/**
* 关系属性
*/
private List<Emp> empList;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public List<Emp> getEmpList() {
return empList;
}
public void setEmpList(List<Emp> empList) {
this.empList = empList;
}
@Override
public String toString() {
return "Dept{" +
"deptno=" + deptno +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
}
6.3.2 Mitarbeiterklasse
public class Emp {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;
private Integer deptno;
/**
* 关系属性
*/
private Dept dept;
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Integer getMgr() {
return mgr;
}
public void setMgr(Integer mgr) {
this.mgr = mgr;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public Double getComm() {
return comm;
}
public void setComm(Double comm) {
this.comm = comm;
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", mgr=" + mgr +
", hiredate=" + hiredate +
", sal=" + sal +
", comm=" + comm +
", deptno=" + deptno +
'}';
}
}
6.4 Verwenden Sie die Assoziation, um Lazy Loading zu implementieren
Fragen Sie Informationen zu Mitarbeitern und zugehörigen Abteilungen ab.
6.4.1 Mapper-Schnittstelle
public interface EmpMapper {
/*
* 查询所有员工的信息,并关联查询部门信息
*/
List<Emp> select();
}
public interface DeptMapper {
/*
* 根据部门编号查询部门信息
*/
Dept selectById(Integer deptno);
}
6.4.2 Mapper-Datei
Die Prämisse des verzögerten Ladens ist, dass SQL getrennt werden muss und die zugehörige Abfrage-Sql nicht mehr verwendet wird.
Zum Beispiel möchten wir die Informationen aller Mitarbeiter abfragen und die Abteilungsinformationen in Verbindung abfragen; wenn wir Lazy Loading von Abteilungsinformationen implementieren möchten, dann ist das Abfragen von Mitarbeiterinformationen ein unabhängiges SQL, und das Abfragen von Abteilungsinformationen nach der Abteilungsnummer ist es auch eine unabhängige Sql. Beim Abfragen von Mitarbeiterinformationen Wenn zu diesem Zeitpunkt die Abteilungsinformationen benötigt werden, rufen Sie die Sql auf, um die Abteilungsinformationen entsprechend der Abteilungsnummer abzufragen.
Abteilungsinformationen nach Abteilungsnummer abfragen:
<?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.newcapec.mapper.DeptMapper">
<select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Dept">
select deptno,dname,loc from dept where deptno=#{deptno}
</select>
</mapper>
Mitarbeiterinformationen abfragen (Einzeltabellenabfrage) und Abteilungsinformationen über die obige Abfrage zuordnen:
Attribute des Zuordnungs-Tags:
select: Die StatementId, die der SQL der zugeordneten Datenabfrage entspricht, wenn Lazy Loading durchgeführt wird.
Die ausgeführte zugeordnete Abfrageanweisung befindet sich in derselben Mapper-Datei: Geben Sie einfach die statementId direkt ein; die
ausgeführte zugeordnete Abfrageanweisung befindet sich in einer anderen Mapper-Datei: namespace.statementId;
Spalte: der ihr zugeordnete Feldname, wenn die relationale Tabelleninformationsabfrage ausgeführt wird .
<?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.newcapec.mapper.EmpMapper">
<resultMap id="baseResultMap" type="com.newcapec.entity.Emp">
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
<association property="dept" javaType="com.newcapec.entity.Dept"
select="com.newcapec.mapper.DeptMapper.selectById" column="deptno">
</association>
</resultMap>
<select id="select" resultMap="baseResultMap">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
</select>
</mapper>
6.4.3 Prüfung
public class LazyLoadingTest {
@Test
public void testOneToOne() {
SqlSession sqlSession = MybatisUtil.getSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> list = empMapper.select();
for (Emp emp : list) {
System.out.println(emp.getEmpno() + "--" + emp.getEname() + "--" + emp.getJob());
System.out.println("----------");
// 需要使用关联信息
Dept dept = emp.getDept();
if (dept != null) {
System.out.println(dept.getDeptno() + "--" + dept.getDname() + "--" + dept.getLoc());
}
System.out.println("-----------------分割线----------------");
}
sqlSession.close();
}
}
6.5 Verwenden Sie eine Sammlung, um verzögertes Laden zu implementieren
6.5.1 Mapper-Schnittstelle
public interface DeptMapper {
/*
* 查询所有部门信息,并关联部门对应的员工信息
*/
List<Dept> select();
}
public interface EmpMapper {
/*
* 根据部门编号查询对应的员工信息
*/
List<Emp> selectByDeptno(Integer deptno);
}
6.5.2 Mapper-Datei
Mitarbeiterinformationen anhand der Abteilungsnummer abfragen:
<select id="selectByDeptno" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where deptno=#{deptno}
</select>
Fragen Sie Abteilungsinformationen ab (Einzeltabellenabfrage) und ordnen Sie Mitarbeiterinformationen in der Abteilung über die obige Abfrage zu:
<resultMap id="baseResultMap" type="com.newcapec.entity.Dept">
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="loc" property="loc"/>
<!--关联信息描述-->
<collection property="empList" ofType="com.newcapec.entity.Emp"
select="com.newcapec.mapper.EmpMapper.selectByDeptno" column="deptno">
</collection>
</resultMap>
<select id="select" resultMap="baseResultMap">
select deptno,dname,loc from dept
</select>
6.5.3 Testen
@Test
public void testOneToMany() {
SqlSession sqlSession = MybatisUtil.getSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> list = deptMapper.select();
for (Dept dept : list) {
System.out.println(dept.getDeptno() + "--" + dept.getDname() + "--" + dept.getLoc());
//查询关联信息
List<Emp> empList = dept.getEmpList();
for (Emp emp : empList) {
System.out.println("员工姓名:" + emp.getEname());
}
}
sqlSession.close();
}