一、延遲加載
resultMap可以實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具備延遲加載功能。
延遲加載:先從單表查詢,需要時再從關聯表去關聯查詢,大大提高數據庫性能,因為查詢單表要比關聯查詢多張表速度要快。
在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading
設置項 |
描述 |
允許值 |
默認值 |
lazyLoadingEnabled |
全局性設置懶加載。如果設為‘false',則所有相關聯的都會被初始化加載。 |
true | false |
false |
aggressiveLazyLoading |
當設置為‘true'的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。 |
true | false |
true |
1
2
3
4
|
<settings> <setting name= "lazyLoadingEnabled" value= "true" /> <setting name= "aggressiveLazyLoading" value= "false" /> </settings> |
場合:
當只有部分記錄需要關聯查詢其它信息時,此時可按需延遲加載,需要關聯查詢時再向數據庫發出sql,以提高數據庫性能。
當全部需要關聯查詢信息時,此時不用延遲加載,直接將關聯查詢信息全部返回即可,可使用resultType或resultMap完成映射。
二:案例:(在部門和員工一對多)
源碼介紹:
1.Dept.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package cn.zhang.entity; import java.util.HashSet; import java.util.Set; public class Dept { private Integer deptno; private String deptname; private Set<Emp> emp = new HashSet<Emp>(); @Override public String toString() { return "Dept [deptno=" + deptno + ", deptname=" + deptname + ", emp=" + emp + "]" ; } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this .deptno = deptno; } public String getDeptname() { return deptname; } public void setDeptname(String deptname) { this .deptname = deptname; } public Set<Emp> getEmp() { return emp; } public void setEmp(Set<Emp> emp) { this .emp = emp; } } |
2.Emp.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package cn.zhang.entity; public class Emp { private Integer empno; private String empname; @Override public String toString() { return "Emp [empno=" + empno + ", empname=" + empname + "]" ; } public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this .empno = empno; } public String getEmpname() { return empname; } public void setEmpname(String empname) { this .empname = empname; } } |
3.MybatisUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package cn.zhang.util; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; /** * 工具類 * */ public class MybatisUtil { private static String config = "mybatis-config.xml" ; static Reader reader; static { try { reader = Resources.getResourceAsReader(config); } catch (IOException e) { e.printStackTrace(); } } private static SqlSessionFactory factory = new SqlSessionFactoryBuilder() .build(reader); // 提供一個可以獲取到session的方法 public static SqlSession getSession() throws IOException { SqlSession session = factory.openSession(); return session; } } |
4.DeptDao.java
1
2
3
4
5
6
7
8
9
10
11
|
package cn.zhang.dao; import java.io.IOException; import cn.zhang.entity.Dept; public interface DeptDao { /** * 查詢指定記錄 * @return * @throws IOException */ public Dept findById(Integer id) throws IOException; } |
5.DeptDAO.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?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= "cn.zhang.dao.DeptDao" > <!-- 3 .根據員工id查詢員工信息 --> <select id= "selectEmpByDeptNo" resultType= "Emp" > select empno,empname from emp where deptno=#{deptno} </select> <!-- 2 .對部門實體的映射 --> <resultMap type= "Dept" id= "deptMapper" > <id property= "deptno" column= "deptno" /> <result property= "deptname" column= "deptname" /> <!-- 一對多部門關聯的員工 --> <!--select:關聯員工查詢 --> <!--column:關聯員工查詢所需要的條件(來源于 1 ) --> <collection property= "emp" ofType= "Emp" select= "selectEmpByDeptNo" column= "deptno" /> </resultMap> <!-- 1 .根據部門id查詢部門信息 --> <select id= "findById" resultMap= "deptMapper" > select deptno,deptname from dept where deptno=#{deptno} </select> </mapper> |
6.mybatis-config.xml (延遲加載的配置在此)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?xml version= "1.0" encoding= "UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <!--lazyLoadingEnabled:設置懶加載,默認為 false 。如果為 false :則所有相關聯的都會被初始化加載。 aggressiveLazyLoading:默認為 true 。當設置為 true 時,懶加載的對象可能被任何懶屬性全部加載;否則,每個屬性按需加載。 --> <settings> <!-- 打開延遲加載的開關 --> <setting name= "lazyLoadingEnabled" value= "true" /> <!-- 將積極加載改為消息加載即按需加載 --> <setting name= "aggressiveLazyLoading" value= "false" /> </settings> <!-- 配置別名 --> <typeAliases> <!--方式一: 按類型名定制別名 --> <!--方式二: 拿當前指定包下的簡單類名作為別名 --> < package name= "cn.zhang.entity" /> </typeAliases> <environments default = "oracle" > <environment id= "oracle" > <!-- 使用jdbc的事務 --> <transactionManager type= "JDBC" /> <!-- 使用自帶的連接池 --> <dataSource type= "POOLED" > <!-- 我用的Oracle數據庫 --> <property name= "driver" value= "oracle.jdbc.driver.OracleDriver" /> <property name= "url" value= "jdbc:oracle:thin:@localhost:1521:orcl" /> <property name= "username" value= "study" /> <property name= "password" value= "123" /> </dataSource> </environment> </environments> <mappers> <mapper resource= "cn/zhang/dao/DeptDAO.xml" /> </mappers> </configuration> |
7.MyTest.java(測試類)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package cn.zhang.test; //一對多 import java.io.IOException; import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; import cn.zhang.dao.DeptDao; import cn.zhang.entity.Dept; import cn.zhang.util.MybatisUtil; public class MyTest { DeptDao dao; @Before public void initData() throws IOException{ SqlSession session = MybatisUtil.getSession(); dao = session.getMapper(DeptDao. class ); } /** * 查詢指定記錄 * @throws IOException */ @Test public void findAll() throws IOException{ Dept dept = dao.findById( 1 ); System.out.println(dept); } } |
測試結果:
在下面位置打斷點
情況一:在mybatis-config.xml中不做配置情況
情況二:在mybatis-config.xml中配置
1
2
3
4
5
6
|
<settings> <!-- 打開延遲加載的開關 --> <setting name= "lazyLoadingEnabled" value= "true" /> <!-- 將積極加載改為消息加載即按需加載 --> <setting name= "aggressiveLazyLoading" value= "false" /> </settings> |
下一步:
F6下步:
F6下步:打出員工的名字
情況三:
F6下一步:
F6下一步:打印出員工名字
以上所述是小編給大家介紹的Mybatis中的延遲加載,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:http://www.cnblogs.com/zhangzongle/archive/2016/12/22/6210407.html